winapi - DOP sin formato para enviar IOCTL al controlador del filtro superior(kbfiltr/moufiltr) para habilitar/deshabilitar el dispositivo
driver device-driver (2)
En primer lugar: puede hacer lo que quiera hacer (deshabilitar el panel táctil de mi computadora portátil cuando el mouse está conectado) en el modo de usuario. Será mucho más sencillo y seguro. Mire WM_DEVICECHANGE usar 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 de depuración del kernel (usando un puerto COM en su PC virtual redirigido a una tubería). Ver herramientas de depuración para Windows
¡Que te diviertas!
Soy bastante nuevo en el desarrollo de controladores y trato de escribir un controlador de filtro simple que habilite o inhabilite 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 el mouse está enchufado. Me doy cuenta de que probablemente hay un software que ya lo hace, 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 incluyen 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 IOCTLs a la DOP que son manejados por KbFilter_EvtIoDeviceControlForRawPdo . Sin embargo, cuando intento hacer algo relacionado con el controlador del filtro, como llamar a KbFilter_EvtIoInternalDeviceControl , puedo 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 llamando a Kbfilter causa el BSOD. He intentado configurar la extensión del dispositivo directamente en el PDO, pero esto también causa un BSOD, probablemente porque es el devExt del PDO, ¿no el de kbfiltr?
(relacionado: ¿cuál es una buena manera de obtener el seguimiento de 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 solo aceptan una conexión a la vez?) Por lo tanto, la necesidad de la DOP sin formato. Realmente solo necesito enviar dos IOCTL (para habilitar y deshabilitar) y pensé que solo usaría la desconexión y conexión del teclado ya que estos ya estaban definidos.
Si me equivoco con cualquiera de estas suposiciones, 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 una DOP.
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 del 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 está iniciando. Luego, puede obtener todos los mensajes 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 fue tratar de reutilizar un IOCTL interno en KbFiltr. Esto 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 restringido y solo deben enviarlos otros controladores o el núcleo. Además, este artículo de KB "Cómo enviar IOCTL al controlador de filtro" es un ejemplo que utiliza la misma estructura de dispositivo de control, pero es WDM.
De todos modos, después de luchar con el ejemplo de KbFiltr durante todo el fin de semana, finalmente me di por vencido y comencé de nuevo usando el ejemplo WDF Toaster / filtr . Este es un controlador de filtro KMDF más básico y tuve que rellenar muchos espacios en blanco utilizando KbFiltr y MouFiltr. La operación del controlador del filtro de la tostadora 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 usermode 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 solo iterando sobre la colección. Se utiliza un waitlock 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 de inmediato en mi máquina de prueba sin modificar el código del controlador! Es mucho más fácil comenzar con algo que está funcionando. Esta página ofrece una lista completa de las cosas que debe cambiar para adaptar las muestras.