[PATCH 0/3] MR1631: wineusb.sys: Implement DevClass compatible id for devices with multiple interfaces.
Also make the device instance id unique (at least to the bus), as required by MS. It is also easily addressable by other drivers. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/1631
From: Ivo Ivanov <logos128(a)gmail.com> --- dlls/wineusb.sys/wineusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c index 7848b31105e..7bc5958ebb4 100644 --- a/dlls/wineusb.sys/wineusb.c +++ b/dlls/wineusb.sys/wineusb.c @@ -127,6 +127,9 @@ static void add_unix_device(const struct usb_add_device_event *event) InitializeListHead(&device->irp_list); device->removed = FALSE; + device->interface = event->interface; + device->interface_index = event->interface_index; + device->class = event->class; device->subclass = event->subclass; device->protocol = event->protocol; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1631
From: Ivo Ivanov <logos128(a)gmail.com> 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 278750c37f6..e717106c3ff 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); @@ -194,6 +211,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 eee16c8fc2b..2b362abde6c 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 7bc5958ebb4..8e9fc45ab85 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""); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1631
From: Ivo Ivanov <logos128(a)gmail.com> Makes the device instance id unique (at least to the bus), as required by MS. It is also easily addressable by other drivers. --- dlls/wineusb.sys/unixlib.c | 3 +++ dlls/wineusb.sys/unixlib.h | 4 ++-- dlls/wineusb.sys/wineusb.c | 15 ++++++++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/dlls/wineusb.sys/unixlib.c b/dlls/wineusb.sys/unixlib.c index e717106c3ff..dc720759d89 100644 --- a/dlls/wineusb.sys/unixlib.c +++ b/dlls/wineusb.sys/unixlib.c @@ -139,9 +139,12 @@ static void add_usb_device(libusb_device *libusb_device) usb_event.u.added_device.vendor = device_desc.idVendor; usb_event.u.added_device.product = device_desc.idProduct; usb_event.u.added_device.revision = device_desc.bcdDevice; + usb_event.u.added_device.usbver = device_desc.bcdUSB; usb_event.u.added_device.class = device_desc.bDeviceClass; usb_event.u.added_device.subclass = device_desc.bDeviceSubClass; usb_event.u.added_device.protocol = device_desc.bDeviceProtocol; + usb_event.u.added_device.busnum = libusb_get_bus_number(libusb_device); + usb_event.u.added_device.portnum = libusb_get_port_number(libusb_device); usb_event.u.added_device.interface = false; usb_event.u.added_device.interface_index = -1; diff --git a/dlls/wineusb.sys/unixlib.h b/dlls/wineusb.sys/unixlib.h index 2b362abde6c..7c1fa337788 100644 --- a/dlls/wineusb.sys/unixlib.h +++ b/dlls/wineusb.sys/unixlib.h @@ -42,8 +42,8 @@ struct usb_event struct usb_add_device_event { struct unix_device *device; - UINT16 vendor, product, revision; - UINT8 class, subclass, protocol; + UINT16 vendor, product, revision, usbver; + UINT8 class, subclass, protocol, busnum, portnum; bool interface; INT16 interface_index; } added_device; diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c index 8e9fc45ab85..7ee7c6524d4 100644 --- a/dlls/wineusb.sys/wineusb.c +++ b/dlls/wineusb.sys/wineusb.c @@ -78,9 +78,9 @@ struct usb_device bool interface; int16_t interface_index; - uint8_t class, subclass, protocol; + uint8_t class, subclass, protocol, busnum, portnum; - uint16_t vendor, product, revision; + uint16_t vendor, product, revision, usbver; struct unix_device *unix_device; @@ -133,9 +133,13 @@ static void add_unix_device(const struct usb_add_device_event *event) device->class = event->class; device->subclass = event->subclass; device->protocol = event->protocol; + device->busnum = event->busnum; + device->portnum = event->portnum; + device->vendor = event->vendor; device->product = event->product; device->revision = event->revision; + device->usbver = event->usbver; EnterCriticalSection(&wineusb_cs); list_add_tail(&device_list, &device->entry); @@ -362,6 +366,11 @@ static void get_device_id(const struct usb_device *device, struct string_buffer append_id(buffer, L"USB\\VID_%04X&PID_%04X", device->vendor, device->product); } +static void get_instance_id(const struct usb_device *device, struct string_buffer *buffer) +{ + append_id(buffer, L"%u&%u&%u&%u", device->usbver, device->revision, device->busnum, device->portnum); +} + static void get_hardware_ids(const struct usb_device *device, struct string_buffer *buffer) { if (device->interface) @@ -407,7 +416,7 @@ static NTSTATUS query_id(struct usb_device *device, IRP *irp, BUS_QUERY_ID_TYPE break; case BusQueryInstanceID: - append_id(&buffer, L"0"); + get_instance_id(device, &buffer); break; case BusQueryHardwareIDs: -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1631
participants (2)
-
Ivo Ivanov -
Ivo Ivanov (@logos128)