⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 0516006.htm

📁 VC知识库5_chm_decompile_20040520_210715
💻 HTM
字号:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title></title>
<link rel="stylesheet" type="text/css" href="../../vckbase.css">
</head>

<body>

<div align="justify">
  <table border="0" width="100%" class="font" height="57">
    <tr>
      <td width="27%" height="6" class="bigfont" bgcolor="#B8CFE7" align="center" bordercolor="#800080">
      <font color="#800080">VC知识库(五)</font>
      </td>
      <td width="73%" height="6" class="bigfont" bgcolor="#B8CFE7" align="center" bordercolor="#800080">
      <font color="#800080">www.vckbase.com</font>
      </td>
    </tr>
    <tr>
      <td width="100%" height="4" class="header" valign="top" align="center" colspan="2">
      <hr>
      </td>
    </tr>
    <tr>
      <td width="100%" height="17" class="header" valign="top" align="center" colspan="2">
  <font class="12v">VxD的设备描述块与VxD API</font> 
      </td> 
    </tr> 
    <tr> 
      <td width="100%" height="17" class="info" align="center" colspan="2"> 
      <font class="12v">孙喜明</font> 
      </td>   
    </tr>   
    <tr>  
      <td width="100%" height="22" class="font" colspan="2"> 
        <hr> 
      </td>   
    </tr>  
    <tr>  
      <td width="100%" height="5" class="font" colspan="2">  
  <p><br> 
  VxD设备描述块<br> 
  <br> 
  <br> 
    用汇编语言描述MYFIRST.VxD的设备描述块(DDB Device Descriptor Block)如下(其实,如果是用DDK来开发VxD,那我们在每个VxD的源程序中都会见到这些代码,只是VToolsD替我们封装了这些费解的东西):</p> 
  <p>Declare—Virtual—Device MYFIRST,1,0,MYFIRST—Control,MYFIRST—Device—ID,MYFIRST—Init—Order,MYFIRST—V86—API—Handler,MYFIRST—PM—API—Handler<br> 
  <br> 
    对于DDB的8个入口来说,只有前面4个是必须的,后面4个的缺省值为0,如果我们的MYFIRST.VxD不输出V86  
  API,那么上面的代码应这样写:<br> 
  <br> 
    Declare—Virtual—Device MYFIRST,1,0,MYFIRST—Control,MYFIRST—Device—ID,MYFIRST—Init—Order,,MYFIRST—PM—API—Handler<br> 
  <br> 
    一般来说,MYFIRST—Init—Order是可以设为缺省值0的,因为我们一般不需要特殊的初始化顺序。<br>
  <br>
    你一定会奇怪MYFIRST—Control是怎么回事。读一下下面的代码,大概就明白了。<br>
  <br>
    BeginProc MYFIRST—Control<br> 
  <br> 
    Begin—Control—Dispatch MYFIRST—Control<br> 
  <br> 
    Control—Dispatch Sys—Dynamic—Device—Init, OnSysDynamicDeviceInit<br> 
  <br> 
  Control—Dispatch Sys—Dynamic—Device—Exit, OnSysDynamicDeviceExit<br> 
  <br> 
  .........<br> 
  <br> 
    End—Control—Dispatch MYFIRST—Control<br> 
  <br> 
    EndProc MYFIRST—Control<br> 
  <br> 
    对比一下VToolsD为我们生成的C程序:<br>
  <br>
    BOOL —cdecl ControlDispatcher(<br> 
  <br> 
  DWORD dwControlMessage,<br> 
  <br> 
  DWORD EBX,DWORD EDX,<br> 
  <br> 
  DWORD ESI, DWORD EDI,<br> 
  <br> 
  DWORD ECX)<br> 
  <br> 
    { START—CONTROL—DISPATCH<br> 
  <br> 
  ON—SYS—DYNAMIC—DEVICE—INIT(OnSysDynamicDeviceInit);<br> 
  <br> 
  ON—SYS—DYNAMIC—DEVICE—EXIT(OnSysDynamicDeviceExit);<br> 
  <br> 
  END—CONTROL—DISPATCH<br> 
  <br> 
  return TRUE;}<br> 
  <br> 
    Windows是基于消息机制的操作系统,这一点在VxD中也体现了出来。MYFIRST—Control就是接收Windows消息的入口点。Windows发给MYFIRST—Control的消息与发给Windows应用程序的消息不完全一样,前者包含了一些系统信息。MYFIRST—Control在收到消息后,调用相应的控制过程。<br>
  <br>
  <br>
    VxD API<br> 
  <br> 
  <br> 
    在前面的文章中,我们说MYFIRST.VxD将支持Real/V86 Mode API及Protected  
  Mode API,这使得MYFIRST.VxD可以与V86应用程序或Win16应用程序通信。MYFIRST.VxD输出的V86  
  API和PM API就是<br> 
  <br> 
    VOID —cdecl V86—Api—Handler(VMHANDLE hVM, PCLIENT—STRUCT pcrs);<br> 
  <br> 
    VOID —cdecl PM—Api—Handler(VMHANDLE hVM, PCLIENT—STRUCT pcrs);<br> 
  <br> 
    一个问题很快就摆在我们面前:如何在我们的应用程序中调用到这两个API?<br>
  <br>
    读一下这段代码:<br>
  <br>
    DWORD NEAR PASCAL GetAPIEntry(WORD VxD—ID)<br> 
  <br> 
    {DWORD Entry—Point;<br> 
  <br> 
     —asm{<br> 
  <br> 
  mov AX, 1684h<br> 
  <br> 
  mov BX, WORD PTR SS: [VxD—ID]<br> 
  <br> 
  sub DI, DI<br> 
  <br> 
  mov ES, DI<br> 
  <br> 
  int 2Fh<br> 
  <br> 
  mov WORD PTR SS: [Entry—Point][0], DI<br> 
  <br> 
  mov WORD PTR SS: [Entry—Point][2], ES<br> 
  <br> 
    } return Entry—Point;}<br> 
  <br> 
    这段代码可以用在MS_DOS应用程序或是Win16应用程序中,函数GetAPIEntry将分别返回V86—Api—Handler的地址或PM—Api—Handler的地址。<br>
  <br>
    等一下,函数GetAPIEntry的入口参数VxD—ID是怎么回事?嗯,问得好。如果你一直在读我的文章,那你会发现我们在前面有一个失误:在用QuickVxD生成MYFIRST.VxD的源程序时,把MYFIRST.VxD的DeviceID置成了UNDEFINED—DEVICE—ID。通过在VToolsD\include\Vmm.h中查找,可以看到:<br>
  <br>
    #define UNDEFINED—DEVICE—ID 0x00000<br> 
  <br> 
    也就是说所有UNDEFINED—DEVICE—ID的VxD的DeviceID都置成了0。如果我们向函数GetAPIEntry传递MYFIRST—DeviceID,那我们很可能无法获得MYFIRST.VxD中的API的地址,因为我们的DeviceID不是惟一的,Windows无法在众多DeviceID为0的VxD中找到我们的MYFIRST.VxD。那怎么办呢?<br>
  <br>
    解决方案有两个:<br>
  <br>
    方案一:<br>
  <br>
    再用QuickVxD重新生成MYFIRST.VxD的源程序。记着在Device Parameters页中填写Device  
  ID为某个值,这个值尽量大一些,因为比较小的DeviceID都让Microsoft或是别的硬件开发商注册了(注册是需要银子的),为了保证不与系统中现存的VxD的DeviceID发生冲突,我们只好把DeviceID设得大一些,比如说0xAAAA。<br> 
  <br> 
    方案二:<br>
  <br>
    编辑一下MYFIRST.H,把MYFIRST—DeviceID改了,改过之后的MYFIRST.h如下:<br>
  <br>
    #include 〈vtoolsc.h〉<br> 
  <br> 
    #define MYFIRST—Major 1<br> 
  <br> 
    #define MYFIRST—Minor 0<br> 
  <br> 
    #define MYFIRST—DeviceID 0xAAAA<br> 
  <br> 
    #define MYFIRST—Init—Order UNDEFINED—INIT—ORDER<br> 
  <br> 
    好了,我们已经准备好与我们的MYFIRST.VxD通信了。</p>
      </td>    
    </tr>   
    <tr>
      <td width="100%" height="12" class="font" colspan="2"> 
      </td>    
    </tr>
    <tr>
      <td width="100%" height="6" class="font" colspan="2"> 
      </td>    
    </tr>
    <tr>
      <td width="100%" height="8" class="font" colspan="2"> 
      </td>    
    </tr>
    <tr>   
      <td width="100%" height="17" class="font" colspan="2"></td>    
    </tr>   
  </table>    
</div>    
    
</body>    
    
</html>    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -