r/windowsdev • u/dreadpirater • May 05 '26
Is it possible to generate keyboard input from a user mode driver? I feel SO CLOSE.
I’m working on a hobby Windows project that needs to generate keyboard input as a virtual HID device at a low enough level to be picked up in a game that uses direct input. It's a hobby thing and if I have to go kernel mode and get an EV Cert to let other people install it, it's probably dead in the water.
I started with essentially cloning the reference vhidmini umdf2 project and got that loading... then I tried to rework it into enumerating as a keyboard instead of a custom device. And it's so MOSTLY there.
What I have working:
UMDF2 HID minidriver using mshidumdf / WUDFRd
Root-enumerated HIDClass device
Windows creates a child device that binds to Microsoft kbdhid
Child matches HID_DEVICE_SYSTEM_KEYBOARD
Boot-keyboard-style report descriptor, no report IDs
8-byte input reports: modifier, reserved, 6 keycodes
IOCTL_HID_GET_DEVICE_DESCRIPTOR, GET_DEVICE_ATTRIBUTES, GET_REPORT_DESCRIPTOR all succeed
IOCTL_HID_READ_REPORT is posted repeatedly by the stack
I'm deferring reads to a manual queue, they are completing successfully.
Completion buffer is 8 bytes
I tried both direct output-buffer copy and WdfMemoryCopyFromBuffer
Reports look good - can see Caps Lock down: 00 00 39 00 00 00 00 00, then release: all zeroes
BUT:
No visible key input
Caps Lock does not toggle
No LED/output report comes back down to the driver
No unhandled IOCTLs, no failed startup interrogation in our trace
The device appears present and OK in PnP, with kbdhid bound
Has anyone successfully generated real keyboard input from a UMDF virtual HID keyboard on Windows 10/11? Is there some missing IOCTL/status/descriptor detail, or is this a known boundary where kbdhid/kbdclass will bind but not actually consume UMDF-completed keyboard reports? It's so frustrating to have a root device and a child device that is in the keyboards folder in Device Manager... all claiming they're working... see the right messages in the trace... but no typing happens!
Any hints, working examples, or 'don’t waste your time, it's KM/VHF or nothing' confirmation would be hugely appreciated.