Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Support WinUSB in Device Firmware

Tags:

c

windows

winusb

I'm trying to set up a USB device to automatically use WinUSB as the driver when it is connected to a Windows 8 machine, as outlined here.

It says:

In order for the USB driver stack to know that the device supports extended feature descriptors, the device must define an OS string descriptor that is stored at string index 0xEE.

Which I take to mean that I need to create a struct containing the descriptor at memory location 0xEE. How would I go about that in C?

Here's what I tried:

// The struct definition
typedef struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t qwSignature[14];
    uint8_t bMS_VendorCode;
    uint8_t bPad;
} usb_os_str_desc_t;

// Create a pointer to a struct located at 0xEE
volatile usb_os_str_desc_t* const extended_feature_support = (usb_os_str_desc_t*) 0xEE;

// Create a new struct at the location specified in "extended_feature_support"
(*extended_feature_support) = {
    .bLength = 0x12,
    .bDescriptorType = 0x03,
    .qwSignature = "MSFT100",
    .bMS_VendorCode = 0x04,
    .bPad = 0x00
};

But the compiler doesn't like this, complaining that the data definition has no type. Is there a way to do this in C? Am I understanding the article correctly?

Any help would be apprciated.

like image 722
Jeremy Sigrist Avatar asked Jul 16 '13 00:07

Jeremy Sigrist


1 Answers

That isn't what it is saying at all. You have to respond to USB requests, not place structures in specific locations of the embedded system's memory.

Windows will, upon seeing a VID:PID:Serial for the first time, request the OS String Descriptor at index 0xee. The device must respond with a data packet matching the structure format you showed. If everything in the returned descriptor is right (your example looks good), Windows will then issue a device vendor request with bReq set to what you provided in the string descriptor response as MS_VendorCode (0x04 in your example).

If your device responds with the correct OS Feature Descriptor, then magic happens. The magic that people usually want is for their device to use the winusb driver without providing an .inf file.

Note that this request only happens once. If you're developing a device you usually want to do this many, many times. To do that, you must uninstall the device from device manager, and then in regedit, look for your VIDPIDRELEASE under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\usbflags and delete it. Now when you plug your device in again it will perform this OS String Descriptor request again.

Please refer to https://github.com/pbatard/libwdi/wiki/WCID-Devices for more information, it's a lot clearer than the MS provided docs.

like image 178
akohlsmith Avatar answered Oct 16 '22 21:10

akohlsmith