Prefacio
Utilice Delphi 3.0 para escribir un controlador de dispositivo VxD. Se compila y pasa en Delphi 3. No hay pruebas en Delphi 2. El archivo de objeto M$ Linker 5.12.8181 creado por Delphi 4 no se puede reconocer. El ensamblador utilizado aquí es M$. 's Macro Assembler ver 6.11d, el vinculador es M$ Incremental Linker ver. , provienen de Windows 98DDK (http://www.microsoft.com/ddk/ddk98.htm).
introducir
Hay dos tipos de controladores de dispositivos VxD para Windows:
1. VxD estático, cargado en el sistema operativo y existente permanentemente en la memoria;
2. Dynamic VxD, que se carga en la memoria cuando es necesario. Después de su uso, cierre el VxD para liberar la memoria.
InPRise Delphi tiene la capacidad de crear cualquier tipo de controlador de dispositivo VxD. A continuación presentaremos cómo crear VxD dinámico.
Cuando una aplicación Win32 abre un dispositivo "virtual" VxD, VWIN32 usa LoadDevice para cargar el VxD en la memoria y crea un mensaje W32_DEVICEIOCONTROL y lo envía al VxD.
En otras palabras, VxD debería al menos responder a los siguientes dos mensajes del sistema y escribir una de las siguientes funciones:
SYS_DYNAMIC_DEVICE_INIT
SYS_DYNAMIC_DEVICE_EXIT
Función W32_DEVICEIOCONTROL.
El mensaje SYS_DYNAMIC_DEVICE_INIT se envía a VxD cuando se intenta cargar VxD, y el mensaje SYS_DYNAMIC_DEVICE_EXIT se envía a VxD cuando se intenta intercambiar dinámicamente. El controlador del mensaje debe devolver el indicador VXD_SUCCESS en el registro AX después del procesamiento exitoso.
El parámetro dwService de W32_DEVICEIOCONTROL tiene los siguientes valores:
DIOC_OPEN se envía cuando VxD intenta una operación de apertura a través de la función CreateFile() (después del mensaje SYS_DYNAMIC_DEVICE_INIT) y devuelve NO_ERROR (0) si tiene éxito;
DIOC_CLOSEHANDLE Enviado cuando VxD intenta una operación de cierre mediante la función CloseHandle() (antes de SYS_DYNAMIC_DEVICE_EXIT)
Todos los demás valores> 0 significan una llamada de función diferente (dada por dwIoControlCode) cuando la función DeviceIoControl llama al VxD.
Iniciar módulo (vxdmain.asm)
...
extrn SysDynamicDeviceInit:PROC
extrn SysDynamicDeviceSalir:PROC
extrn W32DeviceIoControl:PROC
...
PÚBLICO DELPHIIO_DDB
Público @@HandleFinalmente
@inicialización pública
...
Control_0 proceso
cmp eax, SYS_DYNAMIC_DEVICE_INIT
jnz breve chkSysDynSalir
llamar a SysDynamicDeviceInit
cmp eax, 1
regresar
;-------------
chkSysDynSalir:
cmp eax, SYS_DYNAMIC_DEVICE_EXIT
jnz breve chkDevIOCtl
llamar a SysDynamicDeviceExit
cmp eax, 1
regresar
;-------------
chkDevIOCtl:
cmp eax, W32_DEVICEIOCONTROL
jnz corto loc_ret
empujar esi
empujar edx
pushebx
pushecx
llamar a W32DeviceIoControl
cmp eax, 1
regresar
;-------------
loc_ret:
clc
regresar
Control_0 extremo
@@HandleFinalmente:
@inicialización:
retirado
_LTEXT termina
FIN
Delphi llamará a los procedimientos externos HandleFinaly e inicialización para la inicialización/finalización de la unidad, incluso si la inicialización/finalización no existe en la unidad. Por lo tanto, creamos una entrada de procedimiento externo vacía en el archivo de inicio del ensamblado.
Unidad principal del programa Delphi (vxdProcs.pas)
...
procedimiento ShellMessage(Handle, Flags: integer; const Message, Caption: PChar;
Devolución de llamada, Datos de referencia: puntero); llamada estándar;
ENSAMBLE
mov ebx, Mango // identificador de máquina virtual
mov eax, Banderas // banderas del cuadro de mensaje
mov ecx, Mensaje // dirección del texto del mensaje
mov edi, Título // dirección del texto del título
mov esi, devolución de llamada // dirección de devolución de llamada
mov edx, ReferenceData // datos de referencia para devolución de llamada
int 20H // VxDCall
dd 170004h // Shell_Message
fin;
función SysDynamicDeviceInit: INTEGER;
comenzar
ShellMessage(0, $10, Copyright, 'SysDynInit: ¡¡¡Hola desde Delphi VxD !!!', nil, nil);
Resultado := VXD_SUCCESS;
fin;
función SysDynamicDeviceExit: INTEGER;
comenzar
ShellMessage(0, $10, Copyright, 'SysDynDevExit: ¡¡¡Adiós a Delphi VxD !!!', nil, nil);
Resultado := VXD_SUCCESS;
fin;
función W32DeviceIoControl(dwService: INTEGER;
dwDDB: ENTERO;
hDispositivo: ENTERO;
lpDIOCParms: puntero): INTEGER;
comenzar
ShellMessage(0, $10, Copyright, 'W32DevIOCtl', nulo, nulo);
si (dwService = DIOC_OPEN) entonces
comenzar
Resultado := NO_ERROR;
fin
de lo contrario, si (dwService = DIOC_CLOSEHANDLE) entonces
comenzar
Resultado := VXD_SUCCESS;
fin
de lo contrario, si (dwService> MAX_PASVXD_W32_API), entonces
comenzar
Resultado := ERROR_NOT_SUPPORTED;
fin
demás
comenzar
Resultado := VXD_SUCCESS;
fin;
fin;
...
[Traductor: Ok, se ha escrito el controlador de dispositivo VxD simple. Puede usarlo como plantilla para escribir controladores de dispositivos VxD. ]
Apéndice 1: Make.bat
D:VISUAL~198DDKBINWin98ml -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 vxdmain.asm
llamar a dcc3.bat -J vxdprocs.pas
D:VISUAL~198DDKBINlink /DEF:vxddef.def /VXD vxdmain.obj vxdprocs /OUT:delphiio.vxd
Apéndice 2:
Ahora escribamos un programa de prueba para el VxD, con dos botones: uno para abrir el VxD y otro para cerrar el VxD.
constante
VxDName = '/.DELPHIIO.VXD';
...
función TVxDTestForm.OpenVxDDriver: booleano;
comenzar
HVxDHandle := CreateFile(VxDName,0,0,nil,0,FILE_FLAG_DELETE_ON_CLOSE,0);
Resultado := HVxDHandle <> INVALID_HANDLE_VALUE;
fin;
procedimiento TVxDTestForm.CloseVxDDriver;
comenzar
si HVxDHandle <> INVALID_HANDLE_VALUE entonces comienza
CerrarMango(HVxDHandle);
HVxDHandle := INVALID_HANDLE_VALUE;
fin;
fin