Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windows: try to get USB device serial number if not provided by HidD_GetSerialNumberString #464

Merged
merged 3 commits into from
Mar 13, 2023

Conversation

DJm00n
Copy link
Contributor

@DJm00n DJm00n commented Oct 15, 2022

This is efficient for Xbox Common Controller class (XUSB) devices like Xbox 360 or Xbox One controllers that are missing serial number via usual HID API.

Before:

Device Found
  type: 045e 02ff
  path: \\?\HID#VID_045E&PID_02FF&IG_00#7&1912990&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number:
  Manufacturer:
  Product:      Controller (Xbox One For Windows)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1
  
Device Found
  type: 045e 02ff
  path: \\?\HID#VID_045E&PID_02FF&IG_00#7&f6ef908&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number:
  Manufacturer:
  Product:      Controller (Xbox One For Windows)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1

Device Found
  type: 045e 028e
  path: \\?\HID#VID_045E&PID_028E&IG_00#7&176b3b07&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number:
  Manufacturer:
  Product:      Controller (XBOX 360 For Windows)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1
  
Device Found
  type: 1949 041a
  path: \\?\HID#VID_1949&PID_041A&IG_03#8&3373dab9&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number:
  Manufacturer:
  Product:      Controller (Amazon Game Controller)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1

Device Found
  type: 045e 02a1
  path: \\?\HID#VID_045E&PID_02A1&IG_04#7&21ec0f93&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number:
  Manufacturer:
  Product:      Controller (Xbox 360 Wireless Receiver for Windows)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1

After:

Device Found
  type: 045e 02ff
  path: \\?\HID#VID_045E&PID_02FF&IG_00#7&1912990&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number: 7EED86C35B04
  Manufacturer:
  Product:      Controller (Xbox One For Windows)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1

Device Found
  type: 045e 02ff
  path: \\?\HID#VID_045E&PID_02FF&IG_00#7&f6ef908&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number: 3032363330303437373233303433
  Manufacturer:
  Product:      Controller (Xbox One For Windows)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1

Device Found
  type: 045e 028e
  path: \\?\HID#VID_045E&PID_028E&IG_00#7&176b3b07&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number: 04B229A
  Manufacturer:
  Product:      Controller (XBOX 360 For Windows)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1

Device Found
  type: 1949 041a
  path: \\?\HID#VID_1949&PID_041A&IG_03#8&3373dab9&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number: G0G159090273003V
  Manufacturer:
  Product:      Controller (Amazon Game Controller)
  Release:      0
  Interface:    0
  Usage (page): 0x5 (0x1)
  Bus type: 1

Device Found
  type: 045e 02a1
  path: \\?\HID#VID_045E&PID_02A1&IG_04#7&21ec0f93&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  serial_number: E1A03E30
  Manufacturer:
  Product:      Controller (Xbox 360 Wireless Receiver for Windows)
  Release:      0
  Interface:    -1
  Usage (page): 0x5 (0x1)
  Bus type: 1

@Youw
Copy link
Member

Youw commented Oct 15, 2022

This looks good on a first glance, thanks.
I'd like to check closer before merging it. Hopefully somewhere this week.

windows/hid.c Outdated Show resolved Hide resolved
windows/hid.c Outdated Show resolved Hide resolved
windows/hid.c Outdated Show resolved Hide resolved
windows/hid.c Show resolved Hide resolved
windows/hid.c Outdated
https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers
https://docs.microsoft.com/windows-hardware/drivers/usbcon/enumeration-of-interfaces-not-grouped-in-collections
*/
dev->interface_number = hid_internal_extract_int_token_value(hardware_id, L"MI_");
Copy link
Member

@Youw Youw Oct 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a game controller that has only one interface and &MI_ is not present in none of its HardwareIDs.
At the end we end-up setting interface_number to -1 for that device.
Do you think we could add euristic to default it to 0 for devices with only one interface?
I didn't give it enough thought as of how to do so correctly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My device:

        +++++++++++++++++ Device Information ++++++++++++++++++
