Windows: ignore all broken devices during enumeration
authorIhor Dutchak <ihor.youw@gmail.com>
Mon, 9 Nov 2020 23:39:28 +0000 (01:39 +0200)
committerChris Dickens <christopher.a.dickens@gmail.com>
Tue, 10 Nov 2020 02:54:44 +0000 (18:54 -0800)
- explicitly check/log info, when a device has broken descriptor;

Closes #791
Closes #806

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
libusb/os/windows_winusb.c
libusb/version_nano.h

index e0d7b1f..7d47323 100644 (file)
@@ -1104,6 +1104,12 @@ static int init_device(struct libusb_device *dev, struct libusb_device *parent_d
                                return LIBUSB_ERROR_NO_DEVICE;
                        }
 
+                       if ((conn_info.DeviceDescriptor.bLength != LIBUSB_DT_DEVICE_SIZE)
+                                || (conn_info.DeviceDescriptor.bDescriptorType != LIBUSB_DT_DEVICE)) {
+                               SleepEx(50, TRUE);
+                               continue;
+                       }
+
                        static_assert(sizeof(dev->device_descriptor) == sizeof(conn_info.DeviceDescriptor),
                                      "mismatch between libusb and OS device descriptor sizes");
                        memcpy(&dev->device_descriptor, &conn_info.DeviceDescriptor, LIBUSB_DT_DEVICE_SIZE);
@@ -1119,6 +1125,13 @@ static int init_device(struct libusb_device *dev, struct libusb_device *parent_d
                        }
                } while (priv->active_config == 0 && --ginfotimeout >= 0);
 
+               if ((conn_info.DeviceDescriptor.bLength != LIBUSB_DT_DEVICE_SIZE)
+                        || (conn_info.DeviceDescriptor.bDescriptorType != LIBUSB_DT_DEVICE)) {
+                       usbi_err(ctx, "device '%s' has invalid descriptor!", priv->dev_id);
+                       CloseHandle(hub_handle);
+                       return LIBUSB_ERROR_OTHER;
+               }
+
                if (priv->active_config == 0) {
                        usbi_info(ctx, "0x%x:0x%x found %u configurations but device isn't configured, "
                                "forcing current configuration to 1",
@@ -1721,9 +1734,10 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_
                                                LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
 
                                        *_discdevs = discdevs;
-                               } else if (r == LIBUSB_ERROR_NO_DEVICE) {
-                                       // This can occur if the device was disconnected but Windows hasn't
-                                       // refreshed its enumeration yet - in that case, we ignore the device
+                               } else {
+                                       // Failed to initialize a single device doesn't stop us from enumerating all other devices,
+                                       // but we skip it (don't add to list of discovered devices)
+                                       usbi_warn(ctx, "failed to initialize device '%s'", priv->dev_id);
                                        r = LIBUSB_SUCCESS;
                                }
                                break;
index d853d67..371785c 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 11573
+#define LIBUSB_NANO 11574