Programming 版 (精华区)
发信人: Sun (大灯泡), 信区: Programming
标 题: VxD世界——VxD的结构
发信站: 哈工大紫丁香 (Tue Aug 31 12:37:39 1999), 转信
孙喜明
在上一次“走进VxD”世界中,我们用VToolsD生成了一个最简单的可以动态加载的
VxD——MYFIST程序。我们以这个例子为基础,不断地丰富其功能,并以此讲解一
些VxD的基本技术。
下面是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 values.
#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中进行消息映射了。
--
〖小糊涂虫2000灌水机〗
--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: sun@hope.hit.edu.cn]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.130毫秒