@@ -1105,12 +1105,45 @@ static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *
1105
1105
(* device )-> GetDeviceProduct (device , & idProduct );
1106
1106
(* device )-> GetDeviceVendor (device , & idVendor );
1107
1107
1108
+ /* Try synthesize a device descriptor from OS cached values */
1109
+ do {
1110
+ IOUSBDeviceDescriptor * desc = & dev -> dev_descriptor ;
1111
+ UInt16 bcdDevice ;
1112
+
1113
+ /* If anything fails, fall back to requesting descriptor from device */
1114
+ if (!get_ioregistry_value_number (dev -> service , CFSTR ("bMaxPacketSize0" ), kCFNumberSInt8Type , & desc -> bMaxPacketSize0 ))
1115
+ break ;
1116
+
1117
+ desc -> bcdUSB = libusb_cpu_to_le16 (0x0200 ); // FIXME get from somewhere
1118
+
1119
+ desc -> bDeviceClass = bDeviceClass ;
1120
+ (* device )-> GetDeviceSubClass (device , & desc -> bDeviceSubClass );
1121
+ (* device )-> GetDeviceProtocol (device , & desc -> bDeviceProtocol );
1122
+
1123
+ desc -> idVendor = libusb_cpu_to_le16 (idVendor ); // TODO: verify on BE
1124
+ desc -> idProduct = libusb_cpu_to_le16 (idProduct );
1125
+ (* device )-> GetDeviceReleaseNumber (device , & bcdDevice );
1126
+ desc -> bcdDevice = libusb_cpu_to_le16 (bcdDevice );
1127
+
1128
+ (* device )-> USBGetManufacturerStringIndex (device , & desc -> iManufacturer );
1129
+ (* device )-> USBGetProductStringIndex (device , & desc -> iProduct );
1130
+ (* device )-> USBGetSerialNumberStringIndex (device , & desc -> iSerialNumber );
1131
+ (* device )-> GetNumberOfConfigurations (device , & desc -> bNumConfigurations );
1132
+
1133
+ // if needed do validity checks here (and reset descriptor on failure?)
1134
+
1135
+ desc -> bDescriptorType = LIBUSB_DT_DEVICE ;
1136
+ desc -> bLength = LIBUSB_DT_DEVICE_SIZE ;
1137
+ goto done_desc ;
1138
+ } while (0 );
1139
+
1108
1140
/* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
1109
1141
* devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
1110
1142
* to follow the spec as closely as possible, try opening the device */
1111
1143
is_open = ((* device )-> USBDeviceOpenSeize (device ) == kIOReturnSuccess );
1112
1144
1113
1145
do {
1146
+ usbi_dbg (ctx , "requesting device descriptor from device" );
1114
1147
/**** retrieve device descriptor ****/
1115
1148
ret = darwin_request_descriptor (device , kUSBDeviceDesc , 0 , & dev -> dev_descriptor , sizeof (dev -> dev_descriptor ));
1116
1149
@@ -1201,6 +1234,7 @@ static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *
1201
1234
return LIBUSB_ERROR_NO_DEVICE ;
1202
1235
}
1203
1236
1237
+ done_desc :
1204
1238
usbi_dbg (ctx , "cached device descriptor:" );
1205
1239
usbi_dbg (ctx , " bDescriptorType: 0x%02x" , dev -> dev_descriptor .bDescriptorType );
1206
1240
usbi_dbg (ctx , " bcdUSB: 0x%04x" , libusb_le16_to_cpu (dev -> dev_descriptor .bcdUSB ));
0 commit comments