Hidclass joystick trouble

I’ve written a software-only hid minidriver that emulates a mouse. Works great.
I’ve figured that turning it into a joystick would be easy, but hidclass begs the differ.

I replaced the hid report descriptor of the mouse with a joystick report (both of which I got from usb.org’s hid descriptor tool), and expected for hidclass to identify my device as a joystick. But it didn’t.

After my driver gets ioctl’s for IOCTL_HID_GET_DEVICE_DESCRIPTOR and IOCTL_HID_GET_DEVICE_ATTRIBUTES, it gets IOCTL_HID_GET_REPORT_DESCRIPTOR. At this point my mouse driver returned the mouse report descriptor, and hidclass was ok with it and issued IOCTL_HID_READ_REPORT’s. But if I return the joystick descriptor, I get two more IOCTL_HID_GET_REPORT_DESCRIPTOR’s and then hidclass destroys my fdo. At the device manager, my device is listed under HIDs questionmarked, with code 10.

I thought that there was some problem with the report descriptor I got from hid desc tool, so I tried to replace it with a descriptor from a physical (working) joystick. But I get the exact same problem.

Did you introduce a hid descriptor where you now need to handle report IDs (which IIRC are in the first byte of the data)

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Monday, September 21, 2009 12:26 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Hidclass joystick trouble

I’ve written a software-only hid minidriver that emulates a mouse. Works great.
I’ve figured that turning it into a joystick would be easy, but hidclass begs the differ.

I replaced the hid report descriptor of the mouse with a joystick report (both of which I got from usb.org’s hid descriptor tool), and expected for hidclass to identify my device as a joystick. But it didn’t.

After my driver gets ioctl’s for IOCTL_HID_GET_DEVICE_DESCRIPTOR and IOCTL_HID_GET_DEVICE_ATTRIBUTES, it gets IOCTL_HID_GET_REPORT_DESCRIPTOR. At this point my mouse driver returned the mouse report descriptor, and hidclass was ok with it and issued IOCTL_HID_READ_REPORT’s. But if I return the joystick descriptor, I get two more IOCTL_HID_GET_REPORT_DESCRIPTOR’s and then hidclass destroys my fdo. At the device manager, my device is listed under HIDs questionmarked, with code 10.

I thought that there was some problem with the report descriptor I got from hid desc tool, so I tried to replace it with a descriptor from a physical (working) joystick. But I get the exact same problem.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I don’t think so, since there is only a single type of input (and also output, in the real joystick desc) report. Anyway, the problem occurs at the report descriptor stage, before any reports are sent.

That’s desc tool’s descriptor:

USAGE_PAGE (Generic Desktop) 05 01
LOGICAL_MINIMUM (0) 15 00
USAGE (Joystick) 09 04
COLLECTION (Application) A1 01
USAGE_PAGE (Simulation Controls) 05 02
USAGE (Throttle) 09 BB
LOGICAL_MINIMUM (-127) 15 81
LOGICAL_MAXIMUM (127) 25 7F
REPORT_SIZE (8) 75 08
REPORT_COUNT (1) 95 01
INPUT (Data,Var,Abs) 81 02
USAGE_PAGE (Generic Desktop) 05 01
USAGE (Pointer) 09 01
COLLECTION (Physical) A1 00
USAGE (X) 09 30
USAGE (Y) 09 31
REPORT_COUNT (2) 95 02
INPUT (Data,Var,Abs) 81 02
END_COLLECTION C0
USAGE (Hat switch) 09 39
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (3) 25 03
PHYSICAL_MINIMUM (0) 35 00
PHYSICAL_MAXIMUM (270) 46 0E 01
UNIT (Eng Rot:Angular Pos) 65 14
REPORT_SIZE (4) 75 04
REPORT_COUNT (1) 95 01
INPUT (Data,Var,Abs) 81 02
USAGE_PAGE (Button) 05 09
USAGE_MINIMUM (Button 1) 19 01
USAGE_MAXIMUM (Button 4) 29 04
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (1) 25 01
REPORT_SIZE (1) 75 01
REPORT_COUNT (4) 95 04
UNIT_EXPONENT (0) 55 00
UNIT (None) 65 00
INPUT (Data,Var,Abs) 81 02
END_COLLECTION C0

