2009-09-16 11 views
19

Ich bin ziemlich neu in der Treiberentwicklung und versuche, einen einfachen Filtertreiber zu schreiben, der ein Tastatur- oder Mausgerät aktiviert oder deaktiviert. Wenn ich es schaffen kann, möchte ich es verwenden, um das Touchpad auf meinem Laptop zu deaktivieren, wenn eine Maus eingesteckt ist. Mir ist klar, dass es wahrscheinlich Software gibt, die das bereits tut, aber ich bin wirklich an Gerätetreiber interessiert und möchte lerne, wie ich das selbst mache.Raw PDO zum Senden von IOCTL an den oberen Filtertreiber (kbfiltr/moufiltr) zum Aktivieren/Deaktivieren des Geräts

Ich verwende die kbfiltr und moufiltr Beispiele, die mit dem WDK versenden, als obere Filtertreiber installiert. Das Beispiel kbfiltr erzeugt ein pdo, das von einem usermode-Programm aufgelistet und mit ihm verbunden werden kann. Dies ermöglicht es mir, IOCTLs an das PDO zu senden, die von KbFilter_EvtIoDeviceControlForRawPdo behandelt werden. Allerdings, wenn ich versuche und alles tun, um alle auf den Filtertreiber verwendet, wie Anruf in KbFilter_EvtIoInternalDeviceControl so kann ich so etwas wie

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; 
    ... 
    } 

ich einen BSOD bekommen. Es ist nicht der obige Code, im Vanilla-Beispiel ist der auf null gesetzte Wert auskommentiert, der Aufruf von Kbfilter verursacht den BSOD. Ich habe versucht, die Geräteerweiterung direkt im PDO zu setzen, aber das verursacht auch einen BSOD, vermutlich, weil es das PDO devExt ist, nicht kbfiltr?

(bezogen: Was des Erhaltens der Stack-Trace von einem BSOD ein guter Weg ist, ich Virtual PC als meine Testumgebung und einen ungeprüften Build von XPSP3 bin mit)

ich keine IOCTL_INTERNAL_KEYBOARD_DISCONNECT senden kann direkt an der Treiberstapel (ich verstehe, dass Eingabegeräte nur eine Verbindung zu einer Zeit akzeptieren?) Daher die Notwendigkeit für das rohe PDO. Ich brauche wirklich nur zwei IOCTLs zu senden (zu aktivieren und zu deaktivieren) und ich dachte, ich würde einfach die Tastatur trennen und verbinden, da diese bereits definiert waren.

Wenn ich mich bei einer dieser Annahmen geirrt habe, lass es mich wissen, ich weiß, dass ich wirklich ein Anfänger bin, aber ich habe nicht viel Dokumentation über diese Art der Kommunikation über eine PDO gefunden.

Antwort

16

Ok, ich habe das endlich gelöst und mein Treiber funktioniert.

Implementierung eines KMDF Filtertreiber:

Dank Sergius, die den COM-Port-Ansatz vorgeschlagen, weil diese mir einrichten geholfen WinDbg.This awesome blog post erklärt, wie es schnell aufgebaut bekommen, Sie im Grunde lassen VPC einrichten ein COM-Port als Named Pipe, aktivieren Sie den Kernel-Debug-Modus für das virtualisierte Betriebssystem und stellen Sie während des Bootvorgangs eine Verbindung her. Dann können Sie alle DbgPrint-Nachrichten erhalten, wenn der Treiber geladen wird und viel mehr tun, aber nur die Trace-Nachrichten während des Startvorgangs waren eine große Hilfe für mich.

Ich glaube, mein Hauptproblem war der Versuch, eine interne IOCTL in KbFiltr zu verwenden.Dies war nur eine schlechte Design-Idee von mir, weil ich den Unterschied zwischen internen IOCTL und anderen IOCTLs nicht verstanden habe - Interne IOCTLS wie IOCTL_INTERNAL_KEYBOARD_DISCONNECT haben eingeschränkte Zugriffsbedingungen und sollten nur von anderen Treibern oder dem Kernel gesendet werden. Auch this KB article "How to send IOCTL to filter driver" ist ein Beispiel, das die gleiche Steuerungsgeräistruktur verwendet, aber es ist WDM.

