VxDCall _SHELL_CallAtAppyTime, <<OFFSET32 pfnCallback>, dwRefData, dwFlags, dwTimeout>
pfnCallBack | Est l'adresse de retour de la fonction Call que vous souhaitez que le VxD Shell appelle lorsqu'un événement de temps appy se produit. La fonction recevra deux paramètres, dwRefData et dwFlags qui sont exactement identiques aux deux paramètres que vous avez passé à la fonction _Shell_CallAtAppyTime. Notez que le VxD Shell appellera votre fonction de retour avec une séquence d'appel C. Bref, vous devez définir votre fonction de retour de service comme ça :
BeginProc
OnAppyTime,
CCALL, PUBLIC
<Mettez votre code ici> LeaveProc
|
dwRefData | Représente les données que vous souhaitez que votre VxD Shell doit repasser après votre fonction de rappel de service (le Call de votre programme qui nous envoie dans le VxD). Ça peut être tout ce que vous voulez. |
dwFlags | Event flags (les différents événements). Ce paramètre peut être une des valeurs qui suivent :
CAAFL_RING0 événement de type Ring-0.Utilisez-le simplement, dans l'attente qu'un événement de temps appy ne se produise pendant une période de temps définie, en utilisant le Flag CAAFL_TIMEOUT. Si vous voulez attendre indéfiniment l'événement de temps appy, remplacez ce Flag par un NULL. Je ne sais pas ce que fait le Flag CAAFL_RING0 en réalité. |
dwTimeout | est la période de temps que le VxD sera susceptible d'attendre qu'un événement de temps appy se produise. Je n'ai pas pu trouver de renseignements à propos de l'unité de temps employée avec cet argument. |
Ce service est asynchrone, ce qui signifie qu'il retourne (revient à la suite du Call) immédiatement après avoir définit le contenu de votre fonction Call qui s'occupe des événement de temps appy.
Si cet appel de service (le retour de ce Call) est couronné de succès, il renvoie dans eax le handle du type d'événement de temps appy. Si c'est un échec, eax contiendra la valeur 0.
Vous pouvez annuler votre définition (registering) de temps appy en appelant la fonction _Shell_CancelAppyTimeEvent laquelle ne prend qu'un unique paramètre, qui est l'Handle de l'événement de temps appy retourné par la fonction _Shell_CallAtAppyTime.
Pour ne pas transgresser les règles, avant l'appel _Shell_CallAtAppyTime, vous devez vérifier le système pour voir si l'événement de temps appy est valide.
Par exemple, que se passe-t-il si vous êtes en train récupérer un événement de temps appy alors que le système chute (déraille)? Le rappel de service de votre VxD ne sera jamais appelé! (Le Call de notre programme et qui visite le VxD échoue) Vous pouvez questionner le système pour voir si l'événement de temps appy est valide et disponible en appelant _Shell_QueryAppyTimeAvailable. Ce service ne prend aucun paramètre. Il retourne 0 dans eax si le temps appy n'est pas disponible, c'est-à-dire si le système s'est définitivement fermé ou que le server de messages ait obtenu des erreurs GP. Ce service ne vous informe pas qu'on est actuellement ou non au temps appy :
il vous dit seulement qu'il peut y avoir des événements de temps appy. Bref, si vous voulez vous en sortir, appelez d'abord _Shell_QueryAppyTimeAvailable et s'il renvoie une valeur non-nulle dans eax, vous pouvez continuer à appeler _Shell_CallAtAppyTime.
VxDCall _SHELL_ShellExecute, <OFFSET32 ShexPacket>Elle ne prend qu'un seulement paramètre, l'adresse (Flat) d'une structure SHEXPACKET. Elle renvoie la valeur de ShellExecute dans eax. On va examiner la structure SHEXPACKET en détail..
shex_dwTotalSize | est la taille en octets de la structure SHEXPACKET (plus le paramètre facultatif, rgchBaggagergchBaggage bientôt. |
shex_dwSize | est la taille en octets de la structure de SHEXPACKET, ne comptant pas le paramètre facultatif rgchBaggage. Combiné avec shex_dwTotalSize ci-dessus, le VxD Shell peut calculer la taille de rgchBaggage qui est d'une longueur arbitraire. |
shex_ibOp | est l'opération qu'on souhaite exécuter. Si vous spécifiez 0, cela signifie que vous voulez ouvrir le fichier. Si c'est un fichier exécutable, il sera lancé. Si vous voulez exécuter d'autres opérations, vous devez spécifier le nom de l'opération quelque part dans rgchBaggage et ce paramètre doit contenir la taille en octets du début de cette structure SHEXPACKET au premier caractère de la chaîne de caractères ASCII qui spécifie le nom de l'opération que vous voulez exécuter. La taille de SHEXPACKET est sur 32 octets. Si la chaîne de caractères représentant l'opération suit immédiatement la structure SHEXPACKET, la valeur dans shex_ibOp DOIT être sur 32. Quant à la liste des opérations vous pouvez exécuter, vérifier ShellExecute. Il y a trois opérations définies, "ouvrir", "imprimer" et "explorer". |
shex_ibFile | est la distance relative du début de cette structure à la chaîne de caractères ASCII qui est le nom du fichier qu'on veut envoyer à ShellExecute, dans shex_ibOp. |
shex_ibParams | sont les paramètres facultatifs que vous voulez passer au fichier indiqué dans shex_ibFile. Si le fichier est un document ou que vous ne voulez lui passer aucun paramètre, employer un 0. Si vous voulez passer de quelconques paramètres au fichier, mettre ces paramètres (sous forme de chaîne de caractères) quelque part après cette structure et mettre la distance relative du début de cette structure à la chaîne de caractères dans ce paramètre. Bref, c'est comme shex_ibOp et shex_ibFile. |
shex_ibDir | est le répertoire de travail. mettez 0 si vous voulez employer le répertoire Windows, sinon vous pouvez mettre votre répertoire préféré du genre 'C:\temps' quelque part après cette structure et mettre la distance relative entre le début de cette structure et la chaîne de caractères de renseignements de ce paramètre. |
shex_dwReserved | comme le nom l'indique, il est réservé. Ne mettez pas de bordel avec ça. |
shex_nCmdShow | Comment on doit afficher la fenêtre de l'application (du programme). C'est une des valeurs que vous passez normalement à ShowWindow, c'est-à-dire. Une des valeur du genre SW_XXXX. Cherchez ces valeurs dans Windows.inc. |
Tous les membres sont des DWORD. Maintenant qu'est-ce que ce membre rgchBaggage que j'avais promis de décrire ? Il est un peu difficile à expliquer. rgchBaggage est un membre de structure SHEXPACKET mais il ne peut pas être inclus dans la définition de structure même parce que sa taille est arbitraire. Vérifiez Shell.inc, vous verrez que rgchBaggage n'est pas définie dans SHEXPACKET. Cependant la documentation Windows 9x DDK affirme que c'est un membre de SHEXPACKET.
Mais qu'est-ce que rgchBaggage ? C'est simplement un tableau de plusieurs chaînes de caractères ASCII qui sont à la suite de la structure SHEXPACKET. Dans ce tableau, vous pouvez mettre le nom de l'opération que vous voulez exécuter sur le fichier, le nom du fichier, les paramètres que vous voulez passer au fichier et le répertoire de travail.
Le VxD Shell obtient l'adresse de la chaîne de caractères dans rgchBaggage en ajoutant la distance relative entre la structure SHEXPACKET au premier octet de la chaîne de caractères à l'offset de SHEXPACKET. Par exemple, si la structure SHEXPACKET commence en 0060000h et la chaîne de caractères suit immédiatement cette structure, alors la distance entre la structure et la chaîne est la taille de la structure elle-même, sur 32 octets (20h). Ainsi le VxD Shell sait que la Chaîne est placée à l'adresse 0060020h. Ce paramètre sert de position relative pour la chaîne (par rapport au début de la structure = point d'origine)
;---------------------------------------------------------------------------------
; VxD Source Code
;---------------------------------------------------------------------------------
.386p
include \masm\include\vmm.inc
include \masm\include\vwin32.inc
include \masm\include\shell.incVxDName TEXTEQU <VXDEXEC>
ControlName TEXTEQU <VXDEXEC_Control>
VxDMajorVersion TEXTEQU <1>
VxDMinorVersion TEXTEQU <0>VxD_STATIC_DATA_SEG
VxD_STATIC_DATA_ENDSVXD_LOCKED_CODE_SEG
;----------------------------------------------------------------------------
; Souvenez-vous : le nom du VxD DOIT ÊTRE en majuscule sinon il ne se chargera/déchargera pas.
;----------------------------------------------------------------------------
DECLARE_VIRTUAL_DEVICE %VxDName,%VxDMajorVersion,%VxDMinorVersion, %ControlName,UNDEFINED_DEVICE_ID,UNDEFINED_INIT_ORDERBegin_control_dispatch %VxDName
Control_Dispatch W32_DEVICEIOCONTROL, OnDeviceIoControl
End_control_dispatch %VxDName
BeginProc OnDeviceIoControl
assume esi:ptr DIOCParams
.if [esi].dwIoControlCode==1
VxDCall _SHELL_CallAtAppyTime,<<OFFSET32 OnAppyTime>,0,0,0>
.endif
xor eax,eax
ret
EndProc OnDeviceIoControl
VXD_LOCKED_CODE_ENDSVXD_PAGEABLE_CODE_SEG
BeginProc OnAppyTime, CCALL
ArgVar RefData,DWORD
ArgVar TheFlag,DWORD
EnterProc
mov File.shex_dwTotalSize,sizeof SHEXPACKET
add File.shex_dwTotalSize,sizeof EXEName
mov File.shex_dwSize,sizeof SHEXPACKET
mov File.shex_ibOp,0
mov File.shex_ibFile,sizeof SHEXPACKET
mov File.shex_ibParams,0
mov File.shex_ibDir,0
mov File.shex_dwReserved,0
mov File.shex_nCmdShow,1
VxDCall _SHELL_ShellExecute, <OFFSET32 File>
LeaveProc
Return
EndProc OnAppyTime
VXD_PAGEABLE_CODE_ENDSVXD_PAGEABLE_DATA_SEG
File SHEXPACKET <>
EXEName db "calc.exe",0
VXD_PAGEABLE_DATA_ENDSend
VxDCall _SHELL_CallAtAppyTime,<<OFFSET32 OnAppyTime>,0,0,0>Il passe l'adresse (Flat) de la fonction OnAppyTime à _Shell_CallAtAppyTime pour que le VxD Shell l'appelle quand un événement de temps appy se produit. Nous n'employons pas de données de référence et n'avons aucun besoin du temps mort donc les trois paramètres après l'adresse OnAppyTime sont mis à zéros.
BeginProc OnAppyTime, CCALLNous déclarons notre fonction avec BeginProc. Puisque le VxD Shell appellera OnAppyTime avec une séquence d'appel C, nous avons besoin de spécifier l'attribut CCALL.
ArgVar RefData,DWORDPuisque le VxD Shell appellera OnAppyTime avec deux paramètres, nous devons définir une pile en conséquence. La macro ArgVar sert au réglage des bornes (la taille) de pile. Sa syntaxe est la suivante :
ArgVar TheFlag,DWORD
EnterProc
...
LeaveProc
Return
ArgVar varname, size, usedvarname est le nom du paramètre. Vous pouvez employer n'importe quel nom. size est, bien sûr, la taille du paramètre en octets. Vous pouvez utiliser BYTE, WORD, DWORD ou 1,2,4. used est habituellement omis.
mov File.shex_dwTotalSize,sizeof SHEXPACKETLes instructions à l'intérieur de la procédure sont simples : elles initialisent la structure SHEXPACKET et appellent le service _Shell_ShellExecute. Notez que shex_dwTotalSize contient la taille ajoutée de la structure SHEXPACKET elle-même et la taille de la chaîne de caractère qui la suit. C'est un cas simple. Si la chaîne de caractères ne suit pas immédiatement cette structure, vous devez calculer la distance entre le premier octet de la structure et le dernier octet de la chaîne de caractères par vous-même. shex_ibFile contient la taille de la structure elle-même parce que le nom du programme suit immédiatement la structure. shex_ibDir est mis à 0, ce qui signifie que nous voulons employer le répertoire Windows en tant que répertoire de travail. Notez que ça ne signifie pas que le programme doit être dans ce répertoire. Le programme peut être placé n'importe où tant que Windows peut le retrouver. shex_nCmdShow est mis à 1 ce qui est équivalant à la valeur SW_SHOWNORMAL.
add File.shex_dwTotalSize,sizeof EXEName
mov File.shex_dwSize,sizeof SHEXPACKET
mov File.shex_ibOp,0
mov File.shex_ibFile,sizeof SHEXPACKET
mov File.shex_ibParams,0
mov File.shex_ibDir,0
mov File.shex_dwReserved,0
mov File.shex_nCmdShow,1
VxDCall _SHELL_ShellExecute, <OFFSET32 File>
File SHEXPACKET <>Nous définissons une structure SHEXPACKET suivie immédiatement par le nom du programme que nous voulons exécuter.
EXEName db "calc.exe",0