Write VxD device driver (turn) Keywords with Delphi: Delphi Miscellaneous of the control: Emil Biserov (dinfo@mail.primorye.ru) (Russion) English translation: Vitaly Zayko (zayko@vitsoftware.com) Chinese translation adaptation: Riceball ( Teditor@mailroom.com) Preface to write VXD device drivers in Delphi 3.0, compile by Delphi 3, Delphi 2 is not tested, Delphi 4 established Object file M $ Linker 5.12.8181 cannot be identified, the assembler used here is M $ Macro Assembler Ver. 6.11d, the coupler is M $ Incremental Linker Ver. 5.12.8181, they come from Windows 98DDK (http://www.microsoft.com/ddk/ddk98.htm). Introduction Windows has two types of VXD device drivers: 1, static VXD, load the operating system and permanently exist in memory; 2, dynamic vxd, when needed, transfer to memory, use After closing the VXD, you can release the memory. Inprise Delphi has the ability to build any type of VXD device driver. Here we will show how to establish dynamic VXD. When the Win32 application opens a VXD "virtual" device, VWIN32 loads VXD into memory with loadDevice, and establishes a message W32_DeviceioControl, and send VXD. That is, in response VxD should at least two of the following system information and a function to write the following:. SYS_DYNAMIC_DEVICE_INIT SYS_DYNAMIC_DEVICE_EXIT W32_DEVICEIOCONTROL SYS_DYNAMIC_DEVICE_INIT message transmission function when trying to mount the VxD VxD, the message sent to the VxD SYS_DYNAMIC_DEVICE_EXIT when attempting dynamic exchange of messages After the handle is successfully processed, the VXD_SUCCESS flag should be returned in the register AX. The DWService parameter of W32_Deviceiocontrol has the following values: DIOC_OPEN When VXD is sent (after the Sys_Dynamic_Device_init message attempts to open the operation, if the sys_dynamic_Device_init message is successfully returned to NO_ERROR (0); dioc_closehandle When VXD is sent via a closehandle () function attempts to shut down the operation (Before Sys_Dynamic_Device_exit) All other values> 0 means different function calls (given by dwiocontrolcode), when VXD is called by DeviceIocontrol function.
Start (vxdmain.asm) module ... 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 Chkdeviock 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 will call the external process HandleFinal and Initialization, even if INITIALALIZATION / Finalization does not exist in the unit. Therefore, we build an empty external process entrance in the assembled launch file.
Delphi main program unit (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: POIN ter): 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; Else Begin Result: = VXD_SUCCESS; End; End; ... [Translator: Ok, Simple VXD device driver has completed. You can treat it as a template for writing a VXD device driver.
Annea: 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 Addition: Let us write a test program for the VXD, two buttons: one open Vxd; one close 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 Incidentally, Delphi there is a compiler option to load the control program entry
Generally 0x00400000, you can change.