usb_raw: Fetch default language before fetching string descriptors.

This fixes strange hangs that occur with some devices when fetching
their string descriptors with language-id "0".
This commit is contained in:
Augustin Cavalier
2023-05-23 14:23:14 -04:00
parent 943b5775f8
commit c2e8b3177b
+19 -6
View File
@@ -543,20 +543,33 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
return B_BUFFER_OVERFLOW; return B_BUFFER_OVERFLOW;
size_t actualLength = 0; size_t actualLength = 0;
uint8 firstTwoBytes[2]; uint8 temp[4];
status = B_OK; status = B_OK;
// We need to fetch the default language code, first.
if (gUSBModule->get_descriptor(device->device, if (gUSBModule->get_descriptor(device->device,
USB_DESCRIPTOR_STRING, command.string.string_index, 0, USB_DESCRIPTOR_STRING, 0, 0,
firstTwoBytes, 2, &actualLength) < B_OK temp, 4, &actualLength) < B_OK
|| actualLength != 4
|| temp[1] != USB_DESCRIPTOR_STRING) {
command.string.status = B_USB_RAW_STATUS_ABORTED;
command.string.length = 0;
break;
}
const uint16 langid = (temp[2] | (temp[3] << 8));
// Now fetch the string length.
if (gUSBModule->get_descriptor(device->device,
USB_DESCRIPTOR_STRING, command.string.string_index, langid,
temp, 2, &actualLength) < B_OK
|| actualLength != 2 || actualLength != 2
|| firstTwoBytes[1] != USB_DESCRIPTOR_STRING) { || temp[1] != USB_DESCRIPTOR_STRING) {
command.string.status = B_USB_RAW_STATUS_ABORTED; command.string.status = B_USB_RAW_STATUS_ABORTED;
command.string.length = 0; command.string.length = 0;
break; break;
} }
uint8 stringLength = MIN(firstTwoBytes[0], command.string.length); uint8 stringLength = MIN(temp[0], command.string.length);
char *string = (char *)malloc(stringLength); char *string = (char *)malloc(stringLength);
if (string == NULL) { if (string == NULL) {
command.string.status = B_USB_RAW_STATUS_ABORTED; command.string.status = B_USB_RAW_STATUS_ABORTED;
@@ -566,7 +579,7 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
} }
if (gUSBModule->get_descriptor(device->device, if (gUSBModule->get_descriptor(device->device,
USB_DESCRIPTOR_STRING, command.string.string_index, 0, USB_DESCRIPTOR_STRING, command.string.string_index, langid,
string, stringLength, &actualLength) < B_OK string, stringLength, &actualLength) < B_OK
|| actualLength != stringLength) { || actualLength != stringLength) {
command.string.status = B_USB_RAW_STATUS_ABORTED; command.string.status = B_USB_RAW_STATUS_ABORTED;