[PATCH v2 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. -- v2: wineusb.sys: Add usbver, revision, busnum and portnum to PDO's instance id. wineusb.sys: Implement DevClass compatible id for devices with multiple interfaces. wineusb.sys: Pass interface and interface_index from the event data to the usb device data. 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 7889270c37d..fb8ddea1bdf 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 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 fb8ddea1bdf..4d8447e7057 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)