Simple virtual HID device emulation - where to start?

So for some time I was relying on languages and libraries like autohotkey, pynput, and few others to automate routine tasks on my machine. With couple years of using macros in their multiple forms and shapes I’ve came to realize that some applications are always unaffected by such automation. That prompted me to explore the underlying windows api code, and do some research about SendInput, and PostMessageW functions and their respective functionality (aside of general basics of how windows handle events and manages windows). This research in its turn pointed to the raw input api which I assume if I figure a way to emulate - it will eliminate most of the cases where the app would be unaffected by a macro. I tried to use PostMessageW passing WM_INPUT as an argument and artificially create the RAWINPUT structure passing one of existing device handles. However I faced the issue (which I now learned is a very common one) of getting a handle for a RAWINPUT structure. My search then continued - and one of the posts I’ve found said that its a functionality which kernel driver can have. So I started doing my small research on drivers. I’ve found the manual on using km functionality from rust binary and making a driver in rust. However there are few things I cant figure yet:

  1. what are the driver types (filter driver, micro driver, etc.) the only explanations I found are very abstract, saying what is attached where and etc. It doesn’t help in figuring which driver type I should research and focus on (I cant rely on uncommented code much cuz I try to do it from rust, and some C and C++ notations are unfamiliar to me).
  2. How does a driver generate WM_INPUT messages? (in particular - what’s the actual function called? can my driver don’t use an actual HID device to generate the message but do it for example using IO from user-mode app?)
  3. Is driver even the right way to do it? Some posts on the matter claim that its a major overkill.
  4. How to debug the driver? I seem to have a large fight with secure boot on my device at the moment. And that’s one thing I don’t want to disable given how hard it can be to re-enable it)
  5. Is using a windows XP/windows 7 virtual machine even worth it? My main device is not very powerful and I wonder if those outdated OS can help me in writing a driver for win 10?

If anyone can recommend me some tutorial or point me to a helpful docs or just give few pointer I will appreciate that very much.
Thank you in advance.

Greetings! Answering your questions … first you should get familiar with using the WinDbg kernel mode debugger (the Visual Studio Kernel mode debugger I’ve found too many problems with), and building and debugging a simple driver. There are some good articles here that discuss building drivers, and several good MS samples to start with on GitHub. I would stick with using C and C++ for your development; Rust is fine and maybe in another 20 years it will be more mainline but for now “Rust” is that thing I keep scraping off my BBQ in the summer …

  1. For keyboard input you’re going to be needing to write a keyboard HID driver, which basically makes keystrokes and sends them to the OS. You can’t get to the usermode application message queue from kernel mode [I think, others correct me] so you need to get there indirectly using the OS.

  2. The driver itself doesn’t generate WM_INPUT messages; those are sent from the OS to the usermode application in focus [I think, others correct me] in response to HID events like keyboard presses

  3. The driver is probably the way to do it, although I would look into using a UMDF v2 driver rather than a KMDF one (in the MS samples look for ones that say UMDF) … it’s more appropriate to what you’re trying to do

  4. You really need to have two separate physical machines to debug drivers; attempting to do that on a single machines is like changing tires on a vehicle while it’s in motion (which is possible, there’s a great YouTube video of a fellow doing that) … possible, but fraught with peril. The development machine is just the way it is today, the target machine will need to be set for test mode. All of this, and more, are in the OSR articles about building drivers. SecureBoot actually doesn’t need to be disabled on the target machine, just test signing enabled

  5. Most folks test drivers inside VM’s unless it’s touching actual physical hardware like PCI buses … otherwise all manner of drivers can and are debugged in a VM all of the time. The driver that you’re going to be writing should be fine to develop on Win7; there are some differences but for starting out Win7 is fine

Google is your friend here, and the OSR articles here have a wealth of information and tips. I would start by reading those and following the examples, Google for something you don’t understand, and have patience … this is likely an entirely new world for you and you won’t learn it overnight …

If you go with the driver to inject input, start with a UMDF2 HID mini port driver (it isn’t really a mini port but the term is used nonetheless). There was a wdk sample for this type of driver in the past, I assume it is still present. The mini port driver allows you to report the raw HID keyboard data and it will go through the in box keyboard class driver.

1 Like

And that’s one thing I don’t want to disable given how hard it can be to re-enable it)

Why? You boot into the BIOS, you change one option, you reboot. It takes 30 seconds.

I think the OP is talking about also setting the CSM mode … but the ultimate point is that you don’t need to do anything since you’re not going to be testing on the development machine …