明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線(xiàn)學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

用Delphi編寫(xiě)VxD設(shè)備驅(qū)動(dòng)程序

[摘要]前言  用 delphi 3.0 編寫(xiě) vxd 設(shè)備驅(qū)動(dòng)程序,在delphi 3 下編譯通過(guò),delphi 2 下沒(méi)有測(cè)試,delphi 4 建立的 object 文件 m linker 5.12.8181 不能識(shí)別,這里使用的匯編器是m的macro assembler ver. 6.11d ,...
前言  
 用 delphi 3.0 編寫(xiě) vxd 設(shè)備驅(qū)動(dòng)程序,在delphi 3 下編譯通過(guò),delphi 2 下沒(méi)有測(cè)試,delphi 4 建立的 object 文件 m$ linker 5.12.8181 不能識(shí)別,這里使用的匯編器是m$的macro assembler ver. 6.11d ,聯(lián)結(jié)器是m$ incremental linker ver. 5.12.8181 ,它們來(lái)自 windows 98ddk(http://www.microsoft.com/ddk/ddk98.htm)。  

介紹  
 windows 存在有兩種類(lèi)型的 vxd 設(shè)備驅(qū)動(dòng)程序:  
  1、靜態(tài)(static) vxd ,裝入操作系統(tǒng)并永久的存在于內(nèi)存中;  
  2、動(dòng)態(tài)(dynamic) vxd,當(dāng)需要時(shí)才調(diào)入內(nèi)存,用完后關(guān)閉vxd即可釋放內(nèi)存。  
 inprise delphi 有能力建立任何一種類(lèi)型的 vxd 設(shè)備驅(qū)動(dòng)程序,下面我們將介紹如何建立動(dòng)態(tài) vxd。  
 當(dāng) win32 應(yīng)用程序打開(kāi)一個(gè) vxd “虛擬”設(shè)備時(shí),vwin32 使用 loaddevice 將 vxd 裝入內(nèi)存,并建立消息w32_deviceiocontrol ,發(fā)向 vxd。  
 也就是說(shuō),vxd 至少應(yīng)該響應(yīng)以下兩個(gè)系統(tǒng)信息和編寫(xiě)以下的一個(gè)函數(shù):  
  sys_dynamic_device_init  
  sys_dynamic_device_exit  
  w32_deviceiocontrol 函數(shù).  
 消息 sys_dynamic_device_init 在嘗試裝入 vxd 時(shí)發(fā)送到 vxd ,消息 sys_dynamic_device_exit 在嘗試動(dòng)態(tài)交換時(shí)發(fā)送到 vxd ,消息的處理者在成功處理后,應(yīng)該在寄存器 ax 中返回 vxd_success 標(biāo)志。  

 w32_deviceiocontrol 的 dwservice 參數(shù)有以下的值:  
  dioc_open 當(dāng) vxd 通過(guò) createfile() 函數(shù)嘗試打開(kāi)操作時(shí)發(fā)送(在 sys_dynamic_device_init 消息后),如果成功返回 no_error (0); 
  dioc_closehandle 當(dāng) vxd 通過(guò) closehandle() 函數(shù)嘗試關(guān)閉操作時(shí)發(fā)送(在 sys_dynamic_device_exit 前)  
  所有其它的值 > 0 意味著不同的函數(shù)調(diào)用(由 dwiocontrolcode 給出),當(dāng) vxd 被 deviceiocontrol 函數(shù)調(diào)用時(shí)。  

啟動(dòng)模塊(vxdmain.asm)  
...  
extrn sysdynamicdeviceinit :proc  
extrn sysdynamicdeviceexit :proc  
extrn w32deviceiocontrol  :proc  
...  
            public delphiio_ddb  
      public @@handlefinally  
      public @initialization  
...  
control_0  proc  
  cmp  eax, sys_dynamic_device_init  
  jnz  short chksysdynexit  
  call  sysdynamicdeviceinit  
  cmp  eax, 1  
  retn    
;-------------  

chksysdynexit:  
  cmp  eax, sys_dynamic_device_exit  
  jnz  short chkdevioctl  
  call  sysdynamicdeviceexit  
  cmp  eax, 1  
  retn    
;-------------  
chkdevioctl:  
  cmp  eax, w32_deviceiocontrol  
  jnz  short loc_ret  
  push  esi  
  push  edx  
  push  ebx  
  push  ecx  
  call  w32deviceiocontrol  
  cmp  eax, 1  
  retn    
;-------------  
loc_ret:  
  clc    
  retn    

control_0  endp  

@@handlefinally:  
@initialization:  
      ret  

_ltext  ends  
            end  

 delphi 會(huì)為單元的 initialization/finalization 建立代碼調(diào)用外部過(guò)程 handlefinaly 和 initialization ,即使 initialization/finalization 在單元中不存在。因此我們?cè)趨R編的啟動(dòng)文件中建立空的外部過(guò)程入口。  

