PDO brut pour envoyer IOCTL au pilote de filtre supérieur (kbfiltr / moufiltr) pour activer / désactiver le périphérique

StackOverflow https://stackoverflow.com/questions/1430798

Question

Je suis assez novice en matière de développement de pilotes et d’essai d’écrire un pilote de filtre simple qui active ou désactive un clavier ou une souris. Si je peux le faire fonctionner, je veux l'utiliser pour désactiver le pavé tactile de mon ordinateur portable quand une souris est branchée. Je me rends compte qu'il existe probablement un logiciel qui le fait déjà, mais je suis vraiment intéressé par les pilotes de périphérique et apprendre à le faire moi-même.

J'utilise les exemples kbfiltr et moufiltr fournis avec le WDK, installés en tant que pilotes de filtre supérieurs. L'exemple kbfiltr crée un pdo qui peut être énuméré et connecté à un programme utilisateur. Cela me permet d’envoyer des objets IOCTL au PDO gérés par KbFilter_EvtIoDeviceControlForRawPdo . Cependant, lorsque j'essaie de faire quoi que ce soit en relation avec le pilote de filtre, comme un appel à KbFilter_EvtIoInternalDeviceControl afin que je puisse faire quelque chose comme

.
VOID
KbFilter_EvtIoInternalDeviceControl(
    IN WDFQUEUE      Queue,
    IN WDFREQUEST    Request,
    IN size_t        OutputBufferLength,
    IN size_t        InputBufferLength,
    IN ULONG         IoControlCode
    )
    ...
    hDevice = WdfIoQueueGetDevice(Queue);
    devExt = FilterGetData(hDevice);

    switch (IoControlCode) {      
    ...
      case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:
       //
       // Clear the connection parameters in the device extension.
       //
       devExt->UpperConnectData.ClassService = NULL;
       break;
    ...
    }

Je reçois un BSOD. Ce n'est pas le code ci-dessus, dans l'exemple de vanille, la mise à null est commentée, un simple appel à Kbfilter provoque le BSOD. J'ai essayé de définir l'extension de périphérique directement dans le PDO, mais cela provoque également un BSOD, probablement parce que c'est le PDE devExt, pas celui de kbfiltr?

(en rapport: quel est le bon moyen d'obtenir la trace de pile d'un BSOD? J'utilise Virtual PC comme environnement de test et une version non contrôlée de XPSP3)

Je ne peux pas envoyer d'IOCTL_INTERNAL_KEYBOARD_DISCONNECT directement à la pile de pilotes (je comprends que les périphériques d'entrée acceptent une seule connexion à la fois?), d'où la nécessité du PDO brut. Je n’ai vraiment besoin que d’envoyer deux IOCTL (pour activer et désactiver) et j’ai pensé que j’utiliserais simplement le clavier pour déconnecter et connecter, car ils étaient déjà définis.

Si je me trompe à propos de ces hypothèses, merci de me le faire savoir. Je sais que je suis vraiment un noob, mais je n'ai pas trouvé beaucoup de documentation sur ce type de communication via un AOP.

Était-ce utile?

La solution

D'accord, j'ai enfin résolu le problème et mon pilote fonctionne.

Implémentation d'un pilote de filtre KMDF :

Merci à Sergius qui a suggéré l'approche du port COM, car cela m'a aidé à configurer WinDbg. Cet article de blog génial explique comment le configurer rapidement. En gros, vous laissez VPC configurer un port com en tant que canal nommé, activer le mode de débogage du noyau sur le système d’exploitation virtualisé et vous y connecter pendant le démarrage. Ensuite, vous pouvez obtenir tous les messages DbgPrint lorsque le pilote est chargé et en faire beaucoup plus, mais les messages de trace au cours du processus de démarrage ont été d’une aide précieuse pour moi.

Je pense que mon principal problème était de réutiliser un IOCTL interne dans KbFiltr. C'était une mauvaise idée de conception de ma part car je ne comprenais pas la différence entre IOCTL interne et les autres IOCTL - IOCTLS internes tels que IOCTL_INTERNAL_KEYBOARD_DISCONNECT ont des conditions d'accès restreintes et ne doivent être envoyés que par d'autres pilotes ou le noyau. cet article de la base de connaissances " Comment envoyer IOCTL pour filtrer le pilote & est un exemple utilisant le même contrôle structure de l'appareil, mais il s'agit de WDM.

Quoi qu’il en soit, après avoir lutté contre l’exemple KbFiltr tout le week-end, j’ai finalement renoncé à l’utilisation du exemple WDF Toaster / filtr . Ceci est un pilote de filtre KMDF plus barebones et j'ai dû remplir beaucoup de blancs en utilisant KbFiltr et MouFiltr. L'opération de pilote de filtre Toaster est similaire à KbFiltr, mais elle crée un périphérique de contrôle au lieu d'un PDO. Il définit également un nom de périphérique dos pour le périphérique de contrôle afin que vous puissiez communiquer avec lui à partir du mode utilisateur sans avoir à invoquer Pinvoke pour effectuer cette étape. Le périphérique de contrôle vous permet de contrôler tous les périphériques sur lesquels votre pilote de filtre est chargé simplement en effectuant une itération sur la collection. Un waitlock est utilisé pour synchroniser l'accès à la collection.

J'ai également pu modifier le fichier INF (utiliser la classe Mouse au lieu de la classe Toaster) et l'appliquer directement sur la machine de test sans modifier le code du pilote! Il est tellement plus facile de commencer par quelque chose qui fonctionne. Cette page donne une liste complète des modifications à apporter pour s'adapter les échantillons.

Autres conseils

Tout d'abord: vous pouvez faire ce que vous voulez (désactiver le pavé tactile de mon ordinateur portable lorsqu'une souris est branchée) en mode utilisateur. Ce sera beaucoup plus simple et plus sûr. Consultez Utilisation des fonctions d'installation de périphérique et WM_DEVICECHANGE

Pour déboguer des problèmes dans votre code: obtenez un vidage de la mémoire de BSOD ou configurez une connexion au débogueur du noyau (à l'aide d'un port COM de votre PC virtuel redirigé vers un tuyau). Voir Outils de débogage pour Windows

.

Amusez-vous!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top