Hi,
I've been writing software only WFP network drivers on and off for a few years and now recently find myself involved in other areas. My current area relates to keyboards, where I have successfully wrote a Keyboard class KMDF UpperFilter driver that sees keypresses.
An extension of my goals is that I'd like to see the control codes sent from host to keyboard when CAPSLOCK/NUMLOCK/SCROLLLOCK are pressed. Through a series of trial and error I have determined that I can see these using a Keyboard Class KMDF LowerFilter driver in the EvtIoDeviceControl handler, using undocumented control code 0xb0263.
To avoid relying on undocumented control codes, and referencing this doc - I created UpperFilter and LowerFilter drivers on HIDClass. The thinking being that I could see IOCTL_HID_WRITE_REPORT as defined in hidport.h. (Eventually the *LOCK keys will be USB SET REPORT's). However the only EvtIoDeviceControl invocations I see occur immediately after plugging my keyboard in. There are none occuring during the *LOCK keypresses.
From my (naive) understanding of device stacks I would have expected to see 0xb0263 passed down the stack? Or transformed into another control code (IOCTL_HID_WRITE_REPORT) and passed down the stack?
What am I misunderstanding?
Incase it is relevant:
- I'm not interested in PS/2 keyboards, only USB
- All the Upper&Lower filter drivers above store the result of WdfDeviceGetIoTarget in their device context during EvtDeviceAdd, register for EvtIoDefault,EvtIoRead,EvtIoWrite,EvtIoDeviceControl,EvtIoInternalDeviceControl. And forward the IRP with WdfRequestSend.
use the kbdfiltr WDK example as an upper filter. keyboard class or device instance upper filter that sits below kbdclass. you will all key presses in the service callback, including caps lock, numlock, scroll lock. you can process them there if you want, throw them away, log it, etc. filtering at the HIDclass layer for keyboard input is one level too low in the abstraction, as a hid class upper filter will not see all the traffic between the HID PDO and FDO and a lower filter means you are filtering a specific transport (USB in this case), while filtering as described above is independent of all transports (ps2, usb, bluetooth, etc)
Hi Doran, thanks for the reply. Sorry if i was unclear, but I have completed the UpperFilter that detects keypresses. Indeed, I did reference kbdfiltr when doing so.
What I'm interested in now, is detecting the USB SEND_REPORT packets a host sends to keyboards when the *LOCK keys are pressed. This cannot be done as a upper class filter on Keyboard Class as this is not necessarily tied to a keypress on a physical device. (A virtual keyboard for example).
My hope was that I could do something at the HID layer to avoid the aforementioned undocumented control code @ LowerFilter. I'd also like to avoid getting into the dirt with a USB driver, for no other reason than in my head this seems like a solvable problem @ the HID level. Perhaps I'm wrong.
I've recently discovered hidusbfx2
, which i'll look at more closely tomorrow. Maybe that can shed some light on what I'm doing wrong.
Cheers,
Jason
the lower IO edge of hidusb will be URBs. HIDusb doesn't use any private usb functionality IIRC, it is all public WDK. maybe your undocumented IOCTL IOCTL_INTERNAL_USB_SUBMIT_URB?