Hello,
I am writing a small Windows based utility (using Eclipse/MinGW) which needs to request from a HID device the raw report descriptor. From my understanding, I will need to perform a GET_DESCRIPTOR(0x06) request from the devices's interface using a control transfer.
The request I want to make is essentially what I believe is the followng USB request;
SetupPacket:
0000: 81 06 00 22 00 00 60 00
In response I would like to get the raw HID report descriptor data which for this device is;
TransferBuffer: 0x00000020 (32) length
0000: 06 52 ff 09 01 a1 01 09 01 15 80 25 7f 95 40 75
0010: 08 81 02 09 01 15 80 25 7f 95 40 75 08 91 02 c0
In fact I see this transaction when Windows enumerates the device. What I want to do is to be able to make my own user-space request for the HID's raw report descriptor.
I have been able to accomplish this using libusb without problems. For instance if I do the following this gives me the results I want;
// Get report descriptor from USB control channel
ret = usb_control_msg(hdev, USB_ENDPOINT_IN | USB_TYPE_STANDARD
| USB_RECIP_INTERFACE, USB_REQ_GET_DESCRIPTOR,
(USB_DT_REPORT << 8), iInterface, pHidReptDesc, HidReptDescLen,
timeout);
However I do not want to be tied down to having to install the filter driver (or require anyone to install it) to do so. So instead I am hoping to use the APIs available from the WinDDK.
The best information I have found on the WinDDK involves using the IOCTL_USB_USER_REQUEST and submitting a USBUSER_OP_SEND_RAW_COMMAND. However I am not able to get this code to work.
{
PUSB_SEND_RAW_COMMAND_PARAMETERS getDescriptor;
PUSBUSER_REQUEST_HEADER requestHeader;
BOOL success;
ULONG nBytes;
ULONG nBytesReturned;
UCHAR getDescriptorBuf[sizeof(USBUSER_REQUEST_HEADER)
+ sizeof(USB_SEND_RAW_COMMAND_PARAMETERS) + 0x80];
nBytes = sizeof(getDescriptorBuf);
requestHeader = (PUSBUSER_REQUEST_HEADER) getDescriptorBuf;
getDescriptor = (PUSB_SEND_RAW_COMMAND_PARAMETERS) (requestHeader + 1);
memset(requestHeader, 0, nBytes);
requestHeader->UsbUserRequest = USBUSER_OP_SEND_RAW_COMMAND;
requestHeader->RequestBufferLength = nBytes;
getDescriptor->Usb_bmRequest = 0x81;
getDescriptor->Usb_bRequest = 0x6; //GET_DESCRIPTOR;
getDescriptor->Usb_wVlaue = (USB_HID_REPORT_TYPE << 8) | 0;
getDescriptor->Usb_wIndex = 0;
getDescriptor->Usb_wLength = 0x80;
// Not sure how to set these...
getDescriptor->Timeout = 0;
getDescriptor->DataLength = 0;
getDescriptor->DeviceAddress = 0;
getDescriptor->MaximumPacketSize = 0;
getDescriptor->UsbdStatusCode = 0;
HexDump(stdout, NULL, getDescriptor, 8);
success = DeviceIoControl(hHCDevice, IOCTL_USB_USER_REQUEST, requestHeader,
nBytes, requestHeader, nBytes, &nBytesReturned, NULL);
if (!success)
{
DWORD osErr;
osErr = GetLastError();
Printf("USER_REQUEST: result=%d, lasterr=%08x\n", osErr, osErr);
}
HexDump(stdout, NULL, getDescriptorBuf, sizeof(getDescriptorBuf));
return success;
}
Although the call to DeviceIoControl() returns TRUE, I get nothing in return and I see nothing on the USBTrace analyzer.
I have also tried to use the IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION command but I have discovered that this forces the bmRequest field to 0x80, when I need 0x81.
Is there a better method to obtain a USB HID device's raw report descriptor?
Thanks in advance for any help you can offer.
Kevin
FYI, Below is some additional specific information about an example HID device I am trying to do this with.
Device Descriptor:
bcdUSB: 0x0200
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x40 (64)
idVendor: 0x22B8 (Motorola PCS)
idProduct: 0x08A0
bcdDevice: 0x3728
iManufacturer: 0x00
iProduct: 0x02
0x0409: "Motorola S9-HD"
iSerialNumber: 0x00
bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: Full
Device Address: 0x0D
Open Pipes: 1
Endpoint Descriptor:
bEndpointAddress: 0x81 IN
Transfer Type: Interrupt
wMaxPacketSize: 0x0010 (16)
bInterval: 0x01
Configuration Descriptor:
wTotalLength: 0x0022
bNumInterfaces: 0x01
bConfigurationValue: 0x01
iConfiguration: 0x00
bmAttributes: 0x80 (Bus Powered )
MaxPower: 0x64 (200 mA)
Interface Descriptor:
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x01
bInterfaceClass: 0x03 (HID)
bInterfaceSubClass: 0x00
bInterfaceProtocol: 0x00
iInterface: 0x00
HID Descriptor:
bcdHID: 0x0100
bCountryCode: 0x00
bNumDescriptors: 0x01
bDescriptorType: 0x22
wDescriptorLength: 0x0020
Endpoint Descriptor:
bEndpointAddress: 0x81 IN
Transfer Type: Interrupt
wMaxPacketSize: 0x0010 (16)
bInterval: 0x01