Device Description       : Xbox 360 Controller for Windows
Device Path 1            : \\?\USB#VID_045E&PID_028E#6&328b81da&1&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed} (GUID_DEVINTERFACE_USB_DEVICE)
Device Path 2            : \\?\USB#VID_045E&PID_028E#6&328b81da&1&2#{ec87f1e3-c13b-4100-b5f7-8b84d54260cb}
Kernel Name              : \Device\USBPDO-9
Device ID                : USB\VID_045E&PID_028E\6&328B81DA&1&2
Hardware IDs             : USB\VID_045E&PID_028E&REV_2020 USB\VID_045E&PID_028E
Driver KeyName           : {d61ca365-5af4-4486-998b-9db4734c6ca3}\0001
Driver                   : \SystemRoot\System32\drivers\xusb22.sys (Version: 10.0.22000.653  Date: 2022-05-13)
Driver Inf               : C:\WINDOWS\inf\xusb22.inf
Legacy BusType           : PNPBus
Class                    : XnaComposite
Class GUID               : {d61ca365-5af4-4486-998b-9db4734c6ca3}
Service                  : xusb22
Enumerator               : USB
Location Info            : Port_#0002.Hub_#0008
Location IDs             : PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(10)#USB(2), ACPI(_SB_)#ACPI(PC00)#ACPI(XHCI)#ACPI(RHUB)#ACPI(HS10)#USB(2)
Container ID             : {d12ad581-3b3d-11ed-9df4-40b076a530b2}
Manufacturer Info        : Microsoft
Capabilities             : 0x84 (Removable, SurpriseRemovalOK)
Status                   : 0x0180600A (DN_DRIVER_LOADED, DN_STARTED, DN_DISABLEABLE, DN_REMOVABLE, DN_NT_ENUMERATOR, DN_NT_DRIVER)
Problem Code             : 0
HcDisableSelectiveSuspend: 0
EnableSelectiveSuspend   : 0
SelectiveSuspendEnabled  : 0
EnhancedPowerMgmtEnabled : 0
IdleInWorkingState       : 0
WakeFromSleepState       : 0
Power State              : D0 (supported: D0, D2, D3, wake from D0, wake from D2)
 Child Device 1          : USB Input Device
  Device ID              : USB\VID_045E&PID_028E&IG_00\7&C002879&0&00
  Class                  : HIDClass
  Driver KeyName         : {745a17a0-74d3-11d0-b6fe-00a0c90f57da}\0124 (GUID_DEVCLASS_HIDCLASS)
  Service                : HidUsb
  Location               : XBOX_360_DEVICE_00:00
   Child Device 1        : HID-compliant game controller
    Device Path          : \\?\HID#VID_045E&PID_028E&IG_00#8&3e51efe&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} (GUID_DEVINTERFACE_HID)
    Kernel Name          : \Device\00000156
    Device ID            : HID\VID_045E&PID_028E&IG_00\8&3E51EFE&0&0000
    Class                : HIDClass
    Driver KeyName       : {745a17a0-74d3-11d0-b6fe-00a0c90f57da}\0125 (GUID_DEVCLASS_HIDCLASS)

    ---------------------- Device Descriptor ----------------------
bLength                  : 0x12 (18 bytes)
bDescriptorType          : 0x01 (Device Descriptor)
bcdUSB                   : 0x200 (USB Version 2.0) -> but device is Full-Speed only
bDeviceClass             : 0xFF (Vendor Specific)
bDeviceSubClass          : 0xFF
bDeviceProtocol          : 0xFF
bMaxPacketSize0          : 0x08 (8 bytes)
idVendor                 : 0x045E (Microsoft Corporation)
idProduct                : 0x028E
bcdDevice                : 0x2020
iManufacturer            : 0x01 (String Descriptor 1)
 *!*ERROR  String descriptor not found
iProduct                 : 0x02 (String Descriptor 2)
 Language 0x0409         : "XEOX Gamepad"
iSerialNumber            : 0x03 (String Descriptor 3)
 *!*ERROR  String descriptor not found
bNumConfigurations       : 0x01 (1 Configuration)
Data (HexDump)           : 12 01 00 02 FF FF FF 08 5E 04 8E 02 20 20 01 02   ........^...  ..
                           03 01    

Copy link
Contributor Author

@DJm00n DJm00n Nov 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Device ID : USB\VID_045E&PID_028E&IG_00\7&C002879&0&00
iSerialNumber : 0x03 (String Descriptor 3)
*!*ERROR String descriptor not found

Seems this device haven't reported proper serial number it its iSerialNumber string descriptor.

Copy link
Contributor Author

@DJm00n DJm00n Nov 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a game controller that has only one interface and &MI_ is not present in none of its HardwareIDs. At the end we end-up setting interface_number to -1 for that device. Do you think we could add euristic to default it to 0 for devices with only one interface? I didn't give it enough thought as of how to do so correctly.

I think we should set interface_number to 0 for single-interface USB devices since this value is reported in its USB_INTERFACE_DESCRIPTOR.bInterfaceNumber in this case. This way we'll be consistent for all kinds of USB devices.

I'll update this PR a bit later with these corrections.

@mcuee mcuee added the Windows Related to Windows backend label Oct 28, 2022
@mcuee
Copy link
Member

mcuee commented Jan 26, 2023

I do not have a proper device to carry out the tests, at least it does not cause regressions.

@Youw
Copy link
Member

Youw commented Jan 26, 2023

at least it does not cause regressions

There is one:

interface_number is not set to -1 for non-USB devices anymore


this -1 value is not documented properly in hidapi.h

right, we better fix that

windows/hid.c Show resolved Hide resolved
@DJm00n DJm00n requested a review from Youw January 27, 2023 11:33
windows/hid.c Show resolved Hide resolved
windows/hid.c Outdated Show resolved Hide resolved
@DJm00n
Copy link
Contributor Author

DJm00n commented Feb 8, 2023

Hm. I have found DEVPKEY_Device_UINumber property. Maybe I can use it and Instance ID parsing wouldn't be needed. Need to check it.

@Youw
Copy link
Member

Youw commented Feb 22, 2023

@DJm00n I'm a bit lost in where our conversation ended.
Let me know - do you suggest having this merged as is, or should I wait for more of your changes.

@Youw
Copy link
Member

Youw commented Mar 13, 2023

Dang, so now there is a conflict, because of the last change.

…if not provided by HidD_GetSerialNumberString/HidD_GetManufacturerString.

This is efficient for Xbox Common Controller class (XUSB) devices like Xbox 360 or Xbox One controllers that are missing serial number and manufacturer string via usual HID APIs.
@DJm00n
Copy link
Contributor Author

DJm00n commented Mar 13, 2023

@Youw rebased PR

@DJm00n DJm00n requested a review from Youw March 13, 2023 21:46
hidapi/hidapi.h Outdated Show resolved Hide resolved
@Youw Youw merged commit bd6be4d into libusb:master Mar 13, 2023
@Youw
Copy link
Member

Youw commented Mar 13, 2023

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Windows Related to Windows backend
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants