HITEA 版 (精华区)
发信人: hfl (凤凰·风中轻舞), 信区: HITEA
标 题: VxD世界——VxD的结构
发信站: 哈工大紫丁香 (2002年04月02日20:50:23 星期二), 站内信件
在上一次“走进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中进行消息映射了。
--
>(')____, >(')____, >(')____, >(')____, 这是凤凰嬉水
(` =~~/ (` =~~/ (` =~~/ (` =~~/ 哈哈哈
~^~^`---'~^~^~^`---'~^~^~^`---'~^~^~^`---'~^~^~
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.229.253]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.303毫秒