Raw PDO to send IOCTL to upper filter driver (kbfiltr/moufiltr) to enable/disable device

Viewed 6817

I am quite new to driver development and trying to write a simple filter driver that will enable or disable a keyboard or mouse device. If I can make it work, I want to use it to disable the touchpad on my laptop when a mouse is plugged in. I realize there is probably software out there that does this already, but I am really interested in device drivers and want to learn how to do this myself.

I am using the kbfiltr and moufiltr examples that ship with the WDK, installed as upper filter drivers. The kbfiltr example creates a pdo which can be enumerated and connected to by a usermode program. This allows me to send IOCTLs to the PDO that are handled by KbFilter_EvtIoDeviceControlForRawPdo. However, when I try and do anything at all related to the filter driver, like call into KbFilter_EvtIoInternalDeviceControl so I can do something like

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

I get a BSOD. It is not the above code, in the vanilla example the set to null is commented out, just calling into Kbfilter causes the BSOD. I have tried to set the device extension directly in the PDO but this also causes a BSOD, presumably because it is the PDO devExt, not kbfiltr's?

(related: what is a good way of getting the stack trace from a BSOD? I am using Virtual PC as my test environment and an unchecked build of XPSP3)

I can't send an IOCTL_INTERNAL_KEYBOARD_DISCONNECT directly to the driver stack (I understand that input devices accept only one connection at a time?) hence the need for the raw PDO. I really only need to send two IOCTLs (to enable and disable) and I figured I would just use the keyboard disconnect and connect since these were already defined.

If I am wrong about any of these assumptions, please let me know, I know I really am a noob at this but I haven't found a lot of documentation about this kind of communication via a PDO.

2 Answers
Related