je pense me baser sur celle-là
Convention d'événements Ho0k
25/05/2004 (c) Matthieu Gallet (Flanker)
Description du standard HooK de hooks d'événements. Le respect de celui-ci permet des interactions entre différents HooK et l'usage d'un unique désinstalleur pour tous les HooK.
Ce format est conçu pour permettre l'emploi de la majorité des fonctionnalités des programmes kernel : relogements, BSS, exportations de bibliothèques, ROM_CALL, RAM_CALL...
L'importations des bibliothèques dynamiques traditionnelles est malheureusement impossible, mais l'importations de bibliothèques dynamiques en TSR est possible !
1) Au niveau binaire :
* le hook doit correspondre à un bloc mémoire (handle). Le numéro de ce handle est le TsrId du HooK.
* Le bloc doit avoir la structure suivante :
Offset Taille Valeur Commentaire
0 4 0x486F306B 0x486f306B = "Ho0k". Ceci joue le rôle de signature afin d'identifier un bloc mémoire comme étant un HooK
4 8 ? Il faut mettre le nom du programme. Au besoin, le compléter avec des 0 pour faire 8 caractères exactement
12 4 ? Valeur de la variable globale EV_Hook avant sa modification. Ceci permet de maintenir une liste chaînée des Hooks d'événements installés
16 2 x offset vers la table d'exportation =0 si pas de table
18 2 y offset vers la table d'importation =0 si pas de table
20 ? ? Code du hook d'événement, qui sera appelé par le TIOS.
x 2+2n ? 1er word : nombre de fonctions exportées, puis liste des offsets
y 2+8n ? 1er word : nombre de libs nécessaires, puis liste des noms des libs
Petit détail (merci Pollux ^^). Comme l'adresse à l'offser 12 est en fait codée sur 24bits (68000 oblige), on peut considérer que le nom est une chaîne C normale, terminée par 0.
2) Au niveau du Ho0k lui-même :
* Le seul paramètre de la fonction Hook d'événement est un pointeur vers une structure d'EVENT.
* Les registres a2-a7 et d3-d7 doivent être impérativement restaurés quand on quitte le TSR
* Le hook doit appeller l'ancien hook, en lui passant le pointeur vers l'EVENT par la pile ET en le mettant dans a2 (pour des raisons de compatibilité)
3) Au niveau de l'installation :
Il suffit de recopier la structure décrite dans un bloc alloué grâce à HeapAllocHigh au 1), puis de mettre dans la variable globale EV_Hook l'adresse du bloc + 0x40010.
Le 0x10, c'est parce que le code de la fonction est après le header de 16octets
Le 0x40000, c'est pour des raisons de protection matérielle.
Le HeapAllocHigh permet d'allouer un bloc verrouillé (pour qu'il ne bouge pas) en mémoire haute (pour ne pas gêner la défragmentation de la RAM)
4) Désinstallation :
La désinstallation est un peu plus complexe, mais offre l'avantage qu'un seul programme peut désinstaller tous les Hook (c'est un des buts du standard).
UnHook fait très bien l'affaire, il suffit de l'inclure.
5) Evénements non utilisés par l'AMS
Pour offrir de nouvelles possibilités aux Hook, quelques événements ont été rajoutés.
Ils ne doivent pas être envoyés via la commande EV_sendEvent, mais directement au Hook.
a) CM_EVHK_IS_PRESENT (0x7FFA)
Cet Event va permettre de détecter la présence d'un Hook particulier, même si on ne peut pas parcourir la liste chaînée.
Structure EVENT à envoyer:
Offset Taille Nom Valeur initiale
0 2 Type $7FFA
2 2 RunningApp 0
4 2 Side sans importance
6 2 StatusFlags sans importance
8 4 pasteText pointeur vers le nom du hook (exactement 8 caractères), qui ne doit pas nécessairement être terminé par un '\0'
La réponse du Hook doit être le remplacement de RunningApp par le numéro du handle du hook si le nom correspond.
RunningApp reste à 0 si aucun hook n'a répondu (et donc le hook recherché est absent).
Si votre hook n'est pas censé interagir avec d'autres programmes, gérer CM_EVHK_IS_PRESENT n'est pas super utile.
b) CM_EVHK_CAN_DELETE (0x7FFF)
Vérifie si un hook peut être effacé ou non. Un désinstalleur DOIT envoyer cet évènement avant de commencer l'effaçage.
Structure EVENT à envoyer:
Offset Taille Nom Valeur initiale
0 2 Type $7FFF
2 2 RunningApp handle du hook à effacer
4 2 Side sans importance
6 2 StatusFlags sans importance
8 2 hpasteText 1
Le hook doit mettre hPasteText à 0 s'il ne peut pas être effacé, et ne RIEN faire sinon.
N'importe quel hook peut réagir à cet évènement, pas seulement le hook dont l'effaçage est demandé.
Un hook peut ainsi empêcher l'effaçage d'un autre hook dont il dépend.
c) CM_EVHK_DELETE (0x7FFE)
Permet d'annoncer au hook de handle RunningApp qu'il va être effacé
Prépare l'effaçage d'un hook. Un désinstalleur DOIT envoyer cet évènement avant de supprimer un hook, et il DOIT avoir envoyé CM_EVHK_CAN_DELETE (0x7FFF) et vérifié son résultat auparavant.
Structure EVENT à envoyer:
Offset Taille Nom Valeur initiale
0 2 Type $7FFE
2 2 RunningApp handle du hook à effacer
4 2 Side sans importance
6 2 StatusFlags sans importance
8 4 pasteText pointeur vers la fonction DeleteEventHook
La fonction DeleteEventHook:
prototype: void DeleteEventHook(HANDLE handle asm("d0"));
détruit: d0-d2/a0-a1
Cette fonction est exportée par UnInEvHk pour permettre à un hook de se désinstaller quand un hook duquel il dépend est désinstallé. DeleteEventHook:
(i) envoie CM_EVHK_CAN_DELETE au hook dont le handle est donné et vérifie le résultat,
(ii) envoie CM_EVHK_DELETE au hook dont le handle est donné,
(iii) efface le hook et
(iv) continue l'exécution en envoyant CM_EVHK_DELETE à partir du hook qui SUIT le hook qu'on vient d'effacer dans la liste chaînée.
DeleteEventHook NE retourne QU'en cas d'erreur (hook introuvable dans la liste chaînée ou qui refuse à travers CM_EVHK_CAN_DELETE d'être effacé). En cas de succès, l'adresse de retour se trouve dans un handle effacé et la fonction ne peut donc pas y retourner. Cela explique aussi l'absence de valeur de retour.
Réponse du hook:
Suppression de toutes structures internes au hook autres que le handle lui-même, par exemple des handles supplémentaires alloués.
Un hook peut aussi réagir à la suppression d'un autre hook, par exemple en appelant DeleteEventHook.
ATTENTION: Ceci n'est pas nécessairement le dernier évènement reçu par le hook à effacer. Des évènements supplémentaires peuvent être enclenchés par l'appel de DeleteEventHook par un autre hook, par exemple.
d) CM_EVHK_ICON (0x7FFD)
Permet d'obtenir une icône de la part du hook (pour faire joli dans un shell, par exemple)
Structure EVENT à envoyer:
Offset Taille Nom Valeur initiale
0 2 Type $7FFD
2 2 RunningApp handle du hook
4 2 Side sans importance
6 2 StatusFlags sans importance
8 4 pasteText 0 (NULL)
Réponse du hook:
Remplacement de pasteText par un pointeur vers une icône.
e) CM_EVHK_ABOUT (0x7FFC)
Permet d'obtenir une chaîne d'informations au sujet d'un hook.
Structure EVENT à envoyer:
Offset Taille Nom Valeur initiale
0 2 Type $7FFC
2 2 RunningApp handle du hook
4 2 Side sans importance
6 2 StatusFlags sans importance
8 4 pasteText 0 (NULL)
Réponse du hook:
Remplacement de pasteText par un pointeur vers une chaîne de caractères (d'informations).
f) CM_EVHK_INSTALL (0x7FFB)
Permet de signaliser l'installation d'un hook, pour que d'autres hooks puissent y répondre. Doit être envoyé APRÈS l'installation du hook.
Structure EVENT à envoyer:
Offset Taille Nom Valeur initiale
0 2 Type $7FFB
2 2 RunningApp handle du hook
4 2 Side sans importance
6 2 StatusFlags sans importance
8 4 pasteText 0 (NULL)
Réponse du hook:
Aucune réponse nécessaire.
g) CM_EVHK_CMD_0 (0x7F00) - CM_EVHK_CMD_127 (0x7F7F)
Ces événements ne sont pas utilisés par l'AMS et peuvent donc être utilisés pour envoyer des événements personnalisés à des hook
Structure EVENT à envoyer:
Offset Taille Nom Valeur initiale
0 2 Type $7F00 - $7F7F
2 2 RunningApp handle du hook
4 2 Side spécifié par le hook
6 2 StatusFlags spécifié par le hook
8 2 hpasteText spécifié par le hook
en rajotutant l'event Kernel_uninstal, touours facultatif, en changeant la signature (à cause du changement de convention). Le format sera commun aux TSR Ev_Hook et aux autres types de TSR (qui changent un trap, par exemple), ça ne coûte presque rien et ça permet d'éviter d'avoir un désinstalleur supplémentaire.
Le format permet ainsi, sans aucune autre modificiation, l'utilisation de RAM_CALL, bss, et autres fonctions proposées par le kernel, bref tout sauf l'importation / exportation de libs dynamiques.
Là où ce n'est pas réglé du tout, c'est l'importation / exportation des libs dynamique
- soit j'interdis (mais

je trouve)
- soit je fais en sorte que les libs dynamiques soient classiques, dans ce cas il faudrait interdire le déchargement après la fin du programme (pour les libs concernées)
- soit seuls des TSR déjà installés peuvent être utilisés comme des libs dans le code du TSR, avec un relogement mélangé avec le relogement standard (avec un flag disant que c'est pas une lib standard)
- soit je fais une table d'importation à part, relogée à l'installation par ma lib d'installtion (mais dans ce cas, le code du TSR ne sera pas utilisable quand le programme voudra faire autre chose)
- pour les exportations, soit j'utiilise la table d'exportation actuelle, en ne marquant dans le TSR que les fonctions exportées
donc dans certains cas, il faudrait que je vois avec PpHd ce qui est possible (vu qu'une partie du taf se trouverait dans le kernel)
je crois que c'est à peu près tout