Also make the device instance id unique (at least to the bus), as required by MS. It is also easily addressable by other drivers.
From: Ivo Ivanov logos128@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;
From: Ivo Ivanov logos128@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""); }
From: Ivo Ivanov logos128@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: