summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libusb/os/windows_winusb.c18
-rw-r--r--libusb/os/windows_winusb.h2
-rw-r--r--libusb/version_nano.h2
3 files changed, 13 insertions, 9 deletions
diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c
index 81cceef..d1d2749 100644
--- a/libusb/os/windows_winusb.c
+++ b/libusb/os/windows_winusb.c
@@ -864,12 +864,12 @@ static int force_hcd_device_descriptor(struct libusb_device *dev)
priv->dev_descriptor.bNumConfigurations = 1;
priv->active_config = 1;
- if (priv->parent_dev == NULL) {
+ if (dev->parent_dev == NULL) {
usbi_err(ctx, "program assertion failed - HCD hub has no parent");
return LIBUSB_ERROR_NO_DEVICE;
}
- parent_priv = _device_priv(priv->parent_dev);
+ parent_priv = _device_priv(dev->parent_dev);
if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) {
priv->dev_descriptor.idVendor = (uint16_t)vid;
priv->dev_descriptor.idProduct = (uint16_t)pid;
@@ -1043,7 +1043,6 @@ static int init_device(struct libusb_device *dev, struct libusb_device *parent_d
priv->port = port_number;
dev->port_number = port_number;
priv->depth = parent_priv->depth + 1;
- priv->parent_dev = parent_dev;
dev->parent_dev = parent_dev;
// If the device address is already set, we can stop here
@@ -1521,9 +1520,16 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
session_id, dev->bus_number, dev->device_address);
priv = _device_priv(dev);
- if (priv->parent_dev != NULL) {
- if (priv->parent_dev != parent_dev) {
- usbi_err(ctx, "program assertion failed - existing device should share parent");
+ if ((parent_dev != NULL) && (dev->parent_dev != NULL)) {
+ if (dev->parent_dev != parent_dev) {
+ // It is possible for the actual parent device to not have existed at the
+ // time of enumeration, so the currently assigned parent may in fact be a
+ // grandparent. If the devices differ, we assume the "new" parent device
+ // is in fact closer to the device.
+ usbi_dbg("updating parent device [session %lX -> %lX]",
+ dev->parent_dev->session_data, parent_dev->session_data);
+ libusb_unref_device(dev->parent_dev);
+ dev->parent_dev = parent_dev;
} else {
// We hold a reference to parent_dev instance, but this device already
// has a parent_dev reference (only one per child)
diff --git a/libusb/os/windows_winusb.h b/libusb/os/windows_winusb.h
index 49c1df5..a259374 100644
--- a/libusb/os/windows_winusb.h
+++ b/libusb/os/windows_winusb.h
@@ -201,7 +201,6 @@ struct windows_device_priv {
uint8_t depth; // distance to HCD
uint8_t port; // port number on the hub
uint8_t active_config;
- struct libusb_device *parent_dev; // access to parent is required for usermode ops
struct windows_usb_api_backend const *apib;
char *path; // device interface path
int sub_api; // for WinUSB-like APIs
@@ -231,7 +230,6 @@ static inline struct windows_device_priv *windows_device_priv_init(struct libusb
p->depth = 0;
p->port = 0;
- p->parent_dev = NULL;
p->path = NULL;
p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->sub_api = SUB_API_NOTSET;
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index e7cb421..59027da 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11150
+#define LIBUSB_NANO 11151