This function returns a newly allocated wide string containing the USB device string numbered by the index. The returned string must be freed by using free(). */
| 401 | device string numbered by the index. The returned string must be freed |
| 402 | by using free(). */ |
| 403 | static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) |
| 404 | { |
| 405 | char buf[512]; |
| 406 | int len; |
| 407 | wchar_t *str = NULL; |
| 408 | |
| 409 | #if !defined(__ANDROID__) && !defined(NO_ICONV) /* we don't use iconv on Android, or when it is explicitly disabled */ |
| 410 | wchar_t wbuf[256]; |
| 411 | /* iconv variables */ |
| 412 | iconv_t ic; |
| 413 | size_t inbytes; |
| 414 | size_t outbytes; |
| 415 | size_t res; |
| 416 | ICONV_CONST char *inptr; |
| 417 | char *outptr; |
| 418 | #endif |
| 419 | |
| 420 | /* Determine which language to use. */ |
| 421 | uint16_t lang; |
| 422 | lang = get_usb_code_for_current_locale(); |
| 423 | if (!is_language_supported(dev, lang)) |
| 424 | lang = get_first_language(dev); |
| 425 | |
| 426 | /* Get the string from libusb. */ |
| 427 | len = libusb_get_string_descriptor(dev, |
| 428 | idx, |
| 429 | lang, |
| 430 | (unsigned char*)buf, |
| 431 | sizeof(buf)); |
| 432 | if (len < 2) /* we always skip first 2 bytes */ |
| 433 | return NULL; |
| 434 | |
| 435 | #if defined(__ANDROID__) || defined(NO_ICONV) |
| 436 | |
| 437 | /* Bionic does not have iconv support nor wcsdup() function, so it |
| 438 | has to be done manually. The following code will only work for |
| 439 | code points that can be represented as a single UTF-16 character, |
| 440 | and will incorrectly convert any code points which require more |
| 441 | than one UTF-16 character. |
| 442 | |
| 443 | Skip over the first character (2-bytes). */ |
| 444 | len -= 2; |
| 445 | str = (wchar_t*) malloc((len / 2 + 1) * sizeof(wchar_t)); |
| 446 | int i; |
| 447 | for (i = 0; i < len / 2; i++) { |
| 448 | str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); |
| 449 | } |
| 450 | str[len / 2] = 0x00000000; |
| 451 | |
| 452 | #else |
| 453 | |
| 454 | /* buf does not need to be explicitly NULL-terminated because |
| 455 | it is only passed into iconv() which does not need it. */ |
| 456 | |
| 457 | /* Initialize iconv. */ |
| 458 | ic = iconv_open("WCHAR_T", "UTF-16LE"); |
| 459 | if (ic == (iconv_t)-1) { |
| 460 | LOG("iconv_open() failed\n"); |
no test coverage detected