WEB开发网
开发学院软件开发汇编语言 虚拟设备驱动程序初步 阅读

虚拟设备驱动程序初步

 2007-05-02 09:30:38 来源:WEB开发网   
核心提示:Windows 95下有两种VxD: 静态VxD 动态VxD 静态VxD是那些从系统启动就被加载,在系统关闭之前一直存在于内存中的VxD程序,虚拟设备驱动程序初步(2),这种VxD可以追溯至Windows 3.x的时代,动态VxD时只有Windows 9x下才有的,保护模式和Win32应用程序的接口,在下一章里,动态V

Windows 95下有两种VxD:
静态VxD
动态VxD
静态VxD是那些从系统启动就被加载,在系统关闭之前一直存在于内存中的VxD程序。这种VxD可以追溯至Windows 3.x的时代。动态VxD时只有Windows 9x下才有的。动态VxD程序可以在需要的时候被加载/卸载。这些程序大多数都是用来控制设置管理器和输入输出监视器加载的即插即用设备的。你可以在你的win32应用程序里加载或卸载动态VxD程序。
VxD程序之间的通讯
VxD程序,包括VMM,通过以下三种途径在相互之间进行通讯:
控制消息
服务API
回调
控制消息: 当有VMM感兴趣的事件发生时,它就向系统中所有载入的VxD程序发送控制消息。控制消息就像是第三层级别的Windows应用程序的消息。每个VxD程序都有一个接受和处理控制消息的函数,叫做设备控制函数。系统控制消息总共有50多个。控制消息不多的原因是系统中通常加载了很多VxD程序,而每个VxD程序在收到一个控制消息时都要进行处理。如果控制消息太多,就会导致系统停滞。所以控制消息只包括那些与虚拟机有关的重要消息,如:一个虚拟机被创建,被销毁等等。作为对系统控制消息的附加,一个VxD程序可以定义自己的控制消息,这些消息可以用来和那些能响应这些消息的VxD程序通讯。
服务函数: 一个VxD程序,包括VMM在内,通常要导出一系列的被别的VxD程序调用的公共函数,这些函数被称为VxD服务。调用这些服务的机制和在第三层级别运行的的应用程序有很大的不同:每个导出VxD服务的VxD程序必须有一个唯一的ID,你可以从Microsoft得到一个这样的ID。这个ID是一个包含了一个VxD唯一的身份验证的16位的数字,例如:

UNDEFINED_DEVICE_ID EQU 00000H
VMM_DEVICE_ID EQU 00001H
DEBUG_DEVICE_ID EQU 00002H
VPICD_DEVICE_ID EQU 00003H
VDMAD_DEVICE_ID EQU 00004H
VTD_DEVICE_ID EQU 00005H
你可以看到VMM的ID是1,VPICD的ID是3,等等。VMM用这些ID来找到导出所需VxD服务的VxD程序。当一个VxD程序导出VxD服务时,它把所有服务的地址存在一个表里面。所以,你还需要通过服务分支表里面服务的索引来找到你所要的服务。例如,如果你要调用第一个服务,GetVersion服务,你就要指定0(这个索引是从0开始的)。调用VxD服务的实机制包括中断20h,你的代码产生一个中断20h,并带有一个双字的值,这个值包含了设备ID和服务索引。例如,如果你要调用一个VxD程序导出的VxD服务,假设VxD程序设备ID是000DH,服务号码是1,那么代码应该是:
int 20h
dd 000D0001h
跟在中断20H后的双字的高字包含设备ID。低字是在服务列表中的索引。
当20H中断执行时,VMM得到了控制权,并马上检测跟着的双字。然后它提出设备ID用来找到VxD程序,用服务索引来定位在那个VxD程序中的所要求的服务的地址。
你可以看到这个操作时很费时的。VMM必须浪费很多时间来定位VxD程序和所要服务的地址,所以VMM作了个小小的弊 。当中断20H操作成功后,VMM抓取链接。这就是说,VMM用直接的服务调用来替代20H中断和它后面的双字。所以上面的20H中断代码片断就被改变成:
call dword ptr [VxD_Service_Address]
这个把戏是成功的,因为int 20h+dword加一个双字用6个字节,正好和call dword ptr结构相等。所以接下来的服务调用是快速而有效的。这个方法具有直接性,简洁性。在好的一方面,它减轻了VMM和VxD载入器的工作量,因为它们不用定位VxD中所有的服务,那些没有执行过的服务将会保持原样。再不那么好的一方面,一旦一个静态VxD程序导出的服务被调用,那么就不可能把这个静态的VxD程序卸载了。由于VMM把调用锁定到VxD服务的实际地址上,如果提供这个服务的VxD程序从内存中被卸载了,其他VxD程序调用这个服务时就会很快的因为调用无效的内存地址而导致系统崩溃。没有办法来消除抓取的链接。这个问题的结论是动态VxD不适合作为服务提供者。
回调: 回调或者回调函数是在VxD程序中给其他的VxD程序调用的函数,不要把回调函数和VxD服务搞混淆了。回调函数不像服务那样是公共的,它们是私有函数,VxD在特定的情况下把它们的地址送给其他的VxD程序。例如,当一个VxD程序在处理一个硬件中断时,由于VMM是不可重入的,这个VxD程序不能使用VxD服务,否则会引起页面错误(重入VMM)。这个VxD程序可以把它自己的一个回调函数的地址给VMM,这样VMM就可以在能忍受页面错误时调用这个函数。回调函数的想法不是VxD独有的。许多Windows API都在用。最好的例子也许是窗口函数,你把窗口函数的地址填在WINDCLASS或WINDCLASSEX结构里并把它当作函数来调用RegisterClass或者RegisterClassEx。当有这个窗口的消息传来时,Windows就会调用你的窗口函数。另一个例子是窗口接管函数。你的程序把接管函数的地址送给Windows,这样当你感兴趣的事件发生时,Windows就会调用你的接管函数。
上述三种方法是VxD之间通讯的,我们还要讲对V86,保护模式和Win32应用程序的接口。在下一章里,我们要学习VxD对Win32应用程序的接口。

上一页  1 2 

Tags:虚拟 设备 驱动程序

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接