Wie auch immer, nach dem Kampf mit dem KbFiltr-Beispiel das ganze Wochenende, gab ich schließlich auf und begann über die Verwendung der WDF Toaster/filtr example. Dies ist ein barfeuerer KMDF-Filtertreiber und ich musste eine Menge Leerzeichen mit KbFiltr und MouFiltr füllen. Die Funktionsweise des Toaster-Filtertreibers ähnelt der von KbFiltr, jedoch wird anstelle eines PDO ein Kontrollgerät erstellt. Es legt auch einen DOS-Gerätenamen für das Steuergerät fest, so dass Sie mit ihm vom Benutzermodus aus kommunizieren können, ohne dass Sie diesen Schritt ausführen müssen. Mit dem Steuergerät können Sie alle Geräte steuern, die Ihren Filtertreiber geladen haben, indem Sie einfach über die Sammlung iterieren. Ein Waitlock wird verwendet, um den Zugriff auf die Sammlung zu synchronisieren.

Ich war auch in der Lage, nur die INF-Datei zu ändern (um Maus-Klasse anstelle von Toaster-Klasse zu verwenden) und wenden Sie es direkt aus der Box auf meiner Testmaschine ohne Änderung des Treibercodes! Es ist so viel einfacher, mit etwas zu beginnen, das funktioniert. This page gibt eine umfassende Liste von Dingen, die Sie ändern sollten, um die Proben anzupassen.

+2

Mein erster und wahrscheinlich letzter +1 Kommentar! Erspart mir Stunden ... Danke, dass du dir die Zeit genommen hast, deine Antwort zu formatieren ... perfekt! –

+0

Ich frage mich, ob Sie Ihren Tastaturfiltertreibercode teilen können. Ich versuche, eine USB-Tastatur zu aktivieren/deaktivieren (von den vielen, die ich für spezielle Zwecke an meinen PC angeschlossen habe), aber es fällt mir schwer, herauszufinden, wie das geht. Versuche mit der Entwicklung des Filtertreibers, aber es bewegt sich langsam. Vielleicht können Sie Ihre Quellen teilen, um zu sehen, wie Sie es geschafft haben, Dinge zu tun. –

+0

Sicher, Andy, das ist kein Problem, ich habe das funktioniert und einen Windows-Dienst mit WMI verwendet, um das Touchpad ein- oder auszuschalten, wenn eine externe Maus eingesteckt wurde. Wie soll ich dir schicken? –

3

Zunächst einmal: Sie können tun, was Sie tun möchten (deaktivieren Sie das Touchpad auf meinem Laptop, wenn eine Maus eingesteckt ist) im Benutzermodus. Es wird viel einfacher und sicherer sein. Schauen Sie sich Using Device Installation Functions und WM_DEVICECHANGE

Debug-Probleme in Ihrem Code: Holen Sie sich ein Speicherabbild von BSOD oder Setup eine Kernel-Debugger-Verbindung (ein COM-Port auf Ihrem virtuellen PC zu einem Rohr umgeleitet). Siehe Debugging Tools for Windows

Viel Spaß!

+0

Dank Sergius, haben Sie weitere Informationen über die SetupDi-Funktion, die ich aufrufen muss, um das Touchpad zu aktivieren oder zu deaktivieren (oder einfach die Schnittstelle zum Senden von Nachrichten zu stoppen)? –

+2

Sehen Sie sich die Quellen devcon.exe von WINDDK an (WINDDK \ 6000 \ tools \ devcon \ i386 \ devcon.exe, WINDK \ 6000 \ src \ setup \ devcon \\). Es kann Geräte aktivieren/deaktivieren und eine Menge anderer Dinge tun, die SetupAPI verwenden. –