Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Roll My Own Windows Joystick HID Driver?

Tags:

usb

hid

joystick

I have a USB Joystick, and I want to write my own HID driver for it. Notably I want to inject delay between when the joystick input is received by Windows and when my application is notified of that input event. I would also like to change the identity of the joystick percieved by my application. I have never written a driver, let alone an HID driver, for Windows. Can anyone provide me with advice or pointers on how to go about doing this?

like image 405
vicatcu Avatar asked Jun 24 '10 02:06

vicatcu


4 Answers

When you press knobs on the Joystick the electric signals reach the operating system (and onto the game) in the form of IRP's through the drivers chain. Intercepting these IRP's at some point and delaying the forwarding to the next driver can delay the joystick input. This can be achieved with driver filters.

To write windows drivers you need to use WinDDK.

The entrypoint of a windows driver is the DriverEntry function. In this function you will be hooking what IRP's you want to intercept and the callback functions that deal with them, in our case, the callback functions that delay the forwarding.

For example, say our IRP to be delayed is IRP_MJ_READ and our callback function is called CallbackDelayForwarding:

// the function that delays the IRP
NTSTATUS CallbackDelayForwarding(
    IN PDEVICE_OBJECT pDeviceObject, 
    IN PIRP pIrp
){
    // delay the forwarding
}

// this is the driver entrypoint, similar to "main" in user-mode executables
NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT pDriverObject, 
    IN PUNICODE_STRING RegistryPath 
){
    pDriverObject->MajorFunction[IRP_MJ_READ] = CallbackDelayForwarding;
    ...
}

To delay the forwarding inside CallbackDelayForwarding, you must use functions from the KeInitializeTimer family to simulate some sort of sleep (maybe in conjunction with locks), KeDelayExecutionThread etc.

To install your filter driver in the joystick driver chain, you can use .inf files.

Check the toaster filter driver sample in the WinDDK, you can find it at INSTALL_DIR/src/general/toaster/ see also here.

Related links:
http://www.rootkit.com/newsread.php?newsid=187
http://www.techtalkz.com/microsoft-device-drivers/269654-toaster-filter-driver.html

like image 195
clyfe Avatar answered Nov 11 '22 09:11

clyfe


What you are trying to do is a filter driver.

Filter drivers are optional drivers that add value to or modify the behavior of a device. A filter driver can service one or more devices. source: http://msdn.microsoft.com/en-us/library/ff545890.aspx

I think the WDK contains samples You ould have to download the Windows Driver Kit from here: http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx

The WDK probably contains a sample code to create a filter.

There is also the following download on microsoft's site : http://support.microsoft.com/kb/176417

It is probably a little bit outdated since USB was not supported pre-NT5.0, but maybe it is still relevant.

like image 39
David Avatar answered Nov 11 '22 08:11

David


You might want to use Autohotkey. This is a script language for windows which can remap every keys of mouse/keyboard/joysticks. If you capture the key through a script and insert a delay before sending the right key/macro to the active application, you might have a part of a solution to your problem.

like image 2
Jul Avatar answered Nov 11 '22 08:11

Jul


I was under the impression you could use <dinput.h>

joySetCapture(wnd, JOYSTICKID1) or joySetCapture(wnd,JOYSTICKID2)

then Joystick events would fire WM_JOYMOVE events, though what the wParam and lParam for the message would be I have no idea.

Then when your program closes or you no longer want joyReleaseCapture(JOYSTICKID1) etc.
it could just be empty params which then tell you to use joyGetPos or joyGetPosEx functions to find the data for yourself from the USB device.

like image 1
Spadge Avatar answered Nov 11 '22 07:11

Spadge