From 851ff404003a26c1e3428b9a1332227173cc124b Mon Sep 17 00:00:00 2001 From: Ihor Dutchak Date: Tue, 10 Nov 2020 01:39:28 +0200 Subject: [PATCH] Windows: ignore all broken devices during enumeration - explicitly check/log info, when a device has broken descriptor; Closes #791 Closes #806 Signed-off-by: Chris Dickens --- libusb/os/windows_winusb.c | 20 +++++++++++++++++--- libusb/version_nano.h | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index e0d7b1f..7d47323 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -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; diff --git a/libusb/version_nano.h b/libusb/version_nano.h index d853d67..371785c 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11573 +#define LIBUSB_NANO 11574 -- 2.7.4