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毫秒