This is the real joystick’s desc:

Usage Page (Generic Desktop) 05 01
Usage (Joystick) 09 04
Collection (Application) A1 01
Collection (Logical) A1 02
Report Size (8) 75 08
Report Count (5) 95 05
Logical Minimum (0) 15 00
Logical Maximum (255) 26 FF 00
Physical Minimum (0) 35 00
Physical Maximum (255) 46 FF 00
Usage (X) 09 30
Usage (Y) 09 31
Usage (Z) 09 32
Usage (Z) 09 32
Usage (Rz) 09 35
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Report Size (4) 75 04
Report Count (1) 95 01
Logical Maximum (7) 25 07
Physical Maximum (315) 46 3B 01
Unit (Eng Rot: Degree) 65 14
Usage (Hat Switch) 09 39
Input (Data,Var,Abs,NWrp,Lin,Pref,Null,Bit) 81 42
Unit (None) 65 00
Report Size (1) 75 01
Report Count (12) 95 0C
Logical Maximum (1) 25 01
Physical Maximum (1) 45 01
Usage Page (Button) 05 09
Usage Minimum (Button 1) 19 01
Usage Maximum (Button 12) 29 0C
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Usage Page (Vendor-Defined 1) 06 00 FF
Report Size (1) 75 01
Report Count (8) 95 08
Logical Maximum (1) 25 01
Physical Maximum (1) 45 01
Usage (Vendor-Defined 1) 09 01
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
End Collection C0
Collection (Logical) A1 02
Report Size (8) 75 08
Report Count (7) 95 07
Physical Maximum (255) 46 FF 00
Logical Maximum (255) 26 FF 00
Usage (Vendor-Defined 2) 09 02
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
End Collection C0
End Collection C0

Quickly reading through the hidclass docs, physical descriptors are not supported, only report descriptors. As to why you are getting 2 more IOCTL_HID_GET_REPORT_DESCRIPTOR, I don’t know. I would suggest you capture the call stack on the last 2 calls to see if they are any different than the first.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Monday, September 21, 2009 1:55 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Hidclass joystick trouble

I don’t think so, since there is only a single type of input (and also output, in the real joystick desc) report. Anyway, the problem occurs at the report descriptor stage, before any reports are sent.

That’s desc tool’s descriptor:

USAGE_PAGE (Generic Desktop) 05 01
LOGICAL_MINIMUM (0) 15 00
USAGE (Joystick) 09 04
COLLECTION (Application) A1 01
USAGE_PAGE (Simulation Controls) 05 02
USAGE (Throttle) 09 BB
LOGICAL_MINIMUM (-127) 15 81
LOGICAL_MAXIMUM (127) 25 7F
REPORT_SIZE (8) 75 08
REPORT_COUNT (1) 95 01
INPUT (Data,Var,Abs) 81 02
USAGE_PAGE (Generic Desktop) 05 01
USAGE (Pointer) 09 01
COLLECTION (Physical) A1 00
USAGE (X) 09 30
USAGE (Y) 09 31
REPORT_COUNT (2) 95 02
INPUT (Data,Var,Abs) 81 02
END_COLLECTION C0
USAGE (Hat switch) 09 39
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (3) 25 03
PHYSICAL_MINIMUM (0) 35 00
PHYSICAL_MAXIMUM (270) 46 0E 01
UNIT (Eng Rot:Angular Pos) 65 14
REPORT_SIZE (4) 75 04
REPORT_COUNT (1) 95 01
INPUT (Data,Var,Abs) 81 02
USAGE_PAGE (Button) 05 09
USAGE_MINIMUM (Button 1) 19 01
USAGE_MAXIMUM (Button 4) 29 04
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (1) 25 01
REPORT_SIZE (1) 75 01
REPORT_COUNT (4) 95 04
UNIT_EXPONENT (0) 55 00
UNIT (None) 65 00
INPUT (Data,Var,Abs) 81 02
END_COLLECTION C0

