Préface
Utilisez Delphi 3.0 pour écrire un pilote de périphérique VxD. Il se compile et passe sous Delphi 3. Il n'y a pas de test sous Delphi 2. Le fichier objet M$ Linker 5.12.8181 créé par Delphi 4 n'est pas reconnu. L'assembleur utilisé ici est M$. de Macro Assembler ver. 6.11d, l'éditeur de liens est M$ Incremental Linker ver. , ils proviennent de Windows 98DDK (http://www.microsoft.com/ddk/ddk98.htm).
introduire
Il existe deux types de pilotes de périphérique VxD pour Windows :
1. VxD statique, chargé dans le système d'exploitation et existant en permanence dans la mémoire ;
2. Dynamic VxD, qui est chargé dans la mémoire en cas de besoin, fermez le VxD pour libérer la mémoire.
InPRise Delphi a la capacité de créer tout type de pilote de périphérique VxD. Ci-dessous, nous présenterons comment créer un VxD dynamique.
Lorsqu'une application Win32 ouvre un périphérique « virtuel » VxD, VWIN32 utilise LoadDevice pour charger le VxD en mémoire et crée un message W32_DEVICEIOCONTROL et l'envoie au VxD.
En d'autres termes, VxD doit au moins répondre aux deux messages système suivants et écrire l'une des fonctions suivantes :
SYS_DYNAMIC_DEVICE_INIT
SYS_DYNAMIC_DEVICE_EXIT
Fonction W32_DEVICEIOCONTROL.
Le message SYS_DYNAMIC_DEVICE_INIT est envoyé à VxD lors de la tentative de chargement de VxD, et le message SYS_DYNAMIC_DEVICE_EXIT est envoyé à VxD lors de la tentative d'échange dynamique. Le gestionnaire du message doit renvoyer l'indicateur VXD_SUCCESS dans le registre AX après un traitement réussi.
Le paramètre dwService de W32_DEVICEIOCONTROL a les valeurs suivantes :
DIOC_OPEN est envoyé lorsque VxD tente une opération d'ouverture via la fonction CreateFile() (après le message SYS_DYNAMIC_DEVICE_INIT) et renvoie NO_ERROR (0) en cas de succès ;
DIOC_CLOSEHANDLE Envoyé lorsque VxD tente une opération de fermeture via la fonction CloseHandle() (avant SYS_DYNAMIC_DEVICE_EXIT)
Toutes les autres valeurs > 0 signifient un appel de fonction différent (donné par dwIoControlCode) lorsque le VxD est appelé par la fonction DeviceIoControl.
Module de démarrage (vxdmain.asm)
...
externe SysDynamicDeviceInit:PROC
ext SysDynamicDeviceExit: PROC
Externe W32DeviceIoControl: PROC
...
PUBLIC DELPHIIO_DDB
Public @@HandleFinally
@initialisation publique
...
Processus Control_0
cmp eax, SYS_DYNAMIC_DEVICE_INIT
jnz court chkSysDynExit
appeler SysDynamicDeviceInit
cmp eax, 1
revenant
;-------------
chkSysDynExit :
cmp eax, SYS_DYNAMIC_DEVICE_EXIT
jnz court chkDevIOCtl
appeler SysDynamicDeviceExit
cmp eax, 1
revenant
;-------------
chkDevIOCtl :
cmp eax, W32_DEVICEIOCONTROL
jnz court loc_ret
pousser esi
pousser edx
pushebx
pushecx
appeler W32DeviceIoControl
cmp eax, 1
revenant
;-------------
loc_ret :
clc
revenant
Point final Control_0
@@HandleFinally :
@initialisation :
retraité
_LTEXT se termine
FIN
Delphi appellera les procédures externes HandleFinaly et initialisation pour l'initialisation/finalisation de l'unité, même si l'initialisation/finalisation n'existe pas dans l'unité. Par conséquent, nous créons une entrée de procédure externe vide dans le fichier de démarrage de l’assembly.
Unité principale du programme Delphi (vxdProcs.pas)
...
procédure ShellMessage(Handle, Flags : entier; const Message, Caption : PChar;
Rappel, ReferenceData : pointeur); stdcall;
asme
mov ebx, Handle // handle de machine virtuelle
mov eax, Flags // drapeaux de boîte de message
mov ecx, Message // adresse du texte du message
mov edi, Légende // adresse du texte de la légende
mov esi, Callback // adresse de rappel
mov edx, ReferenceData // données de référence pour le rappel
int 20H // VxDCall
jj 170004h // Shell_Message
fin;
fonction SysDynamicDeviceInit : ENTIER ;
commencer
ShellMessage(0, 10 $, Copyright, 'SysDynInit : Bonjour de Delphi VxD !!!', nul, nul);
Résultat := VXD_SUCCESS;
fin;
fonction SysDynamicDeviceExit : ENTIER ;
commencer
ShellMessage(0, 10 $, Copyright, 'SysDynDevExit : Au revoir de Delphi VxD !!!', nul, nul);
Résultat := VXD_SUCCESS;
fin;
fonction W32DeviceIoControl(dwService : INTEGER;
dwDDB : ENTIER ;
hPériphérique : ENTIER ;
lpDIOCParms : pointeur) : INTEGER;
commencer
ShellMessage (0, 10 $, Copyright, 'W32DevIOCtl', nul, nul);
si (dwService = DIOC_OPEN) alors
commencer
Résultat := NO_ERROR;
fin
sinon si (dwService = DIOC_CLOSEHANDLE) alors
commencer
Résultat := VXD_SUCCESS;
fin
sinon si (dwService > MAX_PASVXD_W32_API) alors
commencer
Résultat := ERROR_NOT_SUPPORTED ;
fin
autre
commencer
Résultat := VXD_SUCCESS;
fin;
fin;
...
[Traducteur : Ok, le simple pilote de périphérique VxD a été écrit. Vous pouvez l'utiliser comme modèle pour écrire des pilotes de périphériques VxD. ]
Annexe 1 : Make.bat
D:VISUAL~198DDKBINWin98ml -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 vxdmain.asm
appelez dcc3.bat -J vxdprocs.pas
D:VISUAL~198DDKBINlink /DEF:vxddef.def /VXD vxdmain.obj vxdprocs /OUT:delphiio.vxd
Annexe 2 :
Écrivons maintenant un programme de test pour le VxD, avec deux boutons : un pour ouvrir le VxD et un pour fermer le VxD ;
const
VxDName = '/.DELPHIIO.VXD';
...
fonction TVxDTestForm.OpenVxDDriver : booléen ;
commencer
HVxDHandle := CreateFile(VxDName,0,0,nil,0,FILE_FLAG_DELETE_ON_CLOSE,0);
Résultat := HVxDHandle <> INVALID_HANDLE_VALUE;
fin;
procédure TVxDTestForm.CloseVxDDriver ;
commencer
si HVxDHandle <> INVALID_HANDLE_VALUE alors commencez
CloseHandle(HVxDHandle);
HVxDHandle := INVALID_HANDLE_VALUE ;
fin;
fin