2009-09-16 10 views
19

Sono abbastanza nuovo per lo sviluppo di driver e cercando di scrivere un driver di filtro semplice che abilitare o disabilitare una periferica tastiera o un mouse. Se riesco a farlo funzionare, voglio usarlo per disattivare il touchpad sul mio portatile quando viene collegato un mouse. Mi rendo conto che probabilmente c'è già del software che lo fa già, ma sono davvero interessato ai driver di dispositivo e voglio impara a farlo da soloRaw PDO per inviare IOCTL al driver di filtro superiore (kbfiltr/moufiltr) per abilitare/disabilitare il dispositivo

Sto usando le kbfiltr e moufiltr esempi forniti con il WDK, installato come driver di filtro superiori. L'esempio kbfiltr crea un pdo che può essere enumerato e connesso da un programma usermode. Questo mi permette di inviare IOCTL alla DOP che sono gestite da KbFilter_EvtIoDeviceControlForRawPdo. Tuttavia, quando cerco di fare qualsiasi cosa relativa al driver di filtro, come chiamata in KbFilter_EvtIoInternalDeviceControl modo che io possa fare qualcosa di simile

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

ottengo un BSOD. Non è il codice di cui sopra, nell'esempio di vanilla l'insieme di null è commentato, solo chiamando in Kbfilter provoca il BSOD. Ho provato a impostare l'estensione del dispositivo direttamente nel PDO ma questo causa anche un BSOD, presumibilmente perché è il devExt PDO, non quello di kbfiltr?

(correlate: che cosa è un buon modo di ottenere l'analisi dello stack da un BSOD Sto usando Virtual PC come il mio ambiente di test e di un accumulo incontrollato di XPSP3)

non posso inviare un'IOCTL_INTERNAL_KEYBOARD_DISCONNECT direttamente a lo stack driver (comprendo che i dispositivi di input accettano solo una connessione alla volta?), quindi la necessità del PDO raw. Ho davvero solo bisogno di inviare due IOCTL (per abilitare e disabilitare) e ho pensato che avrei usato la disconnessione della tastiera e la connessione poiché erano già stati definiti.

Se mi sbaglio su una qualsiasi di queste ipotesi, fatemelo sapere, so che sono davvero un noob in questo, ma non ho trovato molta documentazione su questo tipo di comunicazione tramite un PDO.

risposta

16

Ok, ho finalmente risolto questo e il mio autista sta funzionando.

Implementazione di un driver di filtro KMDF:

Grazie a Sergio che ha suggerito l'approccio porta COM, perché questo mi ha aiutato a impostare WinDbg.This awesome blog post spiega come ottenere da esso istituito in fretta, in pratica si lascia VPC configurato una porta com come named pipe, abilita la modalità di debug del kernel sul sistema operativo virtualizzato e si connette ad esso mentre sta avviando. Quindi è possibile ottenere tutti i messaggi DbgPrint quando il driver viene caricato e fare molto di più, ma solo i messaggi di tracciamento durante il processo di avvio sono stati di grande aiuto per me.

Penso che il mio problema principale stava cercando di riutilizzare un IOCTL interno KbFiltr.Questa è stata solo una pessima idea progettuale da parte mia perché non ho compreso la differenza tra IOCTL interno e altri IOCTL: IOCTLS interni come IOCTL_INTERNAL_KEYBOARD_DISCONNECT hanno condizioni di accesso limitate e devono essere inviati solo da altri driver o dal kernel. Anche this KB article "How to send IOCTL to filter driver" è un esempio che utilizza la stessa struttura di dispositivo di controllo, ma è WDM.

In ogni caso, dopo aver combattuto con l'esempio KbFiltr per tutto il fine settimana, alla fine ho rinunciato e ho iniziato a usare il WDF Toaster/filtr example. Questo è un driver del filtro KMDF più semplice e ho dovuto riempire un sacco di spazi vuoti usando KbFiltr e MouFiltr. L'operazione del driver del filtro del tostapane è simile a KbFiltr ma crea un dispositivo di controllo invece di un PDO. Imposta anche un nome dispositivo dos per il dispositivo di controllo in modo da poter comunicare con esso da usermode senza dover Pinvoke per fare quel passo. Il dispositivo di controllo ti consente di controllare tutti i dispositivi che hanno caricato il tuo filtro driver semplicemente iterando sulla raccolta. Un waitlock viene utilizzato per sincronizzare l'accesso alla raccolta.

Ho anche potuto modificare il file INF (per usare la classe Mouse invece della classe Toaster) e applicarlo direttamente dalla mia macchina di prova senza modificare il codice del driver! È molto più facile iniziare con qualcosa che funziona. This page fornisce un elenco completo delle cose che è necessario modificare per adattare i campioni.

+2

Il mio primo commento, e probabilmente l'ultimo, +1! Mi ha risparmiato ore ... grazie mille per aver trovato il tempo per formattare la tua risposta ... perfetta! –

+0

Mi chiedo se è possibile condividere il codice del driver del filtro della tastiera. Sto provando ad abilitare/disabilitare una tastiera USB (dai molti che ho collegato al mio PC per scopi speciali) ma ho avuto difficoltà a capire come farlo. Provare con lo sviluppo del driver di filtro, ma si sta muovendo lentamente. Forse puoi condividere le tue fonti per vedere come sei riuscito a fare le cose. –

+0

Certo Andy, non c'è problema, l'ho fatto funzionare e ho usato un servizio Windows con WMI per accendere o spegnere il touchpad se un mouse esterno è stato collegato. Come vorresti che ti mandassi? –

3

Prima di tutto: Si può fare quello che si vuole fare (disattivare il touchpad sul mio portatile quando il mouse è collegato) nella modalità utente. Sarà molto più semplice e più sicuro. Guarda Using Device Installation Functions e WM_DEVICECHANGE

Per eseguire il debug dei problemi nel codice: scaricare un dump di memoria da BSOD o impostare una connessione del debugger del kernel (utilizzando una porta COM sul PC virtuale reindirizzata a una pipe). Vedere Debugging Tools for Windows

Buon divertimento!

+0

Grazie Sergius, hai altre informazioni sulla funzione SetupDi Avrò bisogno di chiamare per abilitare o disabilitare il touchpad (o anche solo interrompere la sua interfaccia dall'invio di messaggi)? –

+2

Esaminare le origini di devcon.exe da WINDDK (WINDDK \ 6000 \ tools \ devcon \ i386 \ devcon.exe, WINDDK \ 6000 \ src \ setup \ devcon \\). Può abilitare/disabilitare dispositivi e fare molte altre cose usando SetupAPI. –

Problemi correlati