This is the real joystick’s desc:

Usage Page (Generic Desktop) 05 01
Usage (Joystick) 09 04
Collection (Application) A1 01
Collection (Logical) A1 02
Report Size (8) 75 08
Report Count (5) 95 05
Logical Minimum (0) 15 00
Logical Maximum (255) 26 FF 00
Physical Minimum (0) 35 00
Physical Maximum (255) 46 FF 00
Usage (X) 09 30
Usage (Y) 09 31
Usage (Z) 09 32
Usage (Z) 09 32
Usage (Rz) 09 35
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Report Size (4) 75 04
Report Count (1) 95 01
Logical Maximum (7) 25 07
Physical Maximum (315) 46 3B 01
Unit (Eng Rot: Degree) 65 14
Usage (Hat Switch) 09 39
Input (Data,Var,Abs,NWrp,Lin,Pref,Null,Bit) 81 42
Unit (None) 65 00
Report Size (1) 75 01
Report Count (12) 95 0C
Logical Maximum (1) 25 01
Physical Maximum (1) 45 01
Usage Page (Button) 05 09
Usage Minimum (Button 1) 19 01
Usage Maximum (Button 12) 29 0C
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Usage Page (Vendor-Defined 1) 06 00 FF
Report Size (1) 75 01
Report Count (8) 95 08
Logical Maximum (1) 25 01
Physical Maximum (1) 45 01
Usage (Vendor-Defined 1) 09 01
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
End Collection C0
Collection (Logical) A1 02
Report Size (8) 75 08
Report Count (7) 95 07
Physical Maximum (255) 46 FF 00
Logical Maximum (255) 26 FF 00
Usage (Vendor-Defined 2) 09 02
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
End Collection C0
End Collection C0


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Note that the real joystick’s descriptor doesn’t have any physical collections, but logical (assuming that what you meant by physical descriptors), and still fails the same way. Also, the mouse descriptor I used has a physical collection in it, yet it works.

Stack trace for all three READ_REPORTs is identical:

f8af9868 b1f05072 hidtest!HIDTest_EvtIoInternalDeviceControl(
struct WDFQUEUE__ * Queue = 0x7dcc37f8,
struct WDFREQUEST__ * Request = 0x7df2ec28,
unsigned int OutputBufferLength = 0x65,
unsigned int InputBufferLength = 0,
unsigned long IoControlCode = 0xb0007)+0x208
[…]
f8af988c b1f06432 wdf01000!FxIoQueueIoInternalDeviceControl::Invoke+0x30
f8af98bc b1f089ac wdf01000!FxIoQueue::DispatchRequestToDriver+0x37f
f8af98d8 b1f09a36 wdf01000!FxIoQueue::DispatchEvents+0x3be
f8af98f8 b1f0b824 wdf01000!FxIoQueue::QueueRequest+0x1ec
f8af991c b1efaa3f wdf01000!FxPkgIo::Dispatch+0x27d
f8af9928 804eeeb1 wdf01000!FxDevice::Dispatch+0x7f
f8af9938 f8bde4b0 nt!IopfCallDriver+0x31
WARNING: Stack unwind information not available. Following frames may be wrong.
f8af9940 f887ae91 hidkmdf+0x4b0
f8af9954 f887fb17 HIDCLASS!HidpCallDriver+0x3f
f8af997c f887c8b5 HIDCLASS!HidpCallDriverSynchronous+0x3b
f8af99a0 f888041f HIDCLASS!GetHIDRawReportDescriptor+0x55
f8af99c0 f88812f3 HIDCLASS!HidpGetDeviceDescriptor+0x8b
f8af99d8 f888178e HIDCLASS!AllocDeviceResources+0x11
f8af99f4 f887ff25 HIDCLASS!HidpStartDevice+0x72
f8af9a10 f8880076 HIDCLASS!HidpFdoPnp+0x7b
f8af9a20 f887b92b HIDCLASS!HidpIrpMajorPnp+0x1e
f8af9a30 804eeeb1 HIDCLASS!HidpMajorHandler+0x79
f8af9a40 80591823 nt!IopfCallDriver+0x31
f8af9a6c 805918a1 nt!IopSynchronousCall+0xb7

