VxD的初始化和结束[2]

[入库:2005年9月21日] [更新:2007年3月24日]

本文简介:

你也许会感到奇怪:为什么这两个消息后面都跟着个“2\" ”。这是因为:在VMM加载VxD程序的时候,它是按照初始化顺序值小的VxD先加载的顺序加载的,这样VxD程序就可以使用那些在它们之前加载的VxD程序提供的服务。例如,VxD2要用到VxD1中的服务,它就必须把它的初始化顺序值定义的比VxD小。加载的顺序是: 
..... VxD1 ===> VxD2 ===> VxD3 ..... 
那么卸载的时候,理所当然的是初始化顺序值大的VxD程序先被卸载,这样他们仍然可以使用比它们后加载的那些VxD程序提供的服务。如上面的例子,次序是: 
.... VxD3 ===> VxD2 ===> VxD1..... 
在上边的例子中,如果VxD2在初始化时调用了VxD1中的某些服务,那么卸载时它可能也要再次用到一些VxD1中的服务。System_Exit2和Sys_Critical_Exit2是反初始化顺序发送的。这表示,当VxD2接受到这些消息时,VxD1还没有被卸载,它仍可以调用VxD1的服务,而System_Exit和Sys_Critical_Exit消息不是按照反初始化顺序发送的。这意味着,你不能肯定你是否仍能调用在你之前加载的VxD提供的VxD服务。新一代的VxD程序不应该使用这些消息。 
还有两种退出消息: 
Device_Reboot_Notify2 告诉VxD程序VMM正在准备重新启动系统。这时候中断还是开放的。 
Crit_Reboot_Notify2 告诉VxD程序VMM正在准备重新启动系统。这时候中断已经被关闭了。 
到这里,你可以猜到还有Device_Reboot_Notify和Crit_Reboot_Notify 消息,但它们并不是像“2”版本的消息一样按反初始化顺序发送的。 
动态VxD: 
动态VxD在Windows9x里可以动态的被加载和卸载。这个特点在Window3.x下是没有的。动态VxD程序的主要作用是用来支持某些动态的硬件设备的重装,比如:即插即用设备。尽管如此,你可以从你的Win32程序中加载/卸载它,也可以把它看作是你的程序的一个到ring-0的扩展。 
上一节我们提到的例子是一个静态的VxD,你可以把它转换成一个动态的VxD,只要在.def文件中VxD标记的后面加上关键字DYNAMIC。 
VxD FIRSTVxD DYNAMIC 
这就是你把一个静态VxD转换成一个动态的VxD所要做的一切。 
一个动态的VxD可以按以下的方法被加载: 
把它放到你的Windows目录下的\\SYSTEM\\IOSUBSYS目录中。在这个目录里的VxD会被输入输出监视器(ios)加载。这些VxD必须支持层设备驱动。所以用这种方法加载你的动态VxD并不是一个好办法。 
用VxD加载服务。 VxDLDR是一个可以加载动态VxD的静态VxD。你可以在其他VxD里面或者在16位代码里面调用它的服务。 
用Win32应用程序里的 CreateFile API。你在调用CreateFile时,你的动态VxD要以下面的格式填写: 

\\\\.\\VxD完整路径名 

例如,如果你要加载一个在当前目录下名为FirstVxD的动态VxD,你需要做如下的工作: 

.data 
VxDName db \"\\\\.\\FirstVxD.VxD\",0 
...... 
.data? 
hDevice dd ? 
..... 
.code 
..... 
invoke CreateFile, addr VxDName,0,0,0,0, FILE_FLAG_DELETE_ON_CLOSE,0 
mov hDevice,eax 
...... 
invoke CloseHandle,hDevice 
...... 


FILE_FLAG_DELETE_ON_CLOSE 这个标志用来说明该VxD在CreateFile返回的句柄关闭时被卸载。 
如果你用CreateFile来加载一个动态VxD,那么这个动态VxD必须处理w32_DeviceIoControl 消息。当你的动态VxD第一次被CreateFile函数加载的时候,VWIN32 向你的VxD发出这个消息。你的VxD响应这个消息,返回时eax中的值必须为零。当应用程序调用DeviceIoControl API来与一个动态VxD通讯时,w32_DeviceIoControl消息也被发送。我们会在下一章讲到DeviceIoControl接口。 
一个动态VxD在初始化时收到一个消息: 
Sys_Dynamic_Device_Init 
在结束时也收到一个控制消息: 
Sys_Dynamic_Device_Exit 
动态VxD不会收到Sys_Critical_Init, Device_Init和Init_Complete控制消息,因为这些消息是在系统虚拟机初始化时发送的。除了这三个消息,动态VxD能收到所有的控制消息,只要它还在内存里。它可以做静态VxD可以做的所有事情。简单的说,动态VxD除了加载机制和接收到的初始化/结束消息跟静态VxD不同以外,它能做静态VxD所能做的一切。 
其它系统控制消息 
当VxD在内存里的时候,除了接收和初始化及结束相关的消息外,它还要收到许多别的控制消息。有些消息是关于虚拟机管理器的,有的是关于各种事件的。例如,关于虚拟机的消息如下: 
Create_VM 
VM_Critical_Init 
VM_Suspend 
VM_Resume 
Close_VM_Notify 
Destroy_VM 
选择地响应你所感兴趣的消息是你自己的责任。 
在VxD内创建函数 
你要在一个段里面定义你的函数。你应该首先定义一个段,然后把你的函数放进去。例如,如果你要把你的函数放到一个可调页段中。你应该先定义一个可调页段,像这样: 
VxD_PAGEABLE_CODE_SEG 
(你的函数写在这里) 

VxD_PAGEABLE_CODE_ENDS 

本文关键:VxD的初始化和结束
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top