PDO sin formato para enviar IOCTL al controlador de filtro superior (kbfiltr / moufiltr) para habilitar / deshabilitar el dispositivo

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

Pregunta

Soy bastante nuevo en el desarrollo de controladores e intento escribir un controlador de filtro simple que habilite o deshabilite un dispositivo de teclado o mouse. Si puedo hacer que funcione, quiero usarlo para deshabilitar el panel táctil de mi computadora portátil cuando se conecta un mouse. Me doy cuenta de que probablemente ya exista un software que lo haga, pero estoy realmente interesado en los controladores de dispositivos y quiero aprender a hacer esto yo mismo.

Estoy usando los ejemplos kbfiltr y moufiltr que se envían con el WDK, instalado como controladores de filtro superior. El ejemplo kbfiltr crea un pdo que puede ser enumerado y conectado por un programa de modo de usuario. Esto me permite enviar IOCTL a la PDO que manejan KbFilter_EvtIoDeviceControlForRawPdo . Sin embargo, cuando intento hacer algo relacionado con el controlador del filtro, como llamar a KbFilter_EvtIoInternalDeviceControl para poder hacer algo como

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

Me sale un BSOD. No es el código anterior, en el ejemplo de vainilla, el conjunto a nulo está comentado, solo llamar a Kbfilter provoca el BSOD. He intentado configurar la extensión del dispositivo directamente en el PDO, pero esto también causa un BSOD, presumiblemente porque es el devOxt del PDO, no el kbfiltr's.

(relacionado: ¿cuál es una buena forma de obtener el seguimiento de la pila de un BSOD? Estoy usando Virtual PC como mi entorno de prueba y una compilación no comprobada de XPSP3)

No puedo enviar un IOCTL_INTERNAL_KEYBOARD_DISCONNECT directamente a la pila de controladores (¿entiendo que los dispositivos de entrada aceptan solo una conexión a la vez?) De ahí la necesidad del PDO sin procesar. Realmente solo necesito enviar dos IOCTL (para habilitar y deshabilitar) y pensé que simplemente usaría el teclado para desconectar y conectar ya que estos ya estaban definidos.

Si estoy equivocado acerca de cualquiera de estos supuestos, hágamelo saber, sé que realmente soy un novato en esto, pero no he encontrado mucha documentación sobre este tipo de comunicación a través de un PDO.

¿Fue útil?

Solución

Ok, finalmente he resuelto esto y mi controlador está funcionando.

Implementación de un controlador de filtro KMDF :

Gracias a Sergius que sugirió el enfoque de puerto COM porque esto me ayudó a configurar WinDbg. Esta increíble publicación de blog explica cómo configurarlo rápidamente, básicamente permite que VPC configure un puerto com como canalización con nombre, habilite el modo de depuración del kernel en el sistema operativo virtualizado y se conecte a él mientras se inicia. Entonces puede obtener todos los mensajes de DbgPrint cuando el controlador se está cargando y hacer mucho más, pero solo los mensajes de seguimiento durante el proceso de inicio fueron de gran ayuda para mí.

Creo que mi principal problema era intentar reutilizar un IOCTL interno en KbFiltr. Esta fue solo una mala idea de diseño por mi parte porque no entendía la diferencia entre IOCTL interno y otros IOCTL: los IOCTLS internos como IOCTL_INTERNAL_KEYBOARD_DISCONNECT tienen condiciones de acceso restringidas y solo deben enviarlos otros controladores o el núcleo. También este artículo de KB '' Cómo enviar IOCTL para filtrar el controlador '' es un ejemplo con el mismo control estructura del dispositivo, pero es WDM.

De todos modos, después de pelear con el ejemplo KbFiltr todo el fin de semana, finalmente me di por vencido y comencé a usar Ejemplo de WDF Toaster / filtr . Este es un controlador de filtro KMDF más básico y tuve que completar muchos espacios en blanco usando KbFiltr y MouFiltr. La operación del controlador del filtro Toaster es similar a KbFiltr pero crea un dispositivo de control en lugar de un PDO. También establece un nombre de dispositivo dos para el dispositivo de control para que pueda comunicarse con él desde el modo de usuario sin tener que Pinvoke para realizar ese paso. El dispositivo de control le permite controlar todos los dispositivos que tienen su controlador de filtro cargado simplemente iterando sobre la colección. Se utiliza un bloqueo de espera para sincronizar el acceso a la colección.

¡También pude modificar el archivo INF (para usar la clase Mouse en lugar de la clase Toaster) y aplicarlo directamente desde mi caja en mi máquina de prueba sin modificar el código del controlador! Es mucho más fácil comenzar con algo que funciona. Esta página ofrece una lista completa de las cosas que debe cambiar para adaptar las muestras.

Otros consejos

En primer lugar: puede hacer lo que quiera hacer (desactivar el panel táctil en mi computadora portátil cuando se conecta un mouse) en el modo de usuario. Será mucho más simple y seguro. Mire Uso de las funciones de instalación del dispositivo y WM_DEVICECHANGE

Para depurar problemas en su código: Obtenga un volcado de memoria de BSOD o configure una conexión del depurador del núcleo (utilizando un puerto COM en su PC virtual redirigido a una tubería). Consulte Herramientas de depuración para Windows

¡Diviértete!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top