I’d guess that hidclass tries to read the descriptor several times (maybe the descriptor got scarmbled on it’s way from the hardware?) before it gives up on it.
Anyway, there has to be something more to it, since this particular descriptor works for the real joystick.

Stack trace for the fdo’s destruction reveals nothing (HIDCLASS!HidpCallDriver+0x3f, and then it’s wdf all the way up).

You could debug right after the return to HIDCLASS!HidpCallDriver+0x3f (put a bp on the ret address) and see what it does not like about your descriptor

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Monday, September 21, 2009 3:51 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Hidclass joystick trouble

Note that the real joystick’s descriptor doesn’t have any physical collections, but logical (assuming that what you meant by physical descriptors), and still fails the same way. Also, the mouse descriptor I used has a physical collection in it, yet it works.

Stack trace for all three READ_REPORTs is identical:

f8af9868 b1f05072 hidtest!HIDTest_EvtIoInternalDeviceControl(
struct WDFQUEUE__ * Queue = 0x7dcc37f8,
struct WDFREQUEST__ * Request = 0x7df2ec28,
unsigned int OutputBufferLength = 0x65,
unsigned int InputBufferLength = 0,
unsigned long IoControlCode = 0xb0007)+0x208 […] f8af988c b1f06432 wdf01000!FxIoQueueIoInternalDeviceControl::Invoke+0x30
f8af98bc b1f089ac wdf01000!FxIoQueue::DispatchRequestToDriver+0x37f
f8af98d8 b1f09a36 wdf01000!FxIoQueue::DispatchEvents+0x3be
f8af98f8 b1f0b824 wdf01000!FxIoQueue::QueueRequest+0x1ec
f8af991c b1efaa3f wdf01000!FxPkgIo::Dispatch+0x27d
f8af9928 804eeeb1 wdf01000!FxDevice::Dispatch+0x7f
f8af9938 f8bde4b0 nt!IopfCallDriver+0x31
WARNING: Stack unwind information not available. Following frames may be wrong.
f8af9940 f887ae91 hidkmdf+0x4b0
f8af9954 f887fb17 HIDCLASS!HidpCallDriver+0x3f f8af997c f887c8b5 HIDCLASS!HidpCallDriverSynchronous+0x3b
f8af99a0 f888041f HIDCLASS!GetHIDRawReportDescriptor+0x55
f8af99c0 f88812f3 HIDCLASS!HidpGetDeviceDescriptor+0x8b
f8af99d8 f888178e HIDCLASS!AllocDeviceResources+0x11
f8af99f4 f887ff25 HIDCLASS!HidpStartDevice+0x72 f8af9a10 f8880076 HIDCLASS!HidpFdoPnp+0x7b f8af9a20 f887b92b HIDCLASS!HidpIrpMajorPnp+0x1e f8af9a30 804eeeb1 HIDCLASS!HidpMajorHandler+0x79 f8af9a40 80591823 nt!IopfCallDriver+0x31 f8af9a6c 805918a1 nt!IopSynchronousCall+0xb7

I’d guess that hidclass tries to read the descriptor several times (maybe the descriptor got scarmbled on it’s way from the hardware?) before it gives up on it.
Anyway, there has to be something more to it, since this particular descriptor works for the real joystick.

