⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vxd-e1.html

📁 汇编语言编写的虚拟驱动程序
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<font face="Arial,Helvetica"><font size=-1>VxDs are specific to Windows
9x. They can't run on Windows NT. So if your program depends on VxDs, it
will not be portable to Windows NT platform.</font></font></li>

<li>
<font face="Arial,Helvetica"><font size=-1>VxDs are the most powerful entities
in the system. Since they can do anything to the system, they are also
extremely dangerous. An ill-behaved VxD can crash the system. There is
no safeguard against ill-behaved VxDs.</font></font></li>

<li>
<font face="Arial,Helvetica"><font size=-1>Usually, there are lots of way
to achieve the goal you desire without resorting to VxDs. Think and think
twice before taking the VxD solution. If there are other ways to perform
the task in ring 3, use them.</font></font></li>
</ul>
<font face="Arial,Helvetica"><font size=-1>There are two types of VxD under
Windows 95</font></font>
<ul>
<li>
<font face="Arial,Helvetica"><font size=-1>Static VxD</font></font></li>

<li>
<font face="Arial,Helvetica"><font size=-1>Dynamic VxD</font></font></li>
</ul>
<font face="Arial,Helvetica"><font size=-1>Static VxDs are those VxDs that
are loaded during system bootup and stay loaded until the system shutdown.
This type of VxD dates back from the days of Windows 3.x. Dynamic VxDs
are available under Windows 9x only. Dynamic VxDs can be loaded/unloaded
when needed. Most of them are VxDs that controls Plug and Play devices
which are loaded by Configuration Manager and Input Output Supervisor.
You can also load/unload dynamic VxDs from your win32 applications.</font></font>
<h3>
<font face="Arial,Helvetica"><font color="#66FFFF"><font size=-1>Communication
between VxDs</font></font></font></h3>
<font face="Arial,Helvetica"><font size=-1>VxDs, including VMM, communicate
with each other via three mechanisms:</font></font>
<ul>
<li>
<font face="Arial,Helvetica"><font size=-1>Control Messages</font></font></li>

<li>
<font face="Arial,Helvetica"><font size=-1>Service APIs</font></font></li>

