Programming 版 (精华区)

发信人: Sun (大灯泡), 信区: Programming
标  题: VxD世界——VxD的设备描述块与VxD API 
发信站: 哈工大紫丁香 (Sat Sep  4 17:03:05 1999), 转信

   
  孙喜明 


VxD设备描述块


用汇编语言描述MYFIRST.VxD的设备描述块(DDB Device Descriptor Block)如下(
其实,如果是用DDK来开发VxD,那我们在每个VxD的源程序中都会见到这些代码
,只是VToolsD替我们封装了这些费解的东西):

Declare—Virtual—Device MYFIRST,1,0,MYFIRST—Control,MYFIRST—
Device—ID,MYFIRST—Init—Order,MYFIRST—V86—API—Handler,
MYFIRST—PM—API—Handler

对于DDB的8个入口来说,只有前面4个是必须的,后面4个的缺省值为0,如果我们
的MYFIRST.VxD不输出V86 API,那么上面的代码应这样写:

Declare—Virtual—Device MYFIRST,1,0,MYFIRST—Control,MYFIRST—
Device—ID,MYFIRST—Init—Order,,MYFIRST—PM—API—Handler

一般来说,MYFIRST—Init—Order是可以设为缺省值0的,因为我们一般不需要特
殊的初始化顺序。

你一定会奇怪MYFIRST—Control是怎么回事。读一下下面的代码,大概就明白了。

BeginProc MYFIRST—Control

Begin—Control—Dispatch MYFIRST—Control

Control—Dispatch Sys—Dynamic—Device—Init, OnSysDynamicDeviceInit

Control—Dispatch Sys—Dynamic—Device—Exit, OnSysDynamicDeviceExit

.........

End—Control—Dispatch MYFIRST—Control

EndProc MYFIRST—Control

对比一下VToolsD为我们生成的C程序:

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);

END—CONTROL—DISPATCH

return TRUE;}

Windows是基于消息机制的操作系统,这一点在VxD中也体现了出来。MYFIRST—
Control就是接收Windows消息的入口点。Windows发给MYFIRST—Control的消息
与发给Windows应用程序的消息不完全一样,前者包含了一些系统信息。MYFIRST
—Control在收到消息后,调用相应的控制过程。


VxD API


在前面的文章中,我们说MYFIRST.VxD将支持Real/V86 Mode API及Protected 
Mode API,这使得MYFIRST.VxD可以与V86应用程序或Win16应用程序通信。
MYFIRST.VxD输出的V86 API和PM API就是

VOID —cdecl V86—Api—Handler(VMHANDLE hVM, PCLIENT—STRUCT pcrs);

VOID —cdecl PM—Api—Handler(VMHANDLE hVM, PCLIENT—STRUCT pcrs);

一个问题很快就摆在我们面前:如何在我们的应用程序中调用到这两个API?

读一下这段代码:

DWORD NEAR PASCAL GetAPIEntry(WORD VxD—ID)

{DWORD Entry—Point;

—asm{

mov AX, 1684h

mov BX, WORD PTR SS: [VxD—ID]

sub DI, DI

mov ES, DI

int 2Fh

mov WORD PTR SS: [Entry—Point][0], DI

mov WORD PTR SS: [Entry—Point][2], ES

} return Entry—Point;}

这段代码可以用在MS_DOS应用程序或是Win16应用程序中,函数GetAPIEntry将分
别返回V86—Api—Handler的地址或PM—Api—Handler的地址。

等一下,函数GetAPIEntry的入口参数VxD—ID是怎么回事?嗯,问得好。如果你一
直在读我的文章,那你会发现我们在前面有一个失误:在用QuickVxD生成
MYFIRST.VxD的源程序时,把MYFIRST.VxD的DeviceID置成了UNDEFINED—
DEVICE—ID。通过在VToolsD\include\Vmm.h中查找,可以看到:

#define UNDEFINED—DEVICE—ID 0x00000

也就是说所有UNDEFINED—DEVICE—ID的VxD的DeviceID都置成了0。如果我们
向函数GetAPIEntry传递MYFIRST—DeviceID,那我们很可能无法获得
MYFIRST.VxD中的API的地址,因为我们的DeviceID不是惟一的,Windows无法在
众多DeviceID为0的VxD中找到我们的MYFIRST.VxD。那怎么办呢?

解决方案有两个:

方案一:

再用QuickVxD重新生成MYFIRST.VxD的源程序。记着在Device Parameters页中填
写Device ID为某个值,这个值尽量大一些,因为比较小的DeviceID都让Microsoft或
是别的硬件开发商注册了(注册是需要银子的),为了保证不与系统中现存的VxD
的DeviceID发生冲突,我们只好把DeviceID设得大一些,比如说0xAAAA。

方案二:

编辑一下MYFIRST.H,把MYFIRST—DeviceID改了,改过之后的MYFIRST.h如下


#include 〈vtoolsc.h〉

#define MYFIRST—Major 1

#define MYFIRST—Minor 0

#define MYFIRST—DeviceID 0xAAAA

#define MYFIRST—Init—Order UNDEFINED—INIT—ORDER

好了,我们已经准备好与我们的MYFIRST.VxD通信了。
     
     
--
〖小糊涂虫2000灌水机〗

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: sun@hope.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.940毫秒