How do I create a virtual gamepad?

Dataflashsabot picture Dataflashsabot · Jul 29, 2012 · Viewed 28.5k times · Source

How would I go about creating a "gamepad" which appears to DirectInput applications as a normal game controller but the state of its controls is actually defined by software?

Answer

user257111 picture user257111 · Jul 29, 2012

Write a device driver to pretend to be one.

Specifically, Windows device drivers handle what are called Interrupt Requests via the Interrupt Request Protocol - which boils down to a wrapped up structure and a set of buffers internally in the driver.

Now the next thing you need to know is that many drivers are actually layered, or stacked, or whichever name you want to use. So for example to write a disk driver, you might interface with the driver above it (as a disk class) but use a driver below it (scsi port, for example) to actually send commands to your devices.

That's how real devices work. Fake devices need to conform to the top level interface requirements, e.g. a disk, or a controller, or a mouse, or whatever it is. However, underneath they can do anything they like - return whatever values they like.

This opens up the possibility of controlling a driver via a user-mode application and pretending to "be" a device. To send a driver messages, you can DeviceIoControl to it; then to actually get those messages you can either:

  • Stuff them in the Irp that makes up that DeviceIoControl.
  • Have the driver read them out of your process' memory space.

Drivers can also access \\Registry\\Machine and various other, non-user-specific non-explorer registry areas, so it is possible to communicate that way.

Finally, there's no saying you can't filter existing IO, rather than make it all up via a new device. There are a great many options and ways you can go about doing this.

If you're going to do this, you'll need:

  • VirtualKD or an expensive debugger cable and two PCs.
  • You probably also want to start with the references on this blog post. You'll find that there are essentially a bazillion different names for driver code, so I'll interpret some of them:

    • WDM = Windows Driver Model, basically the NT driver model mixed with (some of) Windows 9x.
    • KMDF = Kernel mode driver framework - drivers of the above type use this, plus additionally WDF (Windows Driver Foundation) which is a set of libraries on top of WDM to make it quicker to use.
    • UMDF = User mode driver framework - write a driver without the danger of kernel mode. If you can, use this, as kernel mode drivers that go wrong will bluescreen (in driver parlance, bugcheck) your system.

Edit: I'm not massively knowledgeable on DirectInput - there may be a way to override the various API controls in use via DLL redirection and the like, which may be simpler than the way I've described.