Stack trace for the fdo’s destruction reveals nothing (HIDCLASS!HidpCallDriver+0x3f, and then it’s wdf all the way up).


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I would also put a chk hidclass on the machine. I see now that this not a physical descriptor issue , you are past that check already. GetHIDRawReportDescriptor does have a loop where it tries twice to retrieve the report descriptor. Assuming you are returning success, it is checking that the IoStatus.Information field in the IRP matches the wReportLength given in your HID descriptor as returned by IOCTL_HID_GET_DEVICE_DESCRIPTOR

d

-----Original Message-----
From: Doron Holan
Sent: Monday, September 21, 2009 4:00 PM
To: Windows System Software Devs Interest List
Subject: RE: RE:[ntdev] Hidclass joystick trouble

You could debug right after the return to HIDCLASS!HidpCallDriver+0x3f (put a bp on the ret address) and see what it does not like about your descriptor

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Monday, September 21, 2009 3:51 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Hidclass joystick trouble

Note that the real joystick’s descriptor doesn’t have any physical collections, but logical (assuming that what you meant by physical descriptors), and still fails the same way. Also, the mouse descriptor I used has a physical collection in it, yet it works.

Stack trace for all three READ_REPORTs is identical:

f8af9868 b1f05072 hidtest!HIDTest_EvtIoInternalDeviceControl(
struct WDFQUEUE__ * Queue = 0x7dcc37f8,
struct WDFREQUEST__ * Request = 0x7df2ec28,
unsigned int OutputBufferLength = 0x65,
unsigned int InputBufferLength = 0,
unsigned long IoControlCode = 0xb0007)+0x208 […] f8af988c b1f06432 wdf01000!FxIoQueueIoInternalDeviceControl::Invoke+0x30
f8af98bc b1f089ac wdf01000!FxIoQueue::DispatchRequestToDriver+0x37f
f8af98d8 b1f09a36 wdf01000!FxIoQueue::DispatchEvents+0x3be
f8af98f8 b1f0b824 wdf01000!FxIoQueue::QueueRequest+0x1ec
f8af991c b1efaa3f wdf01000!FxPkgIo::Dispatch+0x27d
f8af9928 804eeeb1 wdf01000!FxDevice::Dispatch+0x7f
f8af9938 f8bde4b0 nt!IopfCallDriver+0x31
WARNING: Stack unwind information not available. Following frames may be wrong.
f8af9940 f887ae91 hidkmdf+0x4b0
f8af9954 f887fb17 HIDCLASS!HidpCallDriver+0x3f f8af997c f887c8b5 HIDCLASS!HidpCallDriverSynchronous+0x3b
f8af99a0 f888041f HIDCLASS!GetHIDRawReportDescriptor+0x55
f8af99c0 f88812f3 HIDCLASS!HidpGetDeviceDescriptor+0x8b
f8af99d8 f888178e HIDCLASS!AllocDeviceResources+0x11
f8af99f4 f887ff25 HIDCLASS!HidpStartDevice+0x72 f8af9a10 f8880076 HIDCLASS!HidpFdoPnp+0x7b f8af9a20 f887b92b HIDCLASS!HidpIrpMajorPnp+0x1e f8af9a30 804eeeb1 HIDCLASS!HidpMajorHandler+0x79 f8af9a40 80591823 nt!IopfCallDriver+0x31 f8af9a6c 805918a1 nt!IopSynchronousCall+0xb7

I’d guess that hidclass tries to read the descriptor several times (maybe the descriptor got scarmbled on it’s way from the hardware?) before it gives up on it.
Anyway, there has to be something more to it, since this particular descriptor works for the real joystick.

Stack trace for the fdo’s destruction reveals nothing (HIDCLASS!HidpCallDriver+0x3f, and then it’s wdf all the way up).


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Ok, I got it.
Turns out that the whole thing was a very stupid bug. I returned the gamepad secriptor, but forgot to change the returned length upon completion :stuck_out_tongue:

Thanks for all your help