Programming 版 (精华区)
发信人: tih (我不敢说), 信区: Programming
标 题: Windows 95虚拟设备驱动程序(VxD)6
发信站: 紫 丁 香 (Wed Sep 8 17:28:38 1999), 转信
六、写一个VxD
许多情况下,写一个VxD用来代替一个由Windows
95提供的标准VxD。然而,大多数情况下,写一个VxD是用来支持新硬件设备或者软件
的,在这种情况下,通常手工创建一个VxD比修改已经存在的VxD要容易,原因是大多
数VxD都是设备相关的。然而,已存在VxD的源代码需要尽可能地仔细分析,原因是它
们可能包含通用的格式和结构,以及说明怎样使用VMM和VxD服务去实现有用的功能。
写一个VxD需要下列步骤:
1、建立包含VxD各个段,VxD声明,设备控制过程,处理系统控制消息过程的基本
部分和API过程的基本部分的VxD框架。
2、加入实模式初始化过程(可选)。
3、完成处理初始化消息的过程。这些过程应该能够初始化控制块,分配全局内存
以及安装中断、I/O捕获和页错误回调过程。
4、完成处理不同中断和错误的回调过程。
5、为服务加入服务表定义和声明(可选)。
6、完成API过程(可选)
7、完成处理系统控制消息的过程以建立和删除虚拟机。
在写一个VxD的过程中,你可以安装该VxD并在调试器控制下运行Windows,在该VxD中
设置断点监视该VxD管理的中断,这样可以帮助你查明该VxD是否正确工作。
1、VxD段
VxD可以包含下面5个段的一些组合:
1)、VxD_CODE段:保护模式代码段(必须)。
该段包含VxD系统控制过程、回调过程、服务和API过程。该
段用宏VxD_CODE_SEG和VxD_CODE_ENDS定义开始和结束,也可命名为_LTEXT。
2)、VxD_DATA段:保护模式数据段(必须)。
该段包括设备描述表、服务表和部分VxD全局数据。该段用宏VxD_DATA_SEG和
VxD_DATA_ENDS定义开始和结束,也可命名为_LDATA。
3)、VxD_ICODE段:保护模式初始化代码段(可选)。
该段一般包括只在VxD初始化过程中使用的过程和服务,VMM在Init_Complete
消息发生后丢弃此段。该段用宏VxD_ICODE_SEG和VxD_ICODE_ENDS定义开始和
结束,也可命名为_ITEXT。
4)、VxD_IDATA段:保护模式初始化数据段(可选)。
该段一般包括初始化过程和服务使用的数据,VMM在Init_Complete消息发生后丢弃
此段。该段用宏VxD_IDATA_SEG和VxD_IDATA_ENDS定义开始和结束,也可命名为IDATA。
5)、VxD_REAL_INIT段:实模式初始化段(可选)。
该段包含实模式初始化过程和数据,VMM在装载VxD其它部分之前调用此过程,过程
返回后丢弃此段,该段用宏VxD_REAL_INIT_SEG和VxD_REAL_INIT_ENDS定义开始和
结束,也可命名为_RTEXT。
除实模式初始化段以外,所有代码和数据段均为32位平坦内存模式的保护模式段,这就
是说定义在保护模式段中的过程和数据均为32位的偏移量。当VMM装载VxD时,按照VxD在
内存中的实际位置修正所有的偏移量。因此,在保护模式段中使用普通OFFSET命令
伪操作,下同——译者注)处应该使用OFFSET32宏,OFFSET32宏定义的偏移量为连接器
确定了正确的偏移量修正信息。VxD不能改变CS、DS、ES和SS段寄存器,VxD能够使用FS
和GS段寄存器。
2、保护模式指令
VxD的源程序文件必须以.386p命令开始,以通知汇编器允许保护模式指令。虽然VxD工作
在0特权级,但也不应该用保护模式指令去修改CPU的运行,例如修改全局描述符(选择子
——译者注)或中断描述符以及修改任务状态段或寄存器,这样做可能会对Windows运行
有不利影响。唯一的例外情况是当该VxD为虚拟数学协处理器设备驱动程序(VMCPD),
允许修改CR0寄存器中的80387位。
3、包含(Include)文件
包含文件定义了VxD需要的宏、结构、符号和服务表,用于声明段和过程以及使用VMM和
其它VxD服务。下面是每个包含文件包含的公共服务定义、宏和符号定义列表:
1)、VMM.INC:包含所有的VMM服务以及所需的宏和符号,例如Declare_Virtual_Device
和VMMCall。
2)、DEBUG.INC:包含在调试终端上输出信息和执行各种数据检查的宏。这些宏的功能
由定义了调试符号的VxD在汇编时该文件生成的代码实现。
3)、VPICD.INC:包含为虚拟可编程中断控制器设备(VPICD)定义的所有服务、宏和符号。VPICD处理所有的中断,所以许多VxD需要VPICD服务。
4)、SHELL.INC:包含虚拟外壳设备提供的公共服务的定义。虚拟外壳设备提供对例如
MessageBox这样的Windows函数的调用,可以让VxD显示对话框。
4、VxD声明
每一个VxD都要声明一个名称、一个版本号、一个初始化顺序和一个设备控制过程,
许多虚拟设备驱动程序还声明一个设备标识和一些API过程。VxD一般使用
Declare_Virtual_Device宏来实现这些声明,例如:
Declare_Virtual_Device VSAMPLED, 4, 0, VSAMPLED_Control, \
VSAMPLED_Device_ID, VSAMPLED_Init_Order, \
VSAMPLED_V86_API_Handler, \
VSAMPLED_PM_API_Handler
本例声明了一个VxD实例——VSAMPLED V4.0,在对应的源文件必须定义名字为
VSAMPLED_Control的设备控制过程。符号VSAMPLED_Device_ID和VSAMPLED_Init_Order
说明非标准VxD的标识和初始化顺序,该VxD支持V86模式和保护模式API过程。
VMM用宏定义的信息来初始化VxD并发送系统控制消息给VxD,并且允许MS-DOS应用程序、
设备驱动程序和TSR调用VxD。为了使VMM存取这些信息,相应的宏建立一个设备描述
块(DDB)并将其保存在保护模式数据段中(DDB的格式与VxD_Desc_Block结构相同),
宏为DDB建立了一个必须在VxD连接时被显式引出的标号。在上例中,DDB的名称是
VSAMPLED_DDB。
5、VxD标识(ID)
一个VxD提供一个VxD标识,以区别于其它VxD。VMM动态连接例程使用VxD标识为合适的
VxD连接服务调用,如果VxD提供服务或者提供V86模式和保护模式API过程以及其它需
要唯一标识的情况,VxD就必须有唯一标识。虽然标准VxD使用预定义VxD标识(符号定
义在VMM.INC文件中),支持新设备和新软件接口的VxD还是必须全部有新标识。为了防
止与其他新VxD冲突,Microsoft通过请求和注册标识来保证没有其它厂商使用自己的VxD
的标识,Microsoft保留0—01FFH之间的所有VxD标识自己使用。不提供服务或者API过程,
或者不需要唯一标识的VxD应该使用Undefined_Device_ID符号来定义VxD标识。
6、初始化顺序
每一个VxD都有一个用于指定VMM应该何时初始化该VxD的初始化顺序值,VMM按照该值从小
到大的顺序初始化虚拟机(VM——译者注)。如果两个或者两个以上的VxD有相同的值,
VMM会按照SYSTEM.INI文件中出现的顺序来初始化,但指定顺序是没有保证的。
对于需要调用其它VxD服务或者需要在其它VxD之前拦截中断的VxD,初始化顺序是很重要
的。如果一个VxD需要在标准VxD之前或者之后初始化,它的初始化顺序值应该通过在标
准VxD预定义的初始化顺序符号(在VMM.INC文件中定义)上加上或者减去一个小数值来
创建。如果一个VxD不需要初始化顺序值,应该使用Undefined_Init_Order符号代替初始
化顺序值。
7、设备控制过程
每一个VxD都有一个设备控制过程,VMM通过调用此过程给VxD发送VxD系统控制消息。
系统控制消息指导VxD完成动作,例如自身初始化或者通知VxD虚拟机的变化(例如创建
虚拟机)等。大多数VxD通过使用Begin_Control_Dispatch、Control_Dispatch和
End_Control_Dispatch宏来定义设备控制过程,例如:
Begin_Control_Dispatch VSAMPLED
Control_Dispatch Sys_Critical_Init, VSAMPLED_Crit_Init
Control_Dispatch Device_Init, VSAMPLED_Device_Init
Control_Dispatch Sys_Critical_Exit, VSAMPLED_Crit_Exit
End_Control_Dispatch VSAMPLED
上例中,宏创建了一个名字为VSAMPLED_Control的设备控制过程,并生成了检查
Sys_Critical_Init、Device_Init和Sys_Critical_Exit消息的指令。当这些消息发送到
该过程时,该过程通过控制相应的过程(例如VSAMPLED_Crit_Init)来处理消息,这些
消息处理过程必须在VxD中定义。
--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: deu.hit.edu.cn]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:10.394毫秒