<li>
<font face="Arial,Helvetica"><font size=-1>Callbacks</font></font></li>
</ul>
<font face="Arial,Helvetica"><font size=-1><b><u><font color="#FF99FF">Control
Messages</font></u></b>: VMM sends system control messages to <b><font color="#FFFF99">ALL</font></b>
loaded VxDs in the system when some interesting events occur. In this regards,
control messages are like windows messages of the ring-3 Windows applications.
Every VxD has a function that receives and deals with control messages
called <b><font color="#FFFF99">device control procedure</font></b>. There
are about 50 or so system control messages. The reason that there are not
many control messages is that there are often many VxDs loaded in the system
and each of them gets a crack at every control message, if there are too
many control messages, the system will grind to a halt. Thus you would
find only the really important messages related to VMs such as when a VM
is created, destroyed and such. In addition to system control messages,
a VxD can define its own custom control messages that it can use to communicate
with other VxDs that understand them.</font></font>
<p><font face="Arial,Helvetica"><font size=-1><b><u><font color="#FF99FF">Service
APIs</font></u></b>: A VxD, including VMM, usually exports a set of public
functions that can be called by other VxDs. Those functions are called
VxD services. The mechanism of calling those VxD services is quite different
from that of ring-3 applications. Every VxD that exports VxD services <b><font color="#FFFF99">MUST</font></b>
have a unique ID number. You can obtain such IDs from Microsoft. The ID
is a 16-bit number which uniquely identifies a VxD. For example,</font></font>
<ul><b><tt><font size=-1>UNDEFINED_DEVICE_ID&nbsp;&nbsp;&nbsp; EQU 00000H</font></tt></b>
<br><b><tt><font size=-1>VMM_DEVICE_ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
EQU 00001H</font></tt></b>
<br><b><tt><font size=-1>DEBUG_DEVICE_ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
EQU 00002H</font></tt></b>
<br><b><tt><font size=-1>VPICD_DEVICE_ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
EQU 00003H</font></tt></b>
<br><b><tt><font size=-1>VDMAD_DEVICE_ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
EQU 00004H</font></tt></b>
<br><b><tt><font size=-1>VTD_DEVICE_ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
EQU 00005H</font></tt></b></ul>
<font face="Arial,Helvetica"><font size=-1>You can see that VMM has the
ID of 1, VPICD has ID of 3 and so on. VMM uses this unique ID to find the
VxD that exports the requested VxD services. You also have to select the
service you want to call by its index in the service branch table. When
a VxD exports VxD services, it stores the addresses of the services in
a table. VMM will use the supplied index to locate the address of the desired
service from the service table. For example, if you want to call GetVersion
which is the first service, you have to specify 0 ( the index is zero-based).
The real mechanism of calling VxD services involves int 20h. Your code
issues int 20h followed by a dword value that is composed of the device
ID and the service index. For example, if you want to call service number
1 which is exported by a VxD that has the device ID of 000Dh, the code
would like this:</font></font>
<ul><b><font face="Arial,Helvetica"><font size=-1>int&nbsp; 20h</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>dd&nbsp; 000D0001h</font></font></b></ul>
<font face="Arial,Helvetica"><font size=-1>The high word of the dword that
follows int 20h instruction contains the device ID. The low word is the
zero-based index into the service table.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>When int 20h is issued,
VMM gains control and it examines the dword that immediately follows the
interrupt instruction. Then it extracts the device ID and uses it to locate
the VxD and then uses the service index to locate the address of the desired
service in that VxD.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>You can see that this operation
is time-consuming. VMM must waste time in locating the VxD and the address
of the desired service. So VMM <i><font color="#66FF99">cheats</font></i>
a little. After the first int 20h operation is successful, VMM <b><font color="#FFFF99">snaps
the link</font></b>. By snapping the link, it means VMM replaces the int
20h and the followed dword with the direct call to the service. So the
above int 20h snippet would be transformed to:</font></font>
<ul><b><font face="Arial,Helvetica"><font size=-1>call dword ptr [VxD_Service_Address]</font></font></b></ul>
<font face="Arial,Helvetica"><font size=-1>This trick works because the<b><font color="#FFFF99">
int 20h+dword</font></b> takes 6 bytes, which is exactly the same as <b><font color="#FFFF99">call
dword ptr</font></b> instruction. So subsequent calls are fast and efficient.
This method has its pros and cons. On the good side, it reduces the workload
of VMM and VxD Loader because they don't have to fix <b><font color="#FFFF99">ALL</font></b>
service calls of VxDs at load time. The calls which are never executed
will remain unmodified. On the not-so-good side, it makes it impossible
to unload the static VxD once its services are linked to. Since VMM fixes
the calls with the actual addresses of the VxD services, if the VxDs which
provide those services are unloaded from memory, other VxDs which are dependent
on their services will quite likely crash the system with calls to invalid
memory address. There is no mechanism to <b><font color="#FFFF99">unsnap</font></b>
the links. The corollary of this is that dynamic VxDs are not suitable
as VxD service providers.</font></font>
<p><font face="Arial,Helvetica"><font size=-1><b><u><font color="#FF99FF">Callbacks:</font></u></b>
callbacks or callback functions are functions in VxD that exist to be called
by other VxDs. Don't confuse between callbacks and VxD services. Callbacks
are not public like services. They are private functions whose adresses
the VxD gives to other VxDs in <font color="#FFFFCC">specific</font> situations.
For example, when a VxD is servicing a hardware interrupt, since VMM is
not reentrant, the VxD cannot use any VxD services that may cause page
faults (thus re-enter VMM). The VxD may give the address of one of its
own function (callback) to VMM so that VMM can call the function when VMM
can tolerate page faults. The VxD can then proceed with its work when its
callback function is called. The callback idea is not unique to VxD. Many
Windows APIs use them as well. The best example is perhaps the window procedure.
You specify the address of a window procedure in WNDCLASS or WNDCLASSEX
structure and pass it to Windows with RegisterClass or RegisterClassEx
call. Windows will call your window procedure when there are messages for
the window. Another example is the Window hook procedure. Your application
gives the address of the hook procedure to Windows so that Windows will
call it when the events the application is interested in happen.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>The above three methods
are for communication between VxDs. There are also interfaces for V86,
protected-mode and Win32 application. I will cover VxD interface for Win32
application in the next tutorials.</font></font>
<br>
<hr WIDTH="100%">
<center><b>[<a href="http://win32asm.cjb.net">Iczelion's Win32 Assembly
Homepage</a>]</b></center>

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -