int usb_get_string(usb_dev_handle * dev, int strindex, int langid, char *buf, size_t buflen) { int err; if (dev == NULL) return (-1); if (buflen > 65535) buflen = 65535; err = libusb20_dev_req_string_sync((void *)dev, strindex, langid, buf, buflen); if (err) return (-1); return (0); }
void dump_string_by_index(struct libusb20_device *pdev, uint8_t str_index) { char *pbuf; uint8_t n; uint8_t len; pbuf = malloc(256); if (pbuf == NULL) err(1, "out of memory"); if (str_index == 0) { /* language table */ if (libusb20_dev_req_string_sync(pdev, str_index, 0, pbuf, 256)) { printf("STRING_0x%02x = <read error>\n", str_index); } else { printf("STRING_0x%02x = ", str_index); len = (uint8_t)pbuf[0]; for (n = 0; n != len; n++) { printf("0x%02x%s", (uint8_t)pbuf[n], (n != (len-1)) ? ", " : ""); } printf("\n"); } } else { /* ordinary string */ if (libusb20_dev_req_string_simple_sync(pdev, str_index, pbuf, 256)) { printf("STRING_0x%02x = <read error>\n", str_index); } else { printf("STRING_0x%02x = <%s>\n", str_index, pbuf); } } free(pbuf); }
void usb_get_string_desc_test(uint16_t vid, uint16_t pid) { struct libusb20_device *pdev; uint32_t x; uint32_t y; uint32_t valid; uint8_t *buf; int error; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 0); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } buf = malloc(256); if (buf == NULL) { printf("Cannot allocate memory\n"); libusb20_dev_free(pdev); return; } valid = 0; printf("Starting string descriptor test for " "VID=0x%04x PID=0x%04x\n", vid, pid); for (x = 0; x != 256; x++) { if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } printf("%d .. ", (int)x); fflush(stdout); error = libusb20_dev_req_string_simple_sync(pdev, x, buf, 255); if (error == 0) { printf("\nINDEX=%d, STRING='%s' (Default language)\n", (int)x, buf); fflush(stdout); } else { continue; } valid = 0; for (y = 0; y != 65536; y++) { if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } error = libusb20_dev_req_string_sync(pdev, x, y, buf, 256); if (error == 0) valid++; } printf("String at INDEX=%d responds to %d " "languages\n", (int)x, (int)valid); } printf("\nDone\n"); free(buf); libusb20_dev_free(pdev); }
int libusb20_dev_req_string_simple_sync(struct libusb20_device *pdev, uint8_t str_index, void *ptr, uint16_t len) { char *buf; int error; uint16_t langid; uint16_t n; uint16_t i; uint16_t c; uint8_t temp[255]; uint8_t swap; /* the following code derives from the FreeBSD USB kernel */ if ((len < 1) || (ptr == NULL)) { /* too short buffer */ return (LIBUSB20_ERROR_INVALID_PARAM); } error = libusb20_dev_req_string_sync(pdev, 0, 0, temp, sizeof(temp)); if (error < 0) { *(uint8_t *)ptr = 0; /* zero terminate */ return (error); } langid = temp[2] | (temp[3] << 8); error = libusb20_dev_req_string_sync(pdev, str_index, langid, temp, sizeof(temp)); if (error < 0) { *(uint8_t *)ptr = 0; /* zero terminate */ return (error); } if (temp[0] < 2) { /* string length is too short */ *(uint8_t *)ptr = 0; /* zero terminate */ return (LIBUSB20_ERROR_OTHER); } /* reserve one byte for terminating zero */ len--; /* find maximum length */ n = (temp[0] / 2) - 1; if (n > len) { n = len; } /* reset swap state */ swap = 3; /* setup output buffer pointer */ buf = ptr; /* convert and filter */ for (i = 0; (i != n); i++) { c = temp[(2 * i) + 2] | (temp[(2 * i) + 3] << 8); /* convert from Unicode, handle buggy strings */ if (((c & 0xff00) == 0) && (swap & 1)) { /* Little Endian, default */ *buf = c; swap = 1; } else if (((c & 0x00ff) == 0) && (swap & 2)) { /* Big Endian */ *buf = c >> 8; swap = 2; } else { /* skip invalid character */ continue;