HITEA 版 (精华区)

发信人: hfl (凤凰·风中轻舞), 信区: HITEA
标  题: VxD世界__VxD的设备描述块与VxD API
发信站: 哈工大紫丁香 (2002年04月02日20:51:51 星期二), 站内信件


  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通信了。





--
━━━━━━╋╋╋  ╔══════════════╗  ╋╋╋━━━━━━
  ━━━━━╋╋╋═╣ 一个令人心动的微笑         ╠═╋╋╋━━━━━
    ━━━━╋╋╋  ║ 一双永不能忘的明眸         ║  ╋╋╋━━━━
      ━━━╋╋╋  ║               令我珍藏一生 ║  ╋╋╋━━━
        ━━╋╋╋═╣                      hfl   ╠═╋╋╋━━
          ━╋╋╋  ╚══════════════╝  ╋╋╋━ 

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