Changing hid report descriptor kills filter completion

I’ve been working a couple of months already to create some filters for a HID joystick device.
It’s taken me a lot of trial and error to get to where I’m at now, and the list and google have been of great help already but now I’m stuck.

I’m trying to enhance the joystick by adding extra buttons which I’ll fill in programmatically based on some rules.
I started by writing an upper filter for the HID enumerated PDO (HID.… device) which swaps around buttons / adds extra buttons on press of another, etc…
This works by changing the buffers in the read completion method.
When testing the joystick in the “Set up up USB game controllers”, everything works perfectly.

Now I wanted to add some buttons to the device. I’m doing this by adding a lower filter below hidusb to filter URBs (on the USB.… device).
I add a completion routine to the IOCTL URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE and modify the HID report descriptor.
The original descriptor looks like:
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x15, 0x81, // Logical Minimum (129)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x0F, // Usage Maximum (0x0F)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x10, // Report Count (16)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0 // End Collection

This device has 15 buttons (and 16 reports???, which I don’t understand, but I guess this is to align on 8 bytes)
I’m modifying the buttons Usage Maximum to 0x20 and the Report Count to 0x20 which should give me 32 buttons.

When I install the filter driver, Windows show me a joystick device with 32 buttons in the “Set up up USB game controllers”.
The only problem is that no button presses show up. I’ve also noticed that my completion routine in the upper filter driver isn’t called.
Only when I disconnect the device, the completion method is called. (I guess to clean up whatever is still open)

I’ve checked the buffer size of the request in the upper filter, which is 7. I’m guessing this is 6 bytes for my report (1byte X, 1byte Y, 32 bits for buttons) and 1 byte for a report ID. (without the lower filter installed, this is 5 bytes (only 16 bits for buttons))

The lower filter still shows the completion method being called and has 6 bytes in the result buffer. (no report ID here? Does hidusb or hidclass add the report id automatically?)

I guess what I’m asking is:
-Can I just change the number of buttons?
-Do I need to intercept / modify something else?
-How can I further debug this?

Quick follow up: I’ve used the !irp command for the irp that’s in the hid request, and it seems to be stuck at hidusb

0: kd> !irp 0xffffcf80`d7f1a870
Irp is active with 23 stacks 22 is current (= 0xffffcf80d7f1af28)
Mdl=ffffe0007c0a14b0: No System Buffer: Thread ffffe0007efc0080: Irp stack trace.
cmd flg cl Device File Completion-Context

[3, 0] 0 e1 ffffe0007c0cb060 ffffe0007c0e3f20 00000000-00000000 pending
\Driver\HidUsb
Args: 00000007 00000000 00000000 00000000
[3, 0] 0 1 ffffe0007e39d410 ffffe0007c0e3f20 00000000-00000000 pending
\Driver\joyhidfilter
Args: 00000007 00000000 00000000 00000000

Is it waiting for enough data to be returned from the device?
Because the device only returns 4 bytes, I’ve added 2 extra by modifying the report descriptor…
Do I now have to do anything special so that hidusb has enough data?

In my lower filter (below hidusb) I can see that the buffer length is 6 bytes, and I use WdfRequestCompleteWithInformation to set information to 6.

Apparently, hidusb is still not satisfied…

Apparently I’m just using this list to reflect on my own braindump…
I was looking at the wrong buffer in the lower filter. I’ve fixed it now by replacing the URB buffer with a new one that’s 6 bytes long and using WdfRequestCompleteWithInformation to set information to 6.
The HID upper filter driver now completes normally and everything works as expected…

Anyway, I would still like to thank the members of this list, as the amount of information available here was what helped me fix my problems :slight_smile: