Module: wine Branch: master Commit: a51af111ab2fa7d63be5cab60950880d0f88c785 URL: https://gitlab.winehq.org/wine/wine/-/commit/a51af111ab2fa7d63be5cab60950880...
Author: Ivo Ivanov logos128@gmail.com Date: Sat Aug 20 10:19:42 2022 +0300
wineusb.sys: Implement DevClass compatible id for devices with multiple interfaces.
Fixes also single interface devices not showing class, subclass, protocol of the first interface, which is the behavior on Windows.
---
dlls/wineusb.sys/unixlib.c | 25 ++++++++++++++++++++++--- dlls/wineusb.sys/unixlib.h | 2 +- dlls/wineusb.sys/wineusb.c | 20 +++++++++++++++----- 3 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/dlls/wineusb.sys/unixlib.c b/dlls/wineusb.sys/unixlib.c index f72686b5a78..406049d2fe3 100644 --- a/dlls/wineusb.sys/unixlib.c +++ b/dlls/wineusb.sys/unixlib.c @@ -143,10 +143,28 @@ static void add_usb_device(libusb_device *libusb_device) usb_event.u.added_device.subclass = device_desc.bDeviceSubClass; usb_event.u.added_device.protocol = device_desc.bDeviceProtocol; usb_event.u.added_device.interface = false; - queue_event(&usb_event); + usb_event.u.added_device.interface_index = -1;
if (!(ret = libusb_get_active_config_descriptor(libusb_device, &config_desc))) { + const struct libusb_interface *interface; + const struct libusb_interface_descriptor *iface_desc; + + if (config_desc->bNumInterfaces == 1) + { + interface = &config_desc->interface[0]; + if (interface->num_altsetting != 1) + FIXME("Interface 0 has %u alternate settings; using the first one.\n", + interface->num_altsetting); + iface_desc = &interface->altsetting[0]; + + usb_event.u.added_device.class = iface_desc->bInterfaceClass; + usb_event.u.added_device.subclass = iface_desc->bInterfaceSubClass; + usb_event.u.added_device.protocol = iface_desc->bInterfaceProtocol; + usb_event.u.added_device.interface_index = iface_desc->bInterfaceNumber; + } + queue_event(&usb_event); + /* Create new devices for interfaces of composite devices. * * On Windows this is the job of usbccgp.sys, a separate driver that @@ -163,10 +181,9 @@ static void add_usb_device(libusb_device *libusb_device)
for (i = 0; i < config_desc->bNumInterfaces; ++i) { - const struct libusb_interface *interface = &config_desc->interface[i]; - const struct libusb_interface_descriptor *iface_desc; struct unix_device *unix_iface;
+ interface = &config_desc->interface[i]; if (interface->num_altsetting != 1) FIXME("Interface %u has %u alternate settings; using the first one.\n", i, interface->num_altsetting); @@ -196,6 +213,8 @@ static void add_usb_device(libusb_device *libusb_device) } else { + queue_event(&usb_event); + ERR("Failed to get configuration descriptor: %s\n", libusb_strerror(ret)); } } diff --git a/dlls/wineusb.sys/unixlib.h b/dlls/wineusb.sys/unixlib.h index 3d27d3715c3..9941bd138ed 100644 --- a/dlls/wineusb.sys/unixlib.h +++ b/dlls/wineusb.sys/unixlib.h @@ -45,7 +45,7 @@ struct usb_event UINT16 vendor, product, revision; UINT8 class, subclass, protocol; bool interface; - UINT8 interface_index; + INT16 interface_index; } added_device; struct unix_device *removed_device; IRP *completed_irp; diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c index 05a9d81dcd6..5447fabacda 100644 --- a/dlls/wineusb.sys/wineusb.c +++ b/dlls/wineusb.sys/wineusb.c @@ -76,7 +76,7 @@ struct usb_device DEVICE_OBJECT *device_obj;
bool interface; - uint8_t interface_index; + int16_t interface_index;
uint8_t class, subclass, protocol;
@@ -377,10 +377,20 @@ static void get_hardware_ids(const struct usb_device *device, struct string_buff
static void get_compatible_ids(const struct usb_device *device, struct string_buffer *buffer) { - append_id(buffer, L"USB\Class_%02x&SubClass_%02x&Prot_%02x", - device->class, device->subclass, device->protocol); - append_id(buffer, L"USB\Class_%02x&SubClass_%02x", device->class, device->subclass); - append_id(buffer, L"USB\Class_%02x", device->class); + if (device->interface_index != -1) + { + append_id(buffer, L"USB\Class_%02x&SubClass_%02x&Prot_%02x", + device->class, device->subclass, device->protocol); + append_id(buffer, L"USB\Class_%02x&SubClass_%02x", device->class, device->subclass); + append_id(buffer, L"USB\Class_%02x", device->class); + } + else + { + append_id(buffer, L"USB\DevClass_%02x&SubClass_%02x&Prot_%02x", + device->class, device->subclass, device->protocol); + append_id(buffer, L"USB\DevClass_%02x&SubClass_%02x", device->class, device->subclass); + append_id(buffer, L"USB\DevClass_%02x", device->class); + } append_id(buffer, L""); }