Virtual Hid Driver - how to design a bidirectional communication between two applications?

I have an application that is written in c# (exe) - which would need to communicate with another windows applications (possibly written in c++ / c#). I could have easily exposed api or any other methods. But then the third party application insists I use Hid.

given that, I have few choices and would like to ask what would be the best design choice here:
implement a KMDF Virtual Hid driver. This driver would be a relay in-between the my application and the other application. My application will send a command to the driver and driver will relay it back to the other application. I would use input report for one way and output reports for other way. but this design looks not very good.

I guess I couldn’t get away with just writing a umdf based simple hid mini driver of some sort and use that as a relay.

typical flow would be something like

Application A → ask the driver what is the state of the device
driver then send this to a raw PDO in VHF
Application B → will be always reading PDO and if it finds anything there, will send a report to the driver
drive will then send this back to the Application A

my question is : what is your opinion on this relay mechanism and what could i do to improve this design?

would it be possible to use virtual hid driver to create a communication between two applications, will this approach work. can two applications connect to same device? if so may be i could have seperate type of reports for each application and then use the driver to persist the information and communicate in between both, where the driver sits inbetween two application and collect information from both sides and relay the information

Of course it’s possible, but it’s insane. NEVER do something in the kernel if there is an adequate solution available in user mode, and clearly there are dozens of interprocess communication solutions available in user mode. Sockets, pipes, memory-mapped files, custom window messages, shared objects. You need to find a SENSIBLE solution.

Did I miss something here? HID is a standard for mouse and keyboard right? And has nothing to do with inter-process communication?

and if you are trying to do something like sending fake keystrokes (valid for some kinds of automated testing), look at the SendInput UM API

Did I miss something here?

No, you didn’t. What he has proposed is, as I said, insane.

1 Like

The solution is needed because to fake a device. What if your device is actually a software solution. But because most apps use hid and use pid/vid to communicate, you would need to show up as device for the application to communicate. The software which is a fake device that runs either as exe or a service, then communicates with the fake device as well which is in the middle. Virtual hid was created for similar scenarios like miracast, fake devices. My question still stands… I am looking for some fake hid device solutions based on wdf , (wdm book has a fake hid sample) where two applications can interact to each other using the virtual hid device in the middle. Vhf provides a framework which helps to relay, but here is where i am still stuck

The current driver samples include a KMDF version of vhidmini. Your proposal is completely the wrong way to solve your problem, but the sample should certainly give you a start.

this is clearly a wrong statement

“most apps use hid and use pid/vid to communicate”

unless I don’t understand the way that you are using these acronyms, no app ever uses HID to communicate. not even with the physical user moving the mouse.

As I understand it, HID stands for Human Input Device and is a standard for how the OS recognizes keyboards, mice etc. Unfortunately, I remember the days when you had to load mouse drivers as well as the much more difficult custom keyboard drivers for early laptops. If you think that HID means something else, please tell us.

Again, HID is a standard for how the hardware will talk with the OS. Not with any application. applications get their input through GDI via windows messages. And those inputs might come from an HID device, or a legacy serial mouse, or a remote desktop connection, or an automation application that calls SendInput, or lots of other stuff.

If you want to send mouse of keyboard input from one UM process to another, and you are not producing malware that needs to cross security boundaries, just use SendInput. it is immensely simpler and fully supported. This is what is used by all kinds of automated testing and application control programs

If I have not understood your question, please help me to my rephrasing and providing more details

Mr. Bond is correct. There are no apps that use HID devices to communicate. I suspect you simply misunderstand your problem. Your title says you want a bidirectional communication channel between two applications. That is a VERY common need, and there are a multitude of solutions, as I outlined above. HID is NOT one of those solutions.

You claim there is a third-party app involved that is dictating your need. What kind of an app? Does it expect to talk to a device? What kind of device?

Really, you need to tell us more, because the problem as you have described it does not make sense.

Ok i cant give lot of details due to nature of project. But here is little more description: An application would look for an hid device using vid and pid to communicate some details like for eg. This could be like a teacher/student application that opens the headset. They will always look for a headset using vid and pid. Now i have a solution which is software only. I dont have a device I want this application to send me the commands as it would to any device I want to design a virtual device which will emulate itself and showup in os as like normal device which would recieve the commands from the application. Since my device is software only, if for eg. Application asks me to mute, i want to grab that command and respond back to the application. I unfortunately couldnt have this logic in the driver itself. My solution is in another application as a software only device. So my fake device application would also want to connect to the virtual device to see what did the teacher/student application is asking and send a response as if its being sent from the device. Why they cant do another way like interprocess? Why would they? They already have code working for all the devices, probably they use very generic hid apis to query and send reports, they wont special case for my fake device. Only choice for me is to fake the device. Does this help?

So, you don’t actually want interprocess communication at all. You want to do HID forwarding. If that’s your goal, then that’s how you should describe it.

1 Like

So a virtual HID device that gets its input from something other than a real device. To send input not to a general application, but one that opens devices directly?

This is not general purpose software and would probably be regarded as malware by many. But in a specific environment, it could be okay.

yes I was thinking a similar functionality that i worked long time ago existed in form of DSF, wdk 7.0, DSF is dead i assume. What are my choices - virtual device is only way I can show up as device to the application. if i go in the route of virtual device - where can i find some good samples, vhidmini doesnt do this - hidinjector is pretty close, any other ideas?

but the way that you describe your problem implies that you are creating new software of some kind in conjunction with a second party? UM programs generally do not open HID devices directly but instead rely on GDI or GDI+ to sort out, amongst other things, if the input was intended for one process or another. There are valid reasons why a UM process might want to monopolize a HID device and there are valid reasons why you might want a virtual HID device, but the intersection of both of those in conjunction with new code on both sides is small.

something like the test harness for a flight simulator (not the game, but the real one with hydraulics) control program. so you can feed automated test cases and perform regression tests?

but regardless of why you might want to do this, the mechanics are simple enough. Just expose one of the HID device classes on the upper edge and then something else to get the commands from your other program