主 delphi 程序單元(vxdprocs.pas) 
...  
procedure shellmessage(handle, flags : integer; const message, caption : pchar; 
  callback, referencedata : pointer); stdcall; assembler;  
asm  
 mov  ebx, handle    // virtual machine handle  
 mov  eax, flags    // message box flags  
 mov  ecx, message    // address of message text  
 mov  edi, caption    // address of caption text  
 mov  esi, callback    // address of callback  
 mov  edx, referencedata    // reference data for callback  

 int  20h      // vxdcall  
 dd   170004h      // shell_message  
end;  

function sysdynamicdeviceinit : integer;  
begin  
 shellmessage(0, $10, copyright, ’sysdyninit: hello from delphi vxd !!!’, nil, nil);  
 result := vxd_success;  
end;  

function sysdynamicdeviceexit : integer;  
begin  
 shellmessage(0, $10, copyright, ’sysdyndevexit: bye from delphi vxd !!!’, nil, nil);  
 result := vxd_success;  
end;  

function w32deviceiocontrol(dwservice : integer;  
              dwddb : integer;  
              hdevice : integer;  
              lpdiocparms : pointer) : integer;  
begin  
 shellmessage(0, $10, copyright, ’w32devioctl’, nil, nil);  

 if (dwservice = dioc_open) then  
 begin  
   result := no_error;  
 end  
 else if (dwservice = dioc_closehandle) then  
 begin  
   result := vxd_success;  
 end  
 else if (dwservice > max_pasvxd_w32_api) then  
 begin  
   result := error_not_supported;  
 end  
  else  
 begin  
   result := vxd_success; 
 end;  
end;  
...  


[譯者:好了,簡(jiǎn)單的 vxd 設(shè)備驅(qū)動(dòng)程序編寫(xiě)完畢了。你可以將它當(dāng)作一個(gè)寫(xiě) vxd 設(shè)備驅(qū)動(dòng)程序的模板。]  

附一:make.bat  
d:\visual~1\98ddk\bin\win98\ml -coff -dbld_coff -dis_32 -w2 -c -cx -zm -dmasm6 vxdmain.asm  
call dcc3.bat -j vxdprocs.pas  
d:\visual~1\98ddk\bin\link /def:vxddef.def /vxd vxdmain.obj vxdprocs /out:delphiio.vxd  

附二:  
現(xiàn)在讓我們來(lái)編寫(xiě)對(duì)該 vxd 的測(cè)試程序,兩個(gè)按鈕:一個(gè)打開(kāi) vxd;一個(gè)關(guān)閉 vxd。  

const  
vxdname = ’\\.\delphiio.vxd’;  

...  

function tvxdtestform.openvxddriver: boolean;  
begin  
hvxdhandle := createfile(vxdname,0,0,nil,0,file_flag_delete_on_close,0);  
result := hvxdhandle <> invalid_handle_value;  
end;  

procedure tvxdtestform.closevxddriver;  
begin  
if hvxdhandle <> invalid_handle_value then begin  
  closehandle(hvxdhandle);  
  hvxdhandle := invalid_handle_value;  
end;  
end  



順便說(shuō)一下,delphi中有個(gè)編譯選項(xiàng)可以控制程序加載的入口

一般是0x00400000,你可以改.