diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index f3e55856b..0665235f2 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -1105,6 +1105,40 @@ static enum libusb_error darwin_cache_device_descriptor (struct libusb_context * (*device)->GetDeviceProduct (device, &idProduct); (*device)->GetDeviceVendor (device, &idVendor); + /* Try synthesize a device descriptor from OS cached values */ + do { + libusb_device descriptor *desc = dev->dev_descriptor; + UInt16 bcdDevice; + + /* If anything fails, fall back to requesting descriptor from device */ + if (!get_ioregistry_value_number (dev->service, CFSTR("bMaxPacketSize0"), kCFNumberUInt8Type, &desc->bMaxPacketSize0)) + break; + + desc.bcdUSB = libusb_cpu_to_le16(0x0200); // FIXME get from somewhere + + desc->bDeviceClass = bDeviceClass; + (*device)->GetDeviceSubClass (device, &desc->bDeviceSubClass); + (*device)->GetDeviceProtocol (device, &desc->bDeviceProtocol); + + (*device)->GetDeviceVendor (device, &idVendor); + desc->idVendor = libusb_cpu_to_le16(idVendor); + (*device)->GetDeviceProduct (device, &idProduct); + desc->idProduct = libusb_cpu_to_le16(idProduct); + (*device)->GetDeviceReleaseNumber (device, &bcdDevice); + desc->bcdDevice = libusb_cpu_to_le16(bcdDevice); + + (*device)->USBGetManufacturerStringIndex (device, &desc->iManufacturer); + (*device)->USBGetProductStringIndex (device, &desc->iProduct); + (*device)->USBGetSerialNumberStringIndex (device, &desc->iSerialNumber); + (*device)->GetNumberOfConfigurations (device, &desc->bNumConfigurations); + + // if needed do validity checks here + + desc.bDescriptorType = LIBUSB_DT_DEVICE; + desc.bLength = LIBUSB_DT_DEVICE_SIZE; + goto done_desc; + } while (0); + /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still, * to follow the spec as closely as possible, try opening the device */ @@ -1201,6 +1235,7 @@ static enum libusb_error darwin_cache_device_descriptor (struct libusb_context * return LIBUSB_ERROR_NO_DEVICE; } +done_desc: usbi_dbg (ctx, "cached device descriptor:"); usbi_dbg (ctx, " bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType); usbi_dbg (ctx, " bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));