|
Accueil-->VxD W9x en ASM - Chapitre 7
Application Time et fonctions du Shell1 IntroductionLe temps d'application est communément appelé "appy time". Cela signifie simplement le temps où la VM système est assez stable pour permettre l'interaction entre VxD et applications en ring 3, particulièrement 16-bit. Par exemple, pendant l’appy time, un VxD peut charger et appeler des fonctions de DLL 16-bit. L’appy time n'est pas disponible sous Windows 3.1x. Sous Windows 3.1x, un VxD peut obtenir l'adresse de n'importe quelle fonction dans une DLL 16-bit et simuler un far call à cette adresse. Cependant, cela interrompra n'importe quelle tâche dans le ring-3 en raison de la réentrance du VMM. Donc les seules API que VxD peut appeler sont ceux qui celles qui ne font pas appel aux interruptions comme PostMessage. Sous Windows 9x, un VxD peut appeler pratiquement n'importe quelle fonction dans n'importe quel DLL 16-bit avec l'aide de l’ appy time. Très simplement, si votre VxD est averti de l’appy time, il peut charger une DLL 16-bit et y appeler des fonctions. Ainsi comment un VxD est il averti de l’appy time ? Il doit enregistrer un événement appy time avec le Shell VxD. Sous réserve que la VM système soit dans un état stable, le Shell VxD appellera la fonction de rappel que le VxD a spécifié quand il a enregistré un événement appy time. Le Shell VxD appellera votre fonction de rappel une seule fois pour chaque enregistrement d’événement d’appy time. C’est comme la recherche d'un job. Vous allez à une agence de recrutement, et lui communiquez votre nom et votre numéro de téléphone et retournez à la maison. Quand un travail est vaquant, l'agence vous téléphone. Vous en prenez connaissance et elle ne vous rappelle plus à ce sujet. Cela peut prendre un certain temps avant qu'un événement appy time survienne. Les événements appy time ne sont pas disponibles dans certaines circonstances : Pendant le démarrage ou l'arrêt du système et quand la VM système est dans une section critique ou attend un sémaphore 2 Gestion d'un événement appy timeVous pouvez enregistrer événement appy time en appelant _SHELL_CallAtAppyTime définie comme suit : VxDCall _SHELL_CallAtAppyTime, <<OFFSET32 pfnCallback>, dwRefData, dwFlags, dwTimeout> pfnCallBack est l'adresse linéaire de la fonction de rappel qui doit être appelée par le Shell VxD quand un événement appy time survient. La fonction recevra deux paramètres, dwRefData et dwFlags qui sont exactement identiques aux deux paramètres que vous avez passé à _SHELL_CallAtAppyTime. Notez que le Shell VxD appellera votre fonction de rappel avec la convention d'appel C. Vous devez définir votre fonction de rappel de service comme détaillé ci après. Ce service est asynchrone, ce qui signifie qu'il retourne immédiatement après l'enregistrement de votre callback de l'événement appy time.
BeginProc OnAppyTime, CCALL, PUBLIC
dwRefData La référence aux données que vous voulez que le Shell VxD passe à votre fonction de rappel. Cela peut être tout ce que vous voulez.
dwFlags Flags d’événement. Une des valeurs suivantes: - CAAFL_RING0 évènement Ring-0. - CAAFL_TIMEOUT Dépassement de la durée spécifiée par dwTimeout. Simplement si vous voulez attendre l'événement de temps appy pour une certaine période seulement, employez le drapeau CAAFL_TIMEOUT. Si vous voulez attendre indéfiniment l'événement de temps appy, employez le NULL. Je ne sais pas ce que CAAFL_RING0 fait en réalité.
wTimeout La période de temps ou le VxD doit attendre l'événement appy time. Je n'ai pas trouvé de renseignements concernant l'unité de temps employée avec cet argument. En cas de succès, le handle de l’application gérant l’appy time est retourné dans eax. En cas d’échec, eax contient 0. 3 ComplémentsVous pouvez annuler l'enregistrement de temps appy en appelant _SHELL_CancelAppyTimeEvent qui prend un seul paramètre, le handle d'événement de temps appy fourni par _SHELL_CallAtAppyTime. Par sécurité, avant l'appel _SHELL_CallAtAppyTime, contrôlez le système pour vérifier si l'événement appy time peut être disponible. Par exemple, que ce passe t'il si vous enregistrez un événement appy time alors que le système s'arrête ? La fonction de rappel de votre VxD ne sera jamais appelée! Vous pouvez savoir si un événement de temps appy peut être disponible en appelant _SHELL_QueryAppyTimeAvailable. Ce service ne prend aucun paramètre. Il retourne 0 dans eax si l’appy time ne peut être disponible, comme par exemple si le système se ferme ou le serveur de messages a obtenu des fautes de protection générale. Ce service ne vous averti pas d’un appy time: il vous dit seulement qu'il peut y avoir des événements appy time. Bref, si vous voulez jouer la sécurité, appelez _SHELL_QueryAppyTimeAvailable d'abord et s'il rend une valeur non nulle dans eax, vous pouvez appeler _SHELL_CallAtAppyTime. 4 Services Appy Time du Shell4.1 GénéralitésQuand l’appy time est atteint, il y a plusieurs services du Shell que vous pouvez appeler : Ces six services sont fournis pour que les VxD puissent appeler des fonctions 16-bit de DLL ou d' EXE 16-bit, comme WinHelp. Cependant, puisque vivons dans un monde 32-bit (et 64-bit bientôt !), Je n'entrerai pas dans leurs détails. Si vous êtes intéressés, consultez la documentation du DDK. D’autres appels du Shell sont plus utiles : _SHELL_ShellExecute et _SHELL_BroadcastSystemMessage. Avec _SHELL_BroadcastSystemMessage, vous pouvez envoyer un message à toutes les fenêtres de plus haut niveau et à tous les VxD via un seul appel Si l’appy time est disponible, vous pouvez envoyer des messages à toutes les fenêtres et VxD. Si l’appy time n'est pas disponible, vous pouvez n’envoyer des messages qu’aux VxD. _SHELL_ShellExecute est l'homologue en ring-0 de la fonction ShellExecute dans le ring-3. En réalité cette fonction appelle ShellExecute en ring-3 pour faire le travail. Avec ce service de shell, vous pouvez exécuter, ouvrir, imprimer n'importe quel fichier. _SHELL_ShellExecute a la définition suivante : VxDCall _SHELL_ShellExecute, <OFFSET32 ShexPacket> Il n'y a qu'un seul paramètre, l'adresse linéaire de structure SHEXPACKET. La valeur de retour de ShellExecute est dans eax. 4.2 La structure de SHEXPACKETLa taille en octets de la structure SHEXPACKET plus le paramètre facultatif, rgchBaggage, qui suit immédiatement cette structure. Je décrirai rgchBaggage bientôt. La taille en octets de la structure SHEXPACKET, sans compter rgchBaggage. Combiné avec shex_dwTotalSize ci-dessus, le Shell peut calculer la taille de rgchBaggage qui est de longueur arbitraire. L'opération que vous voulez exécuter. Si vous spécifiez 0, cela signifie que vous voulez ouvrir un fichier. Si le fichier est exécutable, il est exécuté. Si vous voulez exécuter une autre opération, vous devez spécifier le nom de l'opération quelque part dans rgchBaggage et ce champ doit contenir le décalage en octets du début de cette structure de SHEXPACKET au premier caractère de la chaîne ASCIIZ qui spécifie le nom de l'opération que vous voulez exécuter. La taille de SHEXPACKET est de 32 octets. Si la chaîne d'opération suit immédiatement la structure de SHEXPACKET, la valeur dans shex_ibOp DOIT ÊTRE 32. Quant à la liste des opérations vous pouvez exécuter, examinez ShellExecute. Il y a trois opérations définies, "open", "print" et "explore". La distance relative du début de la structure à la chaîne ASCIIZ qui est le nom du fichier vous voulez envoyer à ShellExecute, comme pour shex_ibOp. Les paramètres facultatifs que vous voulez passer au fichier indiqué dans shex_ibFile. Si le fichier est un document ou si vous ne voulez pas passer de paramètres, employez 0. Si vous voulez passer des paramètres au fichier, mettez la chaîne de paramètres quelque part après cette structure et indiquez son offset avec le début de la structure dans ce champ, comme pour shex_ibOp et shex_ibFile. Le répertoire de travail. Spécifiez 0 si vous voulez employer le répertoire de Windows. Dans le cas contraire spécifiez la chaîne représentant le répertoire et mettez l’offset entre le début de la chaîne et le début de la structure dans ce champ. Comme le nom l'indique, il est réservé. Comment afficher la fenêtre de l'application. C'est une de la valeur que vous passez normalement à ShowWindow du type SW_XXX. Cherchez ces valeurs dans windows.inc. 4.3 ComplémentsTous les membres sont de type DWORD. Maintenant voici le détail de rgchBaggage que je vous ai promis. C’ est un peu difficile à expliquer. rgchBaggage est un membre de la structure SHEXPACKET mais il ne peut pas être inclus dans la définition de structure parce que sa taille est arbitraire. Vérifiez shell.inc, vous verrez que rgchBaggage n'est pas défini dans SHEXPACKET bien que la documentation du DDK affirme le contraire. Qu'est ce rgchBaggage ? C'est simplement un tableau de chaînes de caractères ASCIIZ qui suit la structure de SHEXPACKET. Dans ce tableau, vous pouvez mettre le nom de l'opération que vous voulez exécuter, le nom du fichier, les paramètres que vous voulez passer et une liste de répertoires. Le Shell VxD obtient l'adresse de la chaîne dans rgchBaggage en ajoutant la distance relative entre la structure de SHEXPACKET et le premier octet de la chaîne à l'adresse linéaire de SHEXPACKET. Par exemple, si la structure de SHEXPACKET commence à 60000h et que la chaîne suit immédiatement la structure, la distance entre la structure et la chaîne correspond à la taille de la structure elle-même, soit 32 (20h). Donc le Shell VxD sait que la chaîne est à l'adresse 60020h. 5 Exemple5.1 GénéralitésCe sera un exemple très simple, juste pour vous montrer comment enregistrer un événement appy time et employer _SHELL_ShellExecute. Le VxD dynamique est chargé par une application simple win32. Quand l'utilisateur presse "Calculer", l'application win32 appelle DeviceIoControl pour demander au VxD d'enregistrer un événement de temps appy et lance calc.exe dans le répertoire de Windows. 5.2 Code
;---------------------------------------------------------------
5.3 AnalyseLe VxD attend les messages du service N°1 de DeviceIoControl, service n°1. Quand il reçoit un tel message, il enregistre un événement appy time. VxDCall _SHELL_CallAtAppyTime,<<OFFSET32 OnAppyTime>,0,0,0> Il passe l'adresse linéaire de la fonction OnAppyTime à _SHELL_CallAtAppyTime pour que le Shell VxD puisse l'appeler quand un événement appy time survient. Nous n'employons pas de référence de données et ne nous occuperons pas des temps morts donc tous les trois paramètres suivants sont à 0. Quand un événement appy time survient, le Shell VxD appelle la fonction OnAppyTime. BeginProc OnAppyTime, CCALL Nous déclarons une fonction avec BeginProc. Puisque l'appel OnAppyTime par le Shell VxD est de type C, nous devons spécifier l'attribut de CCALL.
ArgVar RefData, DWORD Puisque le Shell VxD appelle OnAppyTime avec deux paramètres, nous devons préparer la pile en conséquence. La macro ArgVar est conçue pour adapter la pile à chacun des arguments passés à la fonction. Sa syntaxe est la suivante : ArgVar varname, size, used varname est le nom du paramètre. Vous pouvez employer n'importe quel nom de votre choix. La taille est, bien sûr, la taille du paramètre en octets. Vous pouvez employer BYTE, WORD, DWORD ou 1,2,4. USED est d'habitude omis. Immédiatement après ArgVar, nous devons employer les macros EnterProc et LeaveProc pour marquer le commencement et la fin des instructions dans la procédure de manière à ce que les variables locales et les paramètres puissent être accessibles. Utilisez Return pour retourner à l'appelant.
mov File.shex_dwTotalSize, sizeof SHEXPACKET Les instructions à l'intérieur de la procédure sont simples : initialisez la structure SHEXPACKET et appelez le service _SHELL_ShellExecute. Notez que shex_dwTotalSize contient la taille de la structure de SHEXPACKET elle-même et de la taille de la chaîne qui la suit. C'est le cas simple. Si la chaîne ne suit pas immédiatement la structure, vous devez calculer la distance entre le premier octet de la structure et le dernier octet de la chaîne par vous-même. Shex_ibFile contient la taille de la structure seule parce que le nom du programme suit immédiatement la structure. Shex_ibDir est à 0 signifiant que le répertoire de Windows sera le répertoire de travail. Notez que cela ne signifie pas que le programme doit être dans ce répertoire. Le programme peut être n'importe où, tant que Windows puisse le trouver. Shex_nCmdShow est égal à 1 qui est la valeur SW_SHOWNORMAL.
File SHEXPACKET <> Nous définissons une structure SHEXPACKET suivie immédiatement par le nom du programme que nous voulons exécuter.
Page:
1
2
3
4
5
6
7
8
9
Copyright © Jean-Pierre Fayeulle |