VxD tutorial
1. Background KnowledgeIn order to understand the examples given in this article, knowledge of C, assembly and Windows device drivers is required.
2. Development tools
Requires Micros
(Using VC ++ 6.0 as an example)
3. Purpose
Use the development tools listed above to write a dynamically loaded VxD, which can be used to read memory
Address 0
Interrupt vector table at.
4. Get started
first step:
Create a new project with VC ++, named MiniVxd, type Win32 App or Console App
Because V
C ++ does not provide direct generation
VxD's App Wizard, so I have to choose one of the two apps above, and then do manual repair
Change it
, What needs to be modified
There is only one place, which is to add an option to the Link command line
/ VXD
The second step:
Create a new empty file and enter the following code in it:
TITLE MINIVXD-By Ding Kai
.386p
include vmm.inc
MINIVXD_DYNAMIC EQU 1
; Define the device driver block DDB, because it is dynamically loaded, so the device ID and loading order can be taken
Undecided
Meaning.
DECLARE_VIRTUAL_DEVICE MINIVXD, 1, 0, MsgDispatch, UNDEFINED_DEVICE_ID,
Undefined_Init_Order, 0, 0
VXD_LOCKED_CODE_SEG
; Define the message dispatch table. In this example, only one message is needed, namely W32_DEVICEIOCONTROL, which is used to
Win32Ap
Use in p
; DeviceIoControl API function communicates with this VxD.
BeginProc MsgDispatch
Control_Dispatch W32_DEVICEIOCONTROL, W32DeviceIoControl, sCall,
clc
ret
EndProc MsgDispatch
VXD_LOCKED_CODE_EN
END
Save the file, the file name is VxdStub.asm, and then compile the file with the following command:
Aml -coff -W2 -DBLD_COFF -DIS_32 -c -Cx -DMASM6 -I \ 95DDK \ INC32
VxdStub.asm
This will generate vxdstub.obj, add this OBJ file to the project file.
third step:
Create a C language file, the file name is MiniVxd.c, enter the following code in the file:
#define WIN40SERVICES
#pragma warning (disable: 4229)
#include
#define WANTVXDWRAPS
#pragma intrinsic (memcpy)
#pragma VxD_LOCKED_DATA_SEG
// Here you can define any global variables needed in VxD.
char AnyData [200];
#pragma VxD_LOCKED_CODE_SEG
///////////////////////////////////////////
DWORD __stdcall GetMemory (DWORD dwDDB, PDIOCPARAMETERS pD)
{
BYTE * p;
// The parameter check is omitted here, which must not be the case in practical applications !!
p = (PBYTE) pD-> lpvOutBuffer;
memcpy (p, 0, 1024); // Read the interrupt vector table, a total of 1024 bytes
return 1024;
}
////////////////////////////////////////////////// /////
/ * Win32 interface * /
////////////////////////////////////////////////// /////
int __stdcall
W32DeviceIoControl (DWORD dwIoCtrlCode, / * ecx * /
DWORD dwDDB, / * ebx * /
DWORD pDIOCParams) / * esi * /
{
PDIOCPARAMETERS pD;
pD = (PDIOCPARAMETERS) pDIOCParams;
if (dwIoCtrlCode == DIOC_OPEN ||
dwIoCtrlCode == DIOC_CLOSEHANDLE)
return 0L;
// Init returned value
if (pD-> lpcbBytesReturned)
* (DWORD *) pD-> lpcbBytesReturned = 0;
if (dwIoCtrlCode == 1) {// 1 = DeviceIoControl code
GetMemory (dwDDB, pD);
}
else
return ERROR_NOT_SUPPORTED;
return 0;
}
Add this file to the project file.
the fourth step:
Create a module definition file, this file will define the segment attributes of the resulting VxD file and output the device
drive
Program blocks,
Enter the following code and save the file as MiniVxd.def, and add it to the project file.
VXD MINIVXD DYNAMIC
DESCRIPTION 'Written by Ding Kai'
SEGMENTS
_LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
_TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE
_BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE
_ITEXT CLASS 'ICODE' DISCARDABLE
_IDATA CLASS 'ICODE' DISCARDABLE
_PTEXT CLASS 'PCODE' NONDISCARDABLE
_PDATA CLASS 'PDATA' NONDISCARDABLE SHARED
HEAPSIZE 10240
STACKSIZE 40960
EXPORTS
MINIVXD_DDB @ 1
Of course, some of these paragraphs do not exist in this program, listed here is to use this file as a template to
For
After use.
the fifth step:
The last one needed to add this project file, VxdWarps.clb, this file is in the DDK's LIB directory.
The sixth step:
The four required files have been added. They are:
vxdstub.obj
minivxd.c
minivxd.def
vxdwarps.clb
Please check the file path before making make, be sure to include the DDK directory in the Include
INC3
2 Directory.
After confirming that it is correct, you can press F7 to make.
The result will be generated in the DEBUG directory or Release directory (depending on the settings of the project file)
MiniVxd.vxd
file.
At this point, a small Vxd file is generated, you can use the following code in the program to communicate with this VxD
News.
BYTE buffer [1024];
DeviceIoControl (hVxd, 1, NULL, NULL, buffer, 1024, NULL, 0);
As a result, the current interrupt vector table will appear in the buffer array.
This article no longer provides a complete test program, please contact the author if necessary
5. Summary
This article uses a simple example to explain how to write a dynamically installable VxD under Windows 95.
Seed
And use this method
The written VxD is also applicable under Windows 98. However, this method cannot be used in Windows NT
*****************************
**
*******************************************
Title: VxD World-Virtual Windows World
Readers engaged in Windows system programming must have heard of VxD-this is in Windows (Note: refers to Windows
3.1
/ 95/98,
Non-Windows NT) omnipotent super weapon in the world. So far, more and more people have
Into the
Solve the wishes of Windows,
This also makes VxD technology more and more important. VxD, which means Virtual Something Driver, here
Of x
Refers to Something. such as
Say keyboard driver VKD, mouse driver VMD, etc. In the minds of many people, only hardware developers
Only
VxD is used, actually not
Of course, for software development, VxD is also omnipotent. This is not obvious under Windows 3.1,
While in W
indows95, with
With the introduction of the concept of threads and localization, it becomes more and more difficult to control all the resources of the system. Give a simple
example
, Due to 32-bit Windows
The application has an independent 4GB linear address space, commonly used Windows applications under Windows 3.1
Between orders
Communication and shared variables
The method is no longer fully applicable. I want to do something "out of the ordinary", such as intercepting messages from other applications
Become
It's getting harder. It's just you
When you are uneasy, using VxD technology may make you "bright and cheerful"-since the operating system can control
Wholly-owned
Source, then with the operating system
VxD (or simply VxD as part of the operating system) with the same highest authority will also be able to help
Help you
Complete "extraordinary behavior."
Why is VxD so magical? The most fundamental reason is that VxD runs on Ring 0 of the system, and is used
SDK (
Or well known now
VC ++, BC ++, Borl and C ++ Builder, VB, Delphi)
Walk in
Ring 3. At 80x86
In protected mode, VxD running at Ring 0 has the highest system permissions (the operating system also runs at
Ring 0)
.
To truly master VxD technology, you must:
Have a clear understanding of the 80x86 protection mode;
In-depth understanding of the operating mechanism of Windows;
Familiar with the operating mechanism of VxD itself.
As for the protection mode, there are currently some reference books on the domestic market, I hope you can read it a few times. although
Say no
Can make people feel better, but also
Can have a relatively clear understanding of the protection mode.
Let's get to know Windows itself first.
Virtual Windows world
Several applications running under Windows95: DOS application, Win16 application, Win32 application
program
. Among them DOS application
Most programs run in character mode, while Win16 / Win32 applications run in graphics mode. for
Make
These modes of operation are very similar
Tongting applications can "peace coexist", Windows uses a virtual machine (Virtual machine)
the way
. Every DOS application
Running in an independent DOS VM makes this stunned DOS application feel in control
all
Resources, it can be wanton
On the full screen it thinks, read and write on the hard disk that it thinks it is exclusive (Microsoft is setting up
Gauge DO
I can't think of a PC at S
Hardware is developing so rapidly). And all Windows applications, whether they are 16-bit or 32-bit
It is
Run on the same System
VM. This is because Windows applications are more compliant, readers familiar with Windows programming must be right
Handle
(Handle) The concept
I am very impressed. Every move of a Windows application is through various handles (
HWND, H
DC, HANDLE,
HMOUDLE, etc.) is achieved through the intermediary of the handle, so that the system has the opportunity to be in the same
System VM
Coordinate multiple Windows
application. Don't believe it? OK, let's do an experiment (I assume you have installed SofTIce for
Win95
), Start Windows95, start
After the end, do not run any DOS applications, press Control + D to activate SofTIce (in some
Softic
e default installation, activated
Softice's hotkey is Alt + D), and then type in the command:
: Vm
VM Handle Status High Addr VM ID Client Regs
C39200E8 00001862 C3800000 00000001 C3449F70
From the output of Softice, you can see that there is only one VM at this time, and its ID is 1.
Press Control + D to return to the Windows desktop, at this time, run several Windows applications, whether it is
16 bit
, Or 32-bit. repeat
The operation just now, press Control + D to activate Softice, and type in the instruction VM. We see the Softice output
Knot
The result is the same. That is to say
Although there are multiple Windows applications running, but there is only one VM in the system, this VM is
System VM
.
Press Control + D to return to the Windows desktop. At this time, run "MS-DOS mode" from the "Start Menu"
,press
Activate under Control + D
Softice, then type in the instruction:
: Vm
VM Handle Status High Addr VM ID Client Regs
C8D200E8 00000802 C8C00000 00000002 C0F5FF70
C39200E8 00005A62 C3800000 00000001 C0F06F70
From the output of Softice, you can see that there are two VMs in the system, one of which is what we just saw
of
System VM (VM ID = 1), in addition, there is another VM with ID = 2, this VM is DOS VM,
In other words, the "MS-DOS mode" just now runs in this DOS VM.
Press Control + D to return to the Windows desktop, and then run a few "MS-DOS mode" from the "Start Menu"
, Press Control + D to activate Softice, and type in the VM command, you will find that the VM has increased, the number of which is equal to
Place
In some cases, the number of "MS-DOS mode" is increased by 1.
Do you believe it now? All DOS applications are running in their respective DOS VM, and all
Windows applications are running in the same System VM. This is a very important concept.
**********************************************
**
***************************
VxD world-Windows protection mode
In general, 80x86 (80386 and later generation CPUs) can operate in three modes: real mode
,
Protected mode, V86 mode. The real mode is the ancient MS-DOS operating environment. Win95 only uses two
Various modes: protected mode and V86 mode.
Why go into protected mode
The protection mode has many advantages. One of the most direct benefits is: your program can use more internal
Saved
!
Do n’t think this is a big deal, I believe everyone who has written programs under MS-DOS has
One
A worry: how to open a large enough array in the program? If you do n’t move, you will get a stack overflow
do
Too. Don't complain about Turbo C, MS Fortran, Turbo Pascal, they are also overwhelmed.
These ones
The troubles all stem from "your program is running in real mode". The most 16-bit programs running in real mode
only
Can access 1M of memory. You may ask: Doesn't my machine have 64M memory? Yes if you
Yes
Run the program under MS-DOS (or the CPU is running in real mode), then you only use 1M memory,
The rest of the memory is "laid off", in this case, your 386/486/586 / Pâ…¡ is only equivalent to one
Run
8086 fast.
But the protection mode gave us a surprise. In theory, in protected mode, the CPU can address 4096M (
That is 4GB) of memory. That said, just compile your program into a 32-bit executable program (of course you have to borrow
help
32-bit compiler), you can make full use of memory in the program, the direct result of this is: you can
To
There is no need to eat anymore because the stack overflows or a 5000 × 5000 array cannot be opened.
It is the realization of 4GB memory access that makes the operating system have a more intelligent material foundation, multi-tasking
real
Only now can we mention the agenda for consideration.
Go deeper
From the hardware structure, 386 is controlled by three registers CR0, CR1, CR2 CPU operation. For example
The 0th bit of CR0 is used to judge whether the current CPU works in the protection mode or the real mode. Learned
People in 8088/8086 assembly language must be familiar with the 16 bits of AX, BX, CX, DX, SI, DI, SP, BP
Of the registers, in 80386, these registers were expanded to 32 bits, namely EAX, EBX, ECX, EDX
, ESI, EDI, ESP, EBP, if the CPU is running in real mode, then you can only use these 32-bit
The first 16 bits of the memory, and the last 16 bits are wasted.
The concept of segments is the key to our understanding of the protection model. In real mode, 16 bits are stored in the segment register
of
Segment address, at this time, the segment address is involved in addressing: shift the segment address to the left by 4 bits, plus the offset address
20 people
Physical address. In protected mode, a 16-bit segment selector (Segment) is stored in the segment register
Selector), this value is not directly involved in addressing, but only a pointer to the segment description table (
Segment
Descriptor Table). The segment description table (Segment Descriptor Table) stores
Paragraph description
Descriptor (Segment Descriptor). There is a description of the segment in the segment descriptor, for example: the segment is in memory
of
Position, segment size, segment type (whether data segment or code segment), etc.
When the CPU is running in protected mode, there are often at least three segment description tables in the memory: the global description table (
Global Descriptor Table (abbreviated as GDT), Local Descriptor Table (abbreviated as GDT)
LDT)
, Interrupt Descriptor Table (Interrupt Descriptor Table, referred to as IDT). Speaking of which, I want to mention
Awake reader
Note: Remember the meaning of the three words GDT, LDT, and IDT, which we will often use later.
The segment description table cannot exceed 64K (Why? If the answer is not up, then look at the previous explanation)
,
Each segment descriptor (that is, an item in the segment description table) is 8 bytes long, so each segment description
Table most
It can only contain 8192 segment descriptors.
In the future "Walking into the VxD World", we will make the segment description table, segment descriptors and paging machine into
One
Step by step explanation.
*************************
**
***************************
VxD World-About "Description Table"
We mentioned earlier that in protected mode, there are often at least three tables in memory: GDT, LDT, and IDT. Satoshi
Bright
You may ask: Where are these tables in memory?
Figure 1 Schematic diagram of several important registers
The positions of these three tables are recorded by three registers. The three registers are: GDTR, LDTR,
IDTR. We also need to explain a register, that is TR (Task Register), this register
Device
Related to task management in protection mode. In 386, these registers are shown in Figure 1.
We can see that both GDTR and IDTR contain 32-bit physical addresses and 16-bit permission levels, for a total of 48
Bit. The 32-bit addresses in GDTR and IDTR are linear addresses, not a combination of segment: offset (Seg: Offset)
Form, it indicates where the segment starts, if the system has not started the memory paging management mechanism,
that
This linear address is the physical address, but once the system starts the memory paging management mechanism, GDTR and
The 32-bit linear address in IDTR no longer points to the physical address.
The CPU reserves the first descriptor in the GDT. Any attempt to access the internal descriptor through the first descriptor in the GDT
The saved operation is illegal (remember the terrible blue screen under Win95?). If you point to the GDT segment selection
If the Index field of the selector is 0, it points to an empty segment selector. The schematic of the segment selector is shown in Figure 2:
TI: Talbe Indicator
RPL: Requestor Privilege Level
Figure 2 Segment selector
This means that in protected mode, the far NULL pointer is illegal. In real mode, the NULL pointer
there is
meaningful.
In memory (of course, the CPU works in protected mode), there is only one copy of GDT and IDT, which is
In other words, they are global. Any task that changes these two tables will have an impact on other tasks.
Let's talk about each item in IDT, IDT, that is, each descriptor has 256 interrupts defined
in
one of. Remember the interrupt vector table in the MS-DOS environment in real mode? In protected mode, interrupt
Trace
The statement IDT replaces the interrupt vector table. Although the interrupt description table can hold 8192 interrupt descriptors, but
The CPU can only use the first 256. So the length limit of the interrupt description table should be 7FFh (23
× 28-1).
T = 0: Interrupt gate descriptor
1: Trap gate descriptor
Figure 3 Trap / Interrupt gate descriptor
In fact, there can be two kinds of descriptors in the interrupt description table (IDT): Interrupt gate descriptor, Trap
gate trace
Predicate. Figure 3 shows the structure of the Trap / Interrupt gate descriptor. The word gate is mentioned here,
general
Translated as "door". The "interrupt gate" directly represents the process of interrupt calling: the interrupt calling is like
Over one
Like the door, this door is the interrupt descriptor, because the interrupt descriptor has the DPL and other permissions to check the flag
,
So if you want to call the corresponding interrupt service routine through this door, you need a certain qualification.
Trap and Interrupt gate are very similar. Generally speaking, Trap gate is used to catch system anomalies, and
Interrupt gate is used to respond to interrupts. In the specific implementation, there is only one difference: Interrupt
gate meeting
will
IF is set to 0, which can shield the hardware interrupt. But Trap gate will not change the value of IF.
The location of the LDT is stored in the register LDTR. Unlike GDT, there can be multiple LDTs ​​in memory. Every
Tasks can have their own LDT. From Figure 1, we can see that LDTR does not contain "address / permission"
Bit
. LDTR contains a segment selector. This segment selector points to an item in GDT, but it is not a general
A common item, this item is a descriptor that points to a certain LDT. You may immediately realize that GDT can contain
Descriptors that point to different LDTs, yes, exactly. In Windows protected mode, every MS-
DOS applications have their own LDT, and all Windows applications share an LDT. Yes no
Did you remember something? By the way, this is somewhat similar to the concept of VM (Virtual Machine) in Windows!
**********************************
**
***************************
VxD world-paging mechanism
About the paging mechanism
Under this mechanism, memory is divided into fixed-length "pages." In protected mode, the "page" is
Accept
To be protected, and can be "virtual" (to put it bluntly, "virtual" things mean that there is not,
and
The application mistakenly thought there were. For example, you only have 64MB of RAM, but your program thinks it silly
can
With 4GB of RAM, this is called "virtual").
Remember the concept of "segment" in the protected mode mentioned earlier? In protected mode, the length of the segment is OK
change
The size of the "page" cannot be changed here, although both of them are protected by the protection mode.
"
And "virtual". So what is the size of the "page"? The answer is 4KB.
If there is now a 32-bit linear address, let's take a look at how to obtain a physical address from this linear address
.
Figure 1 Linear addresses are mapped to physical addresses through pages
Please remember that Figure 1 shows the content, because it is so important. CR3 in the figure refers to the value of register CR3.
Such as
If you installed Softice for Win95, then press Ctrl + D to activate Softice, and then type the command:
CPU; you will see the value of CR3.
Example of linear address conversion to physical address
Assuming the existing linear address 8000DD88h, let's take a look at where the physical address points. Sexually
site
8000DD88h should be analyzed as follows:
800 0D D88
Page Table Index Page Index Page Offset
(Page table index) (page index) (page offset address)
Now we need to know the starting address of the page table directory. So we look at register CR3. Hypothetical deposit
Device
CR3 = 891000h, then 891000h + 200h? 4 = 891800h (think about why? 4, the answer
Note [1] at the end of the article), now we want to check the value at the linear address 891800h, at
Softice
, Type the following command:
: d 891800
Suppose that the result is 493227h. This value is ANDed with 0FFFFF000h, and we get what we are looking for
The starting physical address of the Page Table is 493000h, then 493000h + 4? 0Dh = 49302Ch (think
One thought why? 4, see note [2]), then we need to know the value at physical address 49302Ch, but
Is in
In Softice, we cannot directly obtain the value stored at the physical address, only through its corresponding linear
address
To view. In Softice, type the following command:
: phys 49302C
Suppose you get a linear address 89302Ch (sometimes you will get two different values, we take the first value
.
Think about why there are two different values? The answer is in note [3]), now we look at the linear
site
The value at 89302Ch, which is also the value at physical address 49302Ch. In Softice, type the following command:
: d 89302C
Assuming that you get 3F5000h, this is the physical address of the Page we are looking for. then,
3F5000h + 0D88h = 3F5D88h, this is the physical address corresponding to the linear address 8000DD88h. I
We want to check the value at physical address 3F5D88h in Softice, then we have to find its corresponding linear address.
in
In Softice, type the following command:
: phys 3F5D88
Suppose we get the linear address 7F5D88h, let us look at the value at this linear address 7F5D88h. in
In softice, type the following command:
: d 7F5D88
Let's write down the result, and then look at the value at linear address 8000DD88h.
: d 8000DD88
You will find that the linear address 7F5D88h and the linear address 8000DD88h point to exactly the same value.
Generally speaking, in order to improve the efficiency of address translation, there will be a page translation buffer (TLB) in the CPU
), Which stores information about the most recent page transition.
MMU (Memory Management Unit)
Since 386, the CPU has a memory management unit (Memory Management Unit, referred to as
MMU).
MMU is responsible for the functions provided: virtual memory, reorganization segment, process separation, page protection, address translation.
The linear address to physical address conversion we performed in the above example is done by the MMU.
Mode conversion
We briefly mention the switching process between the protection mode and the real mode, there is a concept.
Switch from real mode to protection mode: check whether the current CPU is capable of running in protection mode; check
Measurement
Protected mode environment (DPMI or VCPI); establish IDT; establish GDT; disable interrupts, including NMI; load
GDTR; set IDTR; set bit 0 of CR0; clear instruction queue; load segment register; allow interrupt.
Switch from the protection mode to the real mode: interrupt is prohibited, including NMI; page conversion is prohibited; set the data segment to send
Save
The value of the device is the selector in quasi-real mode; reset bit 0 of CR0; clear the command queue; set
IDTR = 0000
: 03FF; interrupt is allowed.
[1] Because in the Page Table Directory, each entry occupies 4 bytes.
[2] Because in the Page Idex Table, each entry occupies 4 bytes.
[3] Because the mapping relationship between linear addresses and physical addresses is not one-to-one, this means that the same physical location
site,
There may be multiple linear addresses pointing to it.
********************************
**
***************************
VxD World-Win95 linear address allocation
Figure 1 is a diagram describing the Win95 linear address space. Below we explain this picture in detail.
Figure 1 Windows 95 linear address allocation diagram
0 ~ 4MB:
The part marked on the figure is the DOS memory area, but this is not true. We know 16-bit DOS application
The sequence can only access 0 ~ 1MB of memory space, so why should we also count the 3MB memory of 1MB ~ 4MB
What about the DOS memory area? The answer lies in the paging mechanism we talked about earlier. Let ’s review it again: a page
surface
(Page) is 4kB, a page table (Page Talbe) has 1024 pages, a page table directory (
Page Table Directory) has 1024 page tables. Then a page table directory item can be mapped
1024 ×
4k = 4MB linear address. In fact, DOS can only use the memory space of 0MB ~ 1MB, then 1MB ~ 4MB
To whom is the address space left? Regarding this question, the author once asked Karen Hazzah, Walter
Oney and Geoff Chappell, their answer is: this part is empty. Win95 saves trouble in order to save time,
on
The linear address space of 1MB ~ 4MB is also used as the DOS memory area, so Win95 switches between DOS VM
At this time, it can be done in units of Page Table Directory Entry. such
although
3MB of addresses were wasted, but the efficiency of DOS VM switching was exchanged.
What does the â‘ marked in Figure 1 mean? Haha, Win95 is very interesting, in order to make the system, Win16
should
The application can cooperate with the DOS application, so it is between 0 and 1MB, in fact, it is next to 1MB
In the face, put a Win16 global heap (actually a very small part of Win16 global heap). Speaking of which, pen
By
I think of a Quick Edit 4.0 editor under DOS that everyone loves. This editor has a
very much
Interesting function: Can share clipboard with Windows. At the time, we guessed that it must have used undisclosed
DPMI
Calling, now from Figure 1, it must be â‘ part of the Win16 global heap to help it.
Please also note that there is a â‘¡ in Figure 1, this part we call the high-end part of the Win16 global heap. why
Want
Place a Win16 global heap here? What is it used for?
The answer to this question is: To efficiently switch DOS VM.
Each DOS VM has a backup in the address space greater than 3GB, Win95 is performed between the DOS VM
When switching, simply switch the first item of the page table directory. So if one
VxD
To access a DOS VM, there is no need to wait until the DOS VM becomes the current VM before it can be accessed.
Go directly to â‘¡ access the backup of that DOS VM. The address of this DOS VM backup is called High-
linear address.
In later articles, we will talk about how to access the DOS VM in VxD in detail.
***********************
**
***************************
VxD World-Win95 Memory Secret
In the last issue of "Entering the VxD World", we talked about the allocation of 0 to 4MB linear memory space in Win95. below
We then talk about the allocation of the remaining 4MB to 4GB of linear memory space.
4MB ~ 2GB
The code, data and resources of the Win32 application are stored in this section of memory.
each
All Win32 applications are private. This is the place that best reflects the role of the protection mode paging mechanism
square
. Two Win32 applications, read and write to the same linear address (in the range of 4MB ~ 2GB), the actual
In fact, they are reading and writing to different physical addresses. Let's calculate how many pieces of memory this section corresponds to
Page Directory Entry. We know that a Page Directory Entry corresponds to 4MB linear memory
,that
4MB ~ 2GB of memory corresponds to 1024/2-1 = 511 Page Directory Entry. Just
says
Win95 realized the "independent" Win32 application by manipulating these 511 Page Directory Entry
Linear
Address space. For example, now there are 511 drawers, God told A: these drawers are all
gold
Coins, and told B to say: these drawers are all silver coins. And stipulate that only God can open the drawer. Actually smoke
Drawer
There may be only one copper plate, or nothing. At this time, A wants to see if it is in a drawer
gold
, So God temporarily put a gold coin in that drawer behind his back, and then opened the drawer to let A see it, so
A just
Believe it. This trick also works on B. B also believes that the 511 drawers are all the silver coins he wants. Protect
Protect
The operating system in mode (of course, Win95 here) is equivalent to God, and the deceived A and B are equivalent to
Luck
Win32 application running in protected mode. The hand of God that manipulates the drawer is the paging mechanism.
2GB ~ 3GB
This part of the memory space is called "application shared memory area", where Ring 3 applications are stored
Cheng
The sequence requires shared data and code. Including Win95 system DLL (such as User32.dll, Kernel32.
dll etc.
), Memory-mapped files, Win16 applications, and memory allocated by DPMI calls.
Win32 applications can be implemented by mapping the data to be shared to a linear memory space between 2GB and 3GB
Data sharing between programs.
Win16 applications need to share a linear address space, which is a legacy of Windows 3.1.
for
In order to make Win16 applications previously running on Windows 3.1 have the same running effect under Win95,
to
Microsoft decided to put the Win16 application in this shared memory area to run. It should be said that this is a comparison
Fit
Rational decision: not only save time and effort, but also ensure good compatibility with the previous generation of products.
From the perspective of the paging mechanism, think about how this "shared memory area" is implemented. 2GB ~ 3GB
The linear space corresponds to 256 Page Directory Entry. No matter who is running, Win95 will not change
Change this
256 Page Directory Entry, which means that the physical address corresponding to the linear address space of 2GB ~ 3GB
site
it's the same. In this way, Win95 achieves a total of 2GB ~ 3GB of linear address space memory without doing anything
enjoy.
3GB ~ 4GB
This part of the memory space is called "system memory area". Only Ring 0 VMM and VxD can access this part
Memory space. This part of the memory is also shared. Although the Ring 3 app cannot directly share this part
Inside
Storage space (that is, the method described in the SDK cannot be achieved), but we still call it shared memory
Area
, At least from the perspective of the paging mechanism, the Page Directory Entry corresponding to this part of memory is not
changing
. In fact, Win32 applications still have a way to access this part of the memory space. The general approach is that in VxD
Minute
Allocate a piece of memory, and then pass the 32-bit address pointer pointing to that piece of memory to the Win32 application, so
can
In order to directly access that memory in the Win32 application. When we talked about 0 ~ 4MB memory space,
mention
To the High-linear address, the place where the DOS VM is backed up, is in the 3GB ~ 4GB memory space.
For Windows application developers, implementing memory sharing is sometimes very important. For VxD open
For developers, it should also be noted that for shared memory pages that need to be accessed frequently, the VMM must be called
_LinPageLock service to lock, otherwise Out-Of-Context Memory Reference will appear
.
********************
**
***************************
VxD World-Hardware Virtualization and Virtual Device Driver
· Hardware Virtualization ·
Recall that in real-mode DOS, real-mode MS-DOS applications call the runtime library
of
fgets or -kbhit functions, these functions will directly call the MS-DOS service through the soft interrupt int 21h (
MS
-The DOS service will eventually call the BIOS service by calling the soft interrupt int 16h), or by soft interrupt
int 16h
Call the BIOS service. The BIOS directly manipulates the keyboard or interrupt controller through IN / OUT instructions.
We use the following picture to understand what is the realization of hardware virtualization (see Figure 1).
Two different MS-DOS applications may want to access the keyboard at the same time, they both feel that they are directly manipulating
Write
hardware. In fact, from a global perspective, the keyboard access of these two MS-DOS applications is serialized by VKD.
These two MS-DOS applications are actually manipulating "virtual hardware".
A key foundation of hardware virtualization is: the "port trapping" function of the 80386 chip, which makes
VKD
You can capture ring 3 application access to the keyboard. We remember when we talked about protected mode memory management earlier
,mention
To the concept of "virtual memory", the realization of "virtual memory" was also because the 80386 chip had "
paging trap "function.
· Virtual Device Driver ·
In the Windows system, it is VMM and VxDs that implement hardware virtualization (VMM itself is a collection of some VxDs
). In Win95, there are two kinds of VxD: static VxD (statically loaded VxD) and dynamic VxD (dynamic
State loaded VxD). In Windows 3.1, there is only one type of VxD: static VxD. Static VxD
load
Need to put VxD in SYSTEM.INI or the registry. For example, you wrote a file named Fool.VxD
of
static VxD, then you can add a sentence in the following location in SYSTEM.INI:
...
[386Enh]
device = Fool.VxD
...
Or add the following item in the following location of the registration form:
\ HKEY—LOCAL—MACHINE \ System \ CurrentControlSet \ services \ VxD \ Fool.VxD
In this way, Win95 will automatically load Fool.VxD when it starts.
Compared with Windows 3.1, Win95 has added dynamic VxD (dynamically loaded VxD). in
In Win95, the main manipulation of dynamic VxD is configuration manager and input / output
The two function modules of Supervisor (these two modules are static VxDs themselves).
Figure 1 Virtual keyboard
VKD: Virtual keyboard device VPICD: Virtual PIC device
*****************************
***************************
VxD World-VxD file format
We know that the executable file .EXE under MS-DOS is in MZ format, which means that the first two of the .EXE file
The byte is the character string "MZ". The .EXE of Windows 3.1 is in NE (New Executable) format,
Win95 and WinNT. EXE is PE (Portable Executable) format, VxD is LE (Linear
Executable) format. But there is one thing to note, there is always a small section embedded in the heads of NE, PE and LE
DOS program, its role is: when you run these kinds of .EXE files under DOS, it will prompt you "This
program cannot be run in DOS mode ".
DEBUG TEST.VXD
LEæ–‡ä»¶æ ¼å¼æœ€æ—©å‡ºè‡ªOS/2 2.0。这ç§æ ¼å¼çš„文件å¯ä»¥åŒæ—¶åŒ…å«16ä½å’Œ32ä½ä»£ç ,
è¿™
æ£æ˜¯VxD需è¦çš„ï¼Œå› ä¸ºVxDåœ¨åŠ è½½çš„åˆå§‹åŒ–阶段,需è¦è¿›è¡Œä¸€äº›å®žæ¨¡å¼çš„æ“作,这
需è¦16ä½ä»£ç ,而VxD的主è¦è¿è¡Œé˜¶æ®µæ˜¯åœ¨32ä½çŽ¯å¢ƒä¸ï¼Œè¿™åˆéœ€è¦32ä½ä»£ç ,所
以
LEæ–‡ä»¶æ ¼å¼æ£å¥½é€‚åˆäºŽVxD。
VxDä¸ä»…有16ä½å’Œ32ä½ä¸¤ç§ä»£ç ,而且,它把数æ®æ®µå’Œä»£ç 段æ…和在一起,åªæ˜¯
通
过段å‰çš„æ ‡è¯†æ¥è¡¨æ˜Žè¯¥æ®µåœ¨è¿è¡Œæ—¶çš„特性。VxDä¹‹æ‰€ä»¥è¿™æ ·ï¼Œæ˜¯å› ä¸ºVxD所用的
Flat
mode的代ç å’ŒData selector有åŒæ ·çš„基本地å€å’Œé™åˆ¶ï¼Œè¿™æ ·å½“VxD想访问数æ®æˆ–
代
ç 时,用哪个段寄å˜å™¨éƒ½å¯ä»¥ã€‚VxDä¸å¸¸ç”¨çš„Segment Classè§è¡¨1。
在VxDä¸ï¼ŒLCODEã€PCODEå’ŒPDATA段包å«äº†ä¸»è¦çš„æ•°æ®å’Œä»£ç 。LCODE段所包
å«çš„æ•°æ®å’Œä»£ç 必须总在内å˜ä¸ï¼Œæˆ‘们在VxDä¸å¤„ç†ç¡¬ä»¶ä¸æ–的代ç 和相关数æ®
å¿…
é¡»ä½äºŽLCODE段ä¸ï¼Œå¦åˆ™ï¼Œåœ¨å¤„ç†ç¡¬ä»¶ä¸æ–时就会出现å¯æ€•çš„Page fault。
ICODE段包å«çš„是VxDåˆå§‹åŒ–æ—¶è¦å®Œæˆçš„工作,当VxD完æˆåˆå§‹åŽï¼ŒICODE段ä¸çš„
代ç 和数æ®å°†è¢«VMM抛弃。
RCODEä¸åŒ…å«çš„是16ä½ä»£ç 和数æ®ï¼Œç”¨ä½œå®žæ¨¡å¼åˆå§‹åŒ–阶段。
SCODEä¸åŒ…å«Static Codeå’ŒData,一般æ¥è¯´ï¼ŒSCODE对于动æ€åŠ 载的VxD尤其有
用。试想一下,如果å¯åŠ¨æ€åŠ 载的VxD包å«äº†ä¸€ä¸ªå›žè°ƒå‡½æ•°ï¼Œå½“ä½ å¸è½½è¿™ä¸ªVxDåŽ
,åˆéœ€è¦è¿™ä¸ªå›žè°ƒå‡½æ•°ç»§ç»å‘ç”Ÿä½œç”¨ï¼Œé‚£ä½ å°±å¾—æŠŠè¿™ä¸ªå›žè°ƒå‡½æ•°æ”¾åˆ°SCODEä¸ã€‚
å†
è€…ï¼Œå¦‚æžœä½ éœ€è¦çŸ¥é“æŸä¸ªåŠ¨æ€åŠ 载的VxDè¢«åŠ ã€å¸è½½äº†å‡ 次,那å¯ä»¥åœ¨SCODEä¸æ”¾
个记数器,æ¯æ¬¡è¯¥VxDè¢«åŠ è½½æ—¶éƒ½æŠŠè¯¥è®°æ•°å™¨åŠ ä¸€ã€‚
由于VxDçš„æ–‡ä»¶æ ¼å¼æ¯”è¾ƒç‰¹æ®Šï¼Œæ‰€ä»¥ä½ å¿…é¡»ä½¿ç”¨å¯ä»¥äº§ç”ŸLEæ ¼å¼çš„链接器(
Linker
).å¦‚æžœä½ è¦å¼€å‘Windows 3.1çš„VxD,那得用Windows 3.1 DDK带的链接器。但
是
如果开å‘Win95çš„VxD,那用MSVC 2.0åŠå…¶ä»¥åŽç‰ˆæœ¬çš„链接器就å¯ä»¥äº†ã€‚有一点需
è¦æ³¨æ„,MSVC 4.1的链接器由于å˜åœ¨ä¸€äº›å°BUG,ä¸èƒ½ç”¨äºŽç”ŸæˆVxD。
Table 1
Segment Class æ è¿°
LCODE Pageï¼locked code and data
PCODE Pageable code
PDATA Pageable data
ICODE Initializationï¼only code and data
SCODE Static code and data
RCODE Realï¼mode initialization
**********************************
***************************
VxD世界——VxDå¼€å‘的利器SoftIce/VToolsD
SoftIce的安装
对于从事Windows系统开å‘的人æ¥è¯´ï¼ŒSoftIce是必ä¸å¯å°‘的利器。目å‰SoftIce
的最
新版本是3.24,有Win 95的版本,也有Win NT的版本。SoftIce 3.24 for Win
95å¯ä»¥
从国内的一些FTP站下载。
在SoftIce的安装过程ä¸ï¼Œæœ‰ä¸€æ¥æ˜¯å¾ˆé‡è¦çš„,那就是对显å¡çš„测试。新版本的
SoftIceæ供对更多ç§æ˜¾å¡çš„支æŒã€‚如果说显å¡ä¸è¢«SoftIce支æŒï¼Œé‚£å°±æ„味ç€
SoftIceå°†æ— æ³•æ£å¸¸å·¥ä½œã€‚
在安装过程ä¸ï¼Œå¦‚æžœTest通ä¸è¿‡ï¼Œé‚£å°±è¯•ç€é€‰ä¸€ä¸‹Universal Video Driver或者
Use
monochrome card/monitor。如果还通ä¸è¿‡çš„è¯ï¼Œé‚£å°±åœ¨Display Adapter
Selection
列表框ä¸é€‰æ‹©Stand VGAå†è¯•ã€‚如果还ä¸è¡Œçš„è¯ï¼Œé‚£å°±è¯•ç€åŽ»ä¸‹è½½ä¸€ä»½new
SoftIce
video driver(在国内的FTP站上也å¯ä»¥æ‰¾åˆ°ï¼‰ï¼Œå¦‚æžœè¿æ°”好的è¯ï¼Œä½ 的显å¡ä¼š
被
SoftIce支æŒã€‚
安装过程结æŸåŽï¼Œé‡æ–°å¯åŠ¨è®¡ç®—机,按下Ctrl+D进入SoftIce,如果SoftIce能
æ£å¸¸
工作,那我们的安装就æˆåŠŸäº†ã€‚ä½ å¯ä»¥æ•²å…¥helpæ¥çœ‹ä¸€ä¸‹SoftIce的简è¦å¸®åŠ©ï¼Œ
或者
,按下Ctrl+D返回Windowsæ¡Œé¢ã€‚
VToolsD的安装
在VToolsD出世之å‰ï¼ŒVxDçš„å¼€å‘者é¢å¯¹DDK浩如烟海的å¤æ€ªçš„asm代ç ,能å¿å—下
æ¥çš„人ä¸å¤šã€‚VToolsD就是把幸ç¦å¸¦ç»™VxDå¼€å‘者的天使。就å‡è¿™ä¸€ç‚¹ï¼ŒVToolsD
å°±
令VxDå¼€å‘者趋之若鹜。VToolsD是Vireoå…¬å¸çš„作å“,目å‰å›½å†…çš„FTP站上有
VToolsD 2.03 for Win95下载(如果è¿æ°”好的è¯ï¼Œè¿˜å¯ä»¥æ‰¾åˆ°2.04ã€2.05b)。
从国
内FTP站下载的VToolsD在安装时有一些需è¦æ³¨æ„的地方。
首先,在安装过程ä¸ä¼šé‡åˆ°å¯¹è¯æ¡†ï¼Œè¯¢é—®ä½ 是å¦éœ€è¦MASM6.11c。VToolsD并ä¸åŒ…
å«MASM 6.11c,但是,å¯ä»¥ä»ŽDDK for Win95ä¸æ‰¾åˆ°MASM 6.11cã€‚å½“ä½ çš„ç¨‹åºä¸
需è¦åµŒå…¥æ±‡ç¼–代ç 时,MASM 6.11cå°±ä¸å¯ç¼ºå°‘äº†ï¼ˆå¦‚æžœä½ åªç”¨Cè¯è¨€å¼€å‘VxD,那
就用ä¸ç€äº†ï¼‰ã€‚
图1所示是对调试器的选择,请选择SoftIce。
图1 调制器的选择
在SoftIce的路径设置对è¯çä¸ï¼Œè¯·é€‰æ‹©SoftIceçš„Util16å目录。
å†è€…,在安装过程ä¸ï¼Œå›¾2所示的两个选项是ä¸èƒ½é€‰çš„,å¦åˆ™ï¼Œå®‰è£…è¿‡ç¨‹å°†æ— æ³•
æ£å¸¸ç»“
æŸã€‚
图2 ä¸è¦é€‰æ‹©çš„两个选项
在VToolsD安装完æˆä¹‹åŽï¼Œé‡æ–°å¯åŠ¨è®¡ç®—机,然åŽï¼Œè¿›åˆ°VToolsD安装目录下的
examples\c\simple\下,敲如下的命令:
nmakeï¼f simple.mak
如果一切æ£å¸¸çš„è¯ï¼Œå°†ç”Ÿæˆsimple.vxd。
如果ä¸è¡Œçš„è¯ï¼Œé‚£å°±åœ¨DOSæ示符下敲set命令,检查一下环境å˜é‡çš„设置。下é¢
是
我的系统ä¸ç›¸åº”环境å˜é‡çš„è®¾ç½®ï¼Œä½ éœ€è¦æ ¹æ®è‡ªå·±ç³»ç»Ÿçš„实际情况调整一下路径
Set up
:
VTOOLSD=E:\VTD95
PATH= ï¼…PAHï¼…;C:\MSDEV\BIN; E:\VTD95\BIN
INCLUDE=C:\MSDEV\INCLUDE; E:\VTD95\INCLUDE
LIB=C:\MSDEV\LIB;E:\VTD95\LIB
把这些环境å˜é‡çš„è®¾ç½®åŠ åˆ°autoexec.batä¸åŽ»ï¼Œä»¥ä½¿å…¶æ¯æ¬¡å¼€æœºéƒ½è‡ªåŠ¨è®¾ç½®ã€‚
*********************************
**
*******************************
VxD世界——用VToolsDå¼€å‘一个简å•çš„VxD
这一次,我们讲一下如何用VToolsDå¼€å‘一个最简å•çš„VxD,以åŠç”¨SoftIce进行
æºç¨‹åº
级的调试。
VToolsD的使用
在VtoolsDä¸ï¼Œæœ‰ä¸€ä¸ªæœ€é‡è¦çš„VxDå¼€å‘工具:QuickVxD。QuickVxDå¯ä»¥ä¸ºæˆ‘们自
动生æˆVxDæºç¨‹åºæ¡†æž¶ï¼Œè€Œä¸”QuickVxDæ供了许多VxD的特性选项,例如å¯ä»¥é€‰æ‹©
è¦ç”Ÿæˆçš„VxD是动æ€åŠ 载的或是é™æ€åŠ 载的,è¦ä½¿ç”¨çš„编程è¯è¨€æ˜¯C还是C++ç‰
ç‰ã€‚
我们è¦åˆ©ç”¨QuickVxD自动生æˆçš„是一个å¯åŠ¨æ€åŠ 载的ã€åŸºäºŽCè¯è¨€çš„VxD框架。之
所以选用动æ€åŠ 载的VxD,是为了调试VxD的方便。æ¯æ¬¡ä¿®æ”¹ä»£ç ,é‡æ–°ç¼–译连接
之åŽï¼Œè¦ä½¿VxDé‡æ–°ç”Ÿæ•ˆï¼Œå¦‚果采用é™æ€åŠ 载的VxD,那就ä¸å¾—ä¸é‡æ–°å¯åŠ¨ç”µè„‘,
而若采用了动æ€åŠ 载的VxD,那åªé¡»ä½¿ç”¨VToolsD带的å¦ä¸€ä¸ªå¼€å‘工具VxDLoadå°±
å¯ä»¥å¸å‡ºæˆ–é‡æ–°åŠ 载内å˜ä¸çš„VxD。之所以采用Cè¯è¨€è€Œä¸æ˜¯Cï¼‹ï¼‹ï¼Œæ˜¯å› ä¸ºå…¶ç®€
æ´
易懂。请按照如图1~图4进行选择。按下Generate Now按钮,我们就获得了动æ€
åŠ
载的ã€åŸºäºŽCè¯è¨€çš„VxDçš„æºç¨‹åºã€‚
å¦‚æžœæ‚¨æ˜¯æŒ‰ç…§ä¸Šä¸€ç¯‡æ–‡ç« ä¸è®²è¿‡çš„VToolsD的编译环境设置系统,那我们就å¯ä»¥
ç¼–
译刚æ‰ç”Ÿæˆçš„这个最简å•çš„VxD了。在DOSæ示符下输入指令:
nmake ï¼f myfirst.mak
看一下当å‰ç›®å½•ä¸‹æ˜¯å¦ç”Ÿæˆäº†myfirst.vxd,如果有,那我们下é¢å‡†å¤‡å¯¹è¿™ä¸ª
VxD进行
æºç¨‹åºçº§çš„调试。如果没有,那么很å¯èƒ½æ˜¯æ‚¨çš„编译环境没有æ£ç¡®é…置,请找æ¥
上
ä¸€ç¯‡æ–‡ç« å¥½å¥½è¯»è¯»ã€‚
用VxDLoadåŠ è½½myfirst.vxd(è§å›¾5)
按下Load按钮,会出现VxD load successfully消æ¯æ¡†ã€‚
用SoftIce调试VxD
对于SoftIce选å•ä½œå¦‚下选择:
(1)File→Open Module选择我们刚æ‰ç”Ÿæˆçš„myfirst.vxd。
(2)Module→Translate,如果Symbol Loaderæç¤ºæ— æ³•åŠ è½½ä¸€äº›asm文件,那就
跳过
所有的asm文件。
(3)Module→Load。
按下Ctrl+D,进入SoftIceè¿è¡ŒçŽ¯å¢ƒä¸ï¼ˆå¦‚æžœæ‚¨è¿˜æ²¡æœ‰æŒ‰ç…§ä¸Šä¸€ç¯‡æ–‡ç« ä¸å®‰è£…
SoftIceçš„è¯ï¼Œé‚£å°±æ— 法å†è¿›è¡Œä¸‹é¢çš„测试)。输入如下指令:
:file ?
myfirst.c
:file myfirst.c
这时,在SoftIceä¸ï¼Œæ‚¨å°†ä¼šçœ‹åˆ°myfirst.cçš„æºç¨‹åºã€‚
图1选项页é¢ä¹‹ä¸€
图2选项页é¢ä¹‹äºŒ
图3选项页é¢ä¹‹ä¸‰
图4å¯ä»¥ç”ŸæˆVxDæºç¨‹åºäº†
图5用VxD LoadåŠ è½½myfirst.vxd
*********************************
**
*******************************
VxD世界——VxD的结构
在上一次“走进VxDâ€ä¸–ç•Œä¸ï¼Œæˆ‘们用VToolsD生æˆäº†ä¸€ä¸ªæœ€ç®€å•çš„å¯ä»¥åŠ¨æ€åŠ è½½
çš„
VxD——MYFIST程åºã€‚我们以这个例å为基础,ä¸æ–地丰富其功能,并以æ¤è®²è§£
一些V
xD的基本技术。
下é¢æ˜¯MYFIRST主è¦ç»„æˆä¹‹ä¸€ï¼šMYFIRST.C。
// MYFIRST.c ï¼ main module for VxD MYFIRST
#define DEVICE_MAIN
#include "myfirst.h"
#undef DEVICE_MAIN
Declare_Virtual_Device(MYFIRST)
VOID_cdecl V86_Api_Handler(VMHANDLE hVM, PCLIENT_STRUCT pcrs) { }
VOID _cdecl PM_Api_Handler(VMHANDLE hVM, PCLIENT_STRUCT pcrs) { }
DefineControlHandler(SYS_DYNAMIC_DEVICE_INIT,
OnSysDynamicDeviceInit);
DefineControlHandler(SYS_DYNAMIC_DEVICE_EXIT,
OnSysDynamicDeviceExit);
DefineControlHandler(W32_DEVICEIOCONTROL, OnW32Deviceiocontrol);
BOOL _cdecl ControlDispatcher(
DWORD dwControlMessage,
DWORD EBX, DWORD EDX,
DWORD ESI, DWORD EDI, DWORD ECX)
{ START_CONTROL_DISPATCH
ON_SYS_DYNAMIC_DEVICE_INIT(OnSysDynamicDeviceInit);
ON_SYS_DYNAMIC_DEVICE_EXIT(OnSysDynamicDeviceExit);
ON_W32_DEVICEIOCONTROL(OnW32Deviceiocontrol);
END_CONTROL_DISPATCH
return TRUE;}
BOOL OnSysDynamicDeviceInit()
{ return TRUE; }
BOOL OnSysDynamicDeviceExit()
{ return TRUE; }
DWORD OnW32Deviceiocontrol(PIOCTLPARAMS p)
{ return 0; }
记得在å‰é¢çš„æ–‡ç« ä¸æ到过,VxDå¯ä»¥ä¸Žåº”用程åºå®žçŽ°ç›¸äº’通信。我们在用
QuickVxD生æˆè¿™ä¸ªä¾‹å时,åˆé€‰ä¸äº†æ”¯æŒåŠ¨æ€åŠ 载和Real/V86 Mode APIåŠ
Protected Mode APIç‰é€‰é¡¹ã€‚上é¢ç¨‹åºä¸ï¼Œå‡½æ•°V86_Api_Handler用æ¥å®žçŽ°VxD与
16ä½çš„DOS应用程åºé€šä¿¡ï¼Œå‡½æ•°PM_Api_Handler用æ¥å®žçŽ°VxD与16ä½çš„Windows
应用程åºæˆ–DOSï¼Extended(DPMI)应用程åºé€šä¿¡ï¼Œå‡½æ•°OnW32Deviceiocontrol用
æ¥
实现VxD与32ä½çš„Windows应用程åºé€šä¿¡ã€‚函数OnSysDynamicDeviceInitå’Œ
OnSysDynamicDeviceExit自然是用æ¥æŽ§åˆ¶VxD动æ€åŠ 载和å¸è½½å•¦ã€‚
上é¢çš„代ç ä¸æœ‰ä¸¤ä¸ªå®DefineControlHandlerå’ŒControlDispatcher,用æ¥æŠŠè¿™
些函数
与VxD的消æ¯æœºåˆ¶è”系起æ¥ã€‚好åƒæˆ‘们æžæ¸…楚了,ä¸ï¼Œå†ä»”细看一下,å®
DefineControlHandlerå’ŒControlDispatcher都åªæ˜¯å®šä¹‰äº†ä¸‰ä¸ªå‡½æ•°
OnW32Deviceiocontrolã€OnSysDynamicDeviceInitå’ŒOnSysDynamicDeviceExitçš„
消
æ¯æ˜ 射关系。我们很自然地想到,函数V86_Api_Handlerå’ŒPM_Api_Handlerå‘¢
,为什么能肯定VxD一定用这两个函数与16ä½åº”用程åºé€šä¿¡å‘¢ï¼Ÿ
让我们在VToolsDçš„includeå目录下找一找,我们会å‘现VToolsC.hä¸æœ‰è¿™ä¸¤ä¸ª
函数
的定义。下é¢çš„代ç 摘自VToolsC.h。
#define Declare_Virtual_Device_Ex(VName, RefData) \
extern _C_ void _cdecl V86_Api_Handler(VMHANDLE hVM, PCLIENT_
STRUCT pRegs); \
extern _C_ void _cdecl PM_Api_Handler(VMHANDLE hVM, PCLIENT_
STRUCT pRegs); \
extern _C_ void (?VXD_SERVICE_TABLE[])(); \
_EXC_ DDB The_DDB = { 0, DDK_VERSION, VName##_DeviceID, VName
##_Major, \
VName##_Minor, 0, {′ ′,′ ′,′ ′,′ ′,′ ′,′ ′,′ ′,′ ′},
\
VName##_Init_Order, (DWORD) LocalControlDispatcher, \
(DWORD) LocalV86handler, \
(DWORD) LocalPMhandler, 0, 0, RefData, (DWORD) VXD_SERVICE_TABLE, \
0, \
0, \
_SIG_} ;
// This is the standard macro for declaring a DDB, using all default
value
s.
#define Declare_Virtual_Device(VName) Declare_Virtual_Device_
Ex(VName,0)
从上é¢çš„代ç ä¸ï¼Œæˆ‘们å¯ä»¥çœ‹åˆ°ï¼Œå‡½æ•°V86_Api_Handlerå’ŒPM_Api_Handler被
å®Declare_Virtual_Device声明已在DDB(Device Descriptor Block)ä¸ï¼Œè‡ªç„¶
ä¸
用å†åœ¨MYFIRST.Cä¸è¿›è¡Œæ¶ˆæ¯æ˜ 射了。
****************************************
**
*******************************
VxD世界__VxD的设备æè¿°å—与VxD API
VxD设备æè¿°å—
用汇编è¯è¨€æè¿°MYFIRST.VxD的设备æè¿°å—(DDB Device Descriptor Block)如下
(
其实,如果是用DDKæ¥å¼€å‘VxD,那我们在æ¯ä¸ªVxDçš„æºç¨‹åºä¸éƒ½ä¼šè§åˆ°è¿™äº›ä»£ç
,åªæ˜¯VToolsD替我们å°è£…了这些费解的东西):
Declare_Virtual_Device MYFIRST,1,0,MYFIRST_Control,MYFIRST_
Device_ID,MYFIRST_Init_Order,MYFIRST_V86_API_Handler,
MYFIRST_PM_API_Handler
对于DDBçš„8个入å£æ¥è¯´ï¼Œåªæœ‰å‰é¢4个是必须的,åŽé¢4个的缺çœå€¼ä¸º0,如果我
们
çš„MYFIRST.VxDä¸è¾“出V86 API,那么上é¢çš„代ç åº”è¿™æ ·å†™ï¼š
Declare_Virtual_Device MYFIRST,1,0,MYFIRST_Control,MYFIRST_
Device_ID,MYFIRST_Init_Order,,MYFIRST_PM_API_Handler
一般æ¥è¯´ï¼ŒMYFIRST_Init_Order是å¯ä»¥è®¾ä¸ºç¼ºçœå€¼0çš„ï¼Œå› ä¸ºæˆ‘ä»¬ä¸€èˆ¬ä¸éœ€è¦ç‰¹
殊的åˆå§‹åŒ–顺åºã€‚
ä½ ä¸€å®šä¼šå¥‡æ€ªMYFIRST_Control是怎么回事。读一下下é¢çš„代ç ,大概就明白了
.
BeginProc MYFIRST_Control
Begin_Control_Dispatch MYFIRST_Control
Control_Dispatch Sys_Dynamic_Device_Init, OnSysDynamicDeviceInit
Control_Dispatch Sys_Dynamic_Device_Exit, OnSysDynamicDeviceExit
.........
End_Control_Dispatch MYFIRST_Control
EndProc MYFIRST_Control
对比一下VToolsD为我们生æˆçš„C程åºï¼š
BOOL _cdecl ControlDispatcher(
DWORD dwControlMessage,
DWORD EBX,DWORD EDX,
DWORD ESI, DWORD EDI,
DWORD ECX)
{ START_CONTROL_DISPATCH
ON_SYS_DYNAMIC_DEVICE_INIT(OnSysDynamicDeviceInit);
ON_SYS_DYNAMIC_DEVICE_EXIT(OnSysDynamicDeviceExit);
END_CONTROL_DISPATCH
return TRUE;}
Windows是基于消æ¯æœºåˆ¶çš„æ“作系统,这一点在VxDä¸ä¹Ÿä½“现了出æ¥ã€‚MYFIRST_
Control就是接收Windows消æ¯çš„å…¥å£ç‚¹ã€‚Windowså‘ç»™MYFIRST_Control的消æ¯
与å‘ç»™Windows应用程åºçš„消æ¯ä¸å®Œå…¨ä¸€æ ·ï¼Œå‰è€…包å«äº†ä¸€äº›ç³»ç»Ÿä¿¡æ¯ã€‚MYFIRST
_Control在收到消æ¯åŽï¼Œè°ƒç”¨ç›¸åº”的控制过程。
VxD API
在å‰é¢çš„æ–‡ç« ä¸ï¼Œæˆ‘们说MYFIRST.VxD将支æŒReal/V86 Mode APIåŠProtected
Mode API,这使得MYFIRST.VxDå¯ä»¥ä¸ŽV86应用程åºæˆ–Win16应用程åºé€šä¿¡ã€‚
MYFIRST.VxD输出的V86 API和PM API就是
VOID _cdecl V86_Api_Handler(VMHANDLE hVM, PCLIENT_STRUCT pcrs);
VOID _cdecl PM_Api_Handler(VMHANDLE hVM, PCLIENT_STRUCT pcrs);
一个问题很快就摆在我们é¢å‰ï¼šå¦‚何在我们的应用程åºä¸è°ƒç”¨åˆ°è¿™ä¸¤ä¸ªAPI?
读一下这段代ç :
DWORD NEAR PASCAL GetAPIEntry(WORD VxD_ID)
{DWORD Entry_Point;
_asm{
mov AX, 1684h
mov BX, WORD PTR SS: [VxD_ID]
sub DI, DI
mov ES, DI
int 2Fh
mov WORD PTR SS: [Entry_Point][0], DI
mov WORD PTR SS: [Entry_Point][2], ES
} return Entry_Point;}
这段代ç å¯ä»¥ç”¨åœ¨MS_DOS应用程åºæˆ–是Win16应用程åºä¸ï¼Œå‡½æ•°GetAPIEntry将分
别返回V86_Api_Handler的地å€æˆ–PM_Api_Handler的地å€ã€‚
ç‰ä¸€ä¸‹ï¼Œå‡½æ•°GetAPIEntryçš„å…¥å£å‚æ•°VxD_ID是怎么回事?嗯,问得好。如果ä½
一
ç›´åœ¨è¯»æˆ‘çš„æ–‡ç« ï¼Œé‚£ä½ ä¼šå‘现我们在å‰é¢æœ‰ä¸€ä¸ªå¤±è¯¯ï¼šåœ¨ç”¨QuickVxD生æˆ
MYFIRST.VxDçš„æºç¨‹åºæ—¶ï¼ŒæŠŠMYFIRST.VxDçš„DeviceIDç½®æˆäº†UNDEFINED_
DEVICE_ID。通过在VToolsD\include\Vmm.hä¸æŸ¥æ‰¾ï¼Œå¯ä»¥çœ‹åˆ°ï¼š
#define UNDEFINED_DEVICE_ID 0x00000
也就是说所有UNDEFINED_DEVICE_IDçš„VxDçš„DeviceID都置æˆäº†0。如果我们
å‘函数GetAPIEntryä¼ é€’MYFIRST_DeviceID,那我们很å¯èƒ½æ— 法获得
MYFIRST.VxDä¸çš„API的地å€ï¼Œå› 为我们的DeviceIDä¸æ˜¯æƒŸä¸€çš„,Windowsæ— æ³•åœ¨
众多DeviceID为0çš„VxDä¸æ‰¾åˆ°æˆ‘们的MYFIRST.VxD。 then what should we do?
解决方案有两个:
方案一:
å†ç”¨QuickVxDé‡æ–°ç”ŸæˆMYFIRST.VxDçš„æºç¨‹åºã€‚è®°ç€åœ¨Device Parameters页ä¸å¡«
写Device ID为æŸä¸ªå€¼ï¼Œè¿™ä¸ªå€¼å°½é‡å¤§ä¸€äº›ï¼Œå› 为比较å°çš„DeviceID都让
Microsoft或
是别的硬件开å‘商注册了(注册是需è¦é“¶å的),为了ä¿è¯ä¸ä¸Žç³»ç»Ÿä¸çŽ°å˜çš„
VxD
çš„DeviceIDå‘生冲çªï¼Œæˆ‘们åªå¥½æŠŠDeviceID设得大一些,比如说0xAAAA。
Option II:
编辑一下MYFIRST.H,把MYFIRST_DeviceID改了,改过之åŽçš„MYFIRST.h如下
:
#include 〈vtoolsc.h〉
#define MYFIRST_Major 1
#define MYFIRST_Minor 0
#define MYFIRST_DeviceID 0xAAAA
#define MYFIRST_Init_Order UNDEFINED_INIT_ORDER
好了,我们已ç»å‡†å¤‡å¥½ä¸Žæˆ‘们的MYFIRST.VxD通信了。
Incremental encoders provide speed, direction and relative position feedback by generating a stream of binary pulses proportional to the rotation of a motor or driven shaft. Lander offers both optical and magnetic incremental encoders in 4 mounting options: shafted with coupling, hollow-shaft, hub-shaft or bearingless. Single channel incremental encoders can measure speed which dual channel or quadrature encoders (AB) can interpret direction based on the phase relationship between the 2 channels. Indexed quadrature encoders (ABZ) are also available for homing location are startup.
Incremental Encoder,6Mm Solid Shaft Encoder,Hollow Rotary Encoder,Elevator Door Encoder
Jilin Lander Intelligent Technology Co., Ltd , https://www.jllandertech.com