..... VxD1 ===> VxD2 ===> VxD3 .....Maintenant pendant le déchargement, il est raisonnable que ce soient les VxDs qui ont été initialisés les plus tard qui doivent être détruit les premiers. Ainsi les VxDs les derniers initialisés ont toujours la possibilité d'appeler les services des premiers VxDs, ce qui n'aurait pas été vrai si ont avait fait l'inverse. Donc dans l'exemple ci-dessus, l'ordre de déchargement doit être :
.... VxD3 ===> VxD2 ===> VxD1.....Dans le susdit exemple, si VxD2 a appelé certains des services de VxD1 pendant l'initialisation, il peut de nouveau avoir besoin de compter sur les services de VxD1 pendant le déchargement. System_Exit2 et Sys_Critical_Exit2 sont envoyé dans l'ordre inverse d'initialisation . Ça signifie que, lorsque VxD2 reçoit ces messages, VxD1 n'a pas encore été désinitialiser et on peut toujours appeler les services de VxD1. Les messages System_Exit et Sys_Critical_Exit ne sont pas envoyés dans l'ordre inverse de l'initialisation. Ça signifie que lorsque vous traitez ces deux messages, vous ne pouvez pas être sûrs que vous pouvez encore appeler les services des VxDs qui ont été chargés avant ça. Ces messages ne doivent pas être employés pour les VxDs les plus nouveau.
VXD FIRSTVXD DYNAMICC'est tout que ce vous devez faire pour convertir un VxD statique en un VxD dynamique.
Par exemple, si vous voulez charger le VxD dynamique nommé FirstVxD qui est dans la liste d'adresses actuelle, vous devez le faire comme suit :
.data
VxDName
db "\\.\FirstVxD.VXD",0
......
.data?
hDevice
dd ?
.....
.code
.....
invoke
CreateFile, addr VxDName,0,0,0,0, FILE_FLAG_DELETE_ON_CLOSE,0
mov
hDevice,eax
......
invoke
CloseHandle,hDevice
......
VxD_PAGEABLE_CODE_SEGVous pouvez placer plusieurs procédures à l'intérieur d'un segment. Vous comme êtes l'auteur du VxD, c'est à vous de décider dans quel segment vous devez mettre vos procédures. Si vos procédures doivent être présent en mémoire tout le temps comme les manipulateurs d'interruption matériel (hardware interrupt handlers), il faut les mettre dans un segment fermé (Page-locked contraire de Pageable). Autrement vous devez les mettre dans le segment pageable.[VOTRE PROÉCDURE ICI]
VxD_PAGEABLE_CODE_ENDS
BeginProc namename est le nom de la procédure. La macro BeginProc peut prendre encore plusieurs paramètres, vous devez consulter la documentation Win95 DDK pour plus de détails. Mais la plupart du temps, vous pouvez vous contenter du nom de la procédure.EndProc name
VMMCall service ; Pour appeler des services basés sur les regitresVMMCall et VxDCall sont en réalité la composition d'une int 20h suivie d'un dword que j'ai décrit dans le tutorial précédent mais ils sont beaucoup plus commodes à employer. Dans le cas de services basés sur pile, vous devez inclure la liste d'argument avec une paire de parenthèse angulaire [].
VMMCall _service, <argument list> ; Pour appeler les services basés sur la pile
VMMCall _HeapAllocate, <<size mybuffer>, HeapLockedIfDP>_HeapAllocate est un service basé sur la pile. Il accepte deux paramètres. Nous devons les inclure à l'intérieur d'une parenthèse angulaire. Cependant, le premier paramètre est une expression que la macro peut mal interpréter, donc nous le mettons à l'intérieur d'une autre parenthèse angulaire.
Note: j'ai expérimenté la compensation Offset32 quand j'ai écris ce Tutorial. Ça a produit des adresses correctes donc je pense que le bogue a été enlevé dans MASM 6.14. Mais pour que ça reste correcte, vous devez employer la macro OFFSET32 au lieu de l'habituel offset.