/** \ingroup desc * Retrieve a string descriptor in C style ASCII. * * Wrapper around libusb_get_string_descriptor(). Uses the first language * supported by the device. * * \param dev a device handle * \param desc_index the index of the descriptor to retrieve * \param data output buffer for ASCII string descriptor * \param length size of data buffer * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure */ int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev, uint8_t desc_index, unsigned char *data, int length) { unsigned char tbuf[255]; /* Some devices choke on size > 255 */ int r, si, di; uint16_t langid; /* Asking for the zero'th index is special - it returns a string * descriptor that contains all the language IDs supported by the * device. Typically there aren't many - often only one. Language * IDs are 16 bit numbers, and they start at the third byte in the * descriptor. There's also no point in trying to read descriptor 0 * with this function. See USB 2.0 specification section 9.6.7 for * more information. */ if (desc_index == 0) return LIBUSB_ERROR_INVALID_PARAM; r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf)); if (r < 0) return r; if (r < 4) return LIBUSB_ERROR_IO; langid = tbuf[2] | (tbuf[3] << 8); r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf, sizeof(tbuf)); if (r < 0) return r; if (tbuf[1] != LIBUSB_DT_STRING) return LIBUSB_ERROR_IO; if (tbuf[0] > r) return LIBUSB_ERROR_IO; for (di = 0, si = 2; si < tbuf[0]; si += 2) { if (di >= (length - 1)) break; if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */ data[di++] = '?'; else data[di++] = tbuf[si]; } data[di] = 0; return di; }
bool USBDevice::open(OpenMode) { close(); int ret; // try to open the device ret = libusb_open(m_data->device, &m_data->handle); if (ret < 0) { setErrorString(ret); return false; } // select the interface ret = libusb_claim_interface(m_data->handle, 0); if (ret < 0) { setErrorString(ret); libusb_close(m_data->handle); m_data->handle = NULL; return false; } // get serial number unsigned char c[64]; ret = libusb_get_string_descriptor(m_data->handle, m_data->descriptor.iSerialNumber, 0, c, sizeof(c)); if (ret < 0) { setErrorString(ret); libusb_release_interface(m_data->handle, 0); libusb_close(m_data->handle); m_data->handle = NULL; return false; } m_serialNumber = QString::fromUtf16((const ushort *) &c[2], (qMin<int>(ret, c[0]) - 2) / 2); // get id ret = libusb_get_string_descriptor(m_data->handle, 4, 0, c, sizeof(c)); if (ret < 0) { setErrorString(ret); libusb_release_interface(m_data->handle, 0); libusb_close(m_data->handle); m_data->handle = NULL; return false; } m_id = QString::fromUtf16((const ushort *) &c[2], (qMin<int>(ret, c[0]) - 2) / 2); // create transfer for receiving robot status startInTransfer(); return QIODevice::open(ReadWrite | Unbuffered); }
char *get_dev_string(libusb_device_handle *dev, u_int8_t id) { #if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV) int ret; char *buf, unicode_buf[254]; u_int16_t langid; #endif if (!dev || !id) return strdup(""); #if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV) langid = get_any_langid(dev); if (!langid) return strdup("(error)"); ret = libusb_get_string_descriptor(dev, id, langid, (unsigned char *) unicode_buf, sizeof unicode_buf); if (ret < 2) return strdup("(error)"); if ((unsigned char)unicode_buf[0] < 2 || unicode_buf[1] != LIBUSB_DT_STRING) return strdup("(error)"); buf = usb_string_to_native(unicode_buf + 2, ((unsigned char) unicode_buf[0] - 2) / 2); if (!buf) return get_dev_string_ascii(dev, 127, id); return buf; #else return get_dev_string_ascii(dev, 127, id); #endif }
static u_int16_t get_any_langid(libusb_device_handle *dev) { unsigned char buf[4]; int ret = libusb_get_string_descriptor(dev, 0, 0, buf, sizeof buf); if (ret != sizeof buf) return 0; return buf[2] | (buf[3] << 8); }
uint16_t LibUSB::DeviceImpl::getLangId() { /// \note This descriptor is described here: http://www.beyondlogic.org/usbnutshell/usb5.shtml if((languageId == 0) && isOpen()) { uint8_t data[255]; memset(data, '\0', sizeof(data)); int Result = libusb_get_string_descriptor(m_pHandle.get(), 0, 0, data, sizeof(data)); if (Result < LIBUSB_SUCCESS) { throw LibUSBException("libusb_get_string_descriptor() failed.", Result); } // First element is the size of the descriptor, in bytes uint8_t descriptorSize = data[0]; // Second element should be 0x03 if (data[1] != 0x03) { throw std::runtime_error("USB language string descriptor (index 0) is invalid."); } // Grab the first/default language. languageId = data[2] | data[3]<<8; } return languageId; }
std::wstring LibUSB::DeviceImpl::getStringDescriptorW( uint8_t index ) { unsigned char descStr[128]; wmemset((wchar_t*)descStr, L'\0', sizeof(descStr)/sizeof(wchar_t)); int Result = libusb_get_string_descriptor(m_pHandle.get(), index, getLangId(), (unsigned char*)descStr, sizeof(descStr)); if (Result < LIBUSB_SUCCESS) { throw LibUSBException("libusb_get_string_descriptor() failed.", Result); } // First character is the size of the string descriptor, in bytes uint8_t descSize = descStr[0]; // Second character is 0x03, always if (descStr[1] != 0x03) { throw std::runtime_error("USB string descriptor returned from device is invalid."); } std::wstring strResult; strResult.assign((const wchar_t*)descStr + 1, (descSize-2)/2); return strResult; }
static int is_language_supported(libusb_device_handle *dev, uint16_t lang) { uint16_t buf[32]; int len; int i; /* Get the string from libusb. */ len = libusb_get_string_descriptor(dev, 0x0, /* String ID */ 0x0, /* Language */ (unsigned char*)buf, sizeof(buf)); if (len < 4) return 0x0; len /= 2; /* language IDs are two-bytes each. */ /* Start at index 1 because there are two bytes of protocol data. */ for (i = 1; i < len; i++) { if (buf[i] == lang) return 1; } return 0; }
API_EXPORTED int usb_get_string(usb_dev_handle *dev, int desc_index, int langid, char *buf, size_t buflen) { int r; r = libusb_get_string_descriptor(dev->handle, desc_index & 0xff, langid & 0xffff, buf, (int) buflen); if (r >= 0) return r; return compat_err(r); }
/** * Retrieve a string descriptor in C style ASCII. */ int libusb_get_string_descriptor_ascii(libusb_device_handle *dev, uint8_t desc_index, unsigned char *data, int length) { unsigned char tbuf[255]; /* Some devices choke on size > 255 */ int r, si, di; uint16_t langid; if (desc_index == 0) return LIBUSB_ERROR_INVALID_PARAM; r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf)); if (r < 0) return r; if (r < 4) return LIBUSB_ERROR_IO; langid = tbuf[2] | (tbuf[3] << 8); r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf, sizeof(tbuf)); if (r < 0) return r; if (tbuf[1] != LIBUSB_DT_STRING) return LIBUSB_ERROR_IO; if (tbuf[0] > r) return LIBUSB_ERROR_IO; for (di = 0, si = 2; si < tbuf[0]; si += 2) { if (di >= (length - 1)) break; if (tbuf[si + 1]) /* high byte */ data[di++] = '?'; else data[di++] = tbuf[si]; } data[di] = 0; return di; }
QString QUsbHid::getIndexedString(int index,bool* r) { char ret[256]; if(!handle || index ==0){ if(r) *r = false; return QString(); } //bool res = HidD_GetIndexedString(Win_Handle, index, ret, sizeof(ret)); int res = libusb_get_string_descriptor(handle,index,0,(uint8_t*)ret,256); if(r) *r = res > 0; return translateUSBString(ret,res); }
/* Get the first language the device says it reports. This comes from USB string #0. */ static uint16_t get_first_language(libusb_device_handle *dev) { uint16_t buf[32]; int len; /* Get the string from libusb. */ len = libusb_get_string_descriptor(dev, 0x0, /* String ID */ 0x0, /* Language */ (unsigned char*)buf, sizeof(buf)); if (len < 4) return 0x0; return buf[1]; // First two bytes are len and descriptor type. }
//============================================================================== void USB_Device::string_descriptor_utf8(uint8_t index, uint16_t language, String &data) { check_open(); uint8_t raw_data[256]; int result = libusb_get_string_descriptor(handle_, index, language, raw_data, sizeof(raw_data)); if (result < 0) on_error("Failed to get string descriptor " + number_to_string(index), (libusb_error)result); data.assign(raw_data, raw_data + result); raw_data[result] = '\0'; log_info("usb, get string descriptor %u, language: %u, data: %s", index, language, raw_data); }
int get_dev_string(char *buf, size_t size, libusb_device_handle *hdev, u_int8_t id) { #if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV) int ret; unsigned char unicode_buf[254]; u_int16_t langid; #endif if (!hdev || !id) { return 0; } #if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV) langid = get_any_langid(hdev); if (!langid) { return snprintf(buf, size, "%s", "(error)"); } ret = libusb_get_string_descriptor(hdev, id, langid, (unsigned char *) unicode_buf, sizeof unicode_buf); if (ret < 2) { return snprintf(buf, size, "%s", "(error)"); } char *tmp = usb_string_to_native(unicode_buf + 2, ((unsigned char) unicode_buf[0] - 2) / 2); if (tmp) { snprintf(buf, size, "%s", tmp); free(tmp); } else { get_dev_string_ascii(buf, size, hdev, id); } return strlen(buf); #else get_dev_string_ascii(buf, size, hdev, id); return strlen(buf); #endif }
/* 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(). */ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) { char buf[512]; int len; wchar_t *str = NULL; wchar_t wbuf[256]; /* iconv variables */ iconv_t ic; size_t inbytes; size_t outbytes; size_t res; #ifdef __FreeBSD__ const char *inptr; #else char *inptr; #endif char *outptr; /* Determine which language to use. */ uint16_t lang; lang = get_usb_code_for_current_locale(); if (!is_language_supported(dev, lang)) lang = get_first_language(dev); /* Get the string from libusb. */ len = libusb_get_string_descriptor(dev, idx, lang, (unsigned char*)buf, sizeof(buf)); if (len < 0) return NULL; /* buf does not need to be explicitly NULL-terminated because it is only passed into iconv() which does not need it. */ /* Initialize iconv. */ ic = iconv_open("WCHAR_T", "UTF-16LE"); if (ic == (iconv_t)-1) { LOG("iconv_open() failed\n"); return NULL; } /* Convert to native wchar_t (UTF-32 on glibc/BSD systems). Skip the first character (2-bytes). */ inptr = buf+2; inbytes = len-2; outptr = (char*) wbuf; outbytes = sizeof(wbuf); res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes); if (res == (size_t)-1) { LOG("iconv() failed\n"); goto err; } /* Write the terminating NULL. */ wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000; if (outbytes >= sizeof(wbuf[0])) *((wchar_t*)outptr) = 0x00000000; /* Allocate and copy the string. */ str = wcsdup(wbuf); err: iconv_close(ic); return str; }
/* 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(). */ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) { char buf[512]; int len; wchar_t *str = NULL; #ifndef __ANDROID__ /* we don't use iconv on Android */ wchar_t wbuf[256]; /* iconv variables */ iconv_t ic; size_t inbytes; size_t outbytes; size_t res; #ifdef __FreeBSD__ const char *inptr; #else char *inptr; #endif char *outptr; #endif /* Determine which language to use. */ uint16_t lang; lang = get_usb_code_for_current_locale(); if (!is_language_supported(dev, lang)) lang = get_first_language(dev); /* Get the string from libusb. */ len = libusb_get_string_descriptor(dev, idx, lang, (unsigned char*)buf, sizeof(buf)); if (len < 0) return NULL; #ifdef __ANDROID__ /* Bionic does not have iconv support nor wcsdup() function, so it has to be done manually. The following code will only work for code points that can be represented as a single UTF-16 character, and will incorrectly convert any code points which require more than one UTF-16 character. Skip over the first character (2-bytes). */ len -= 2; str = malloc((len / 2 + 1) * sizeof(wchar_t)); int i; for (i = 0; i < len / 2; i++) { str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); } str[len / 2] = 0x00000000; #else /* buf does not need to be explicitly NULL-terminated because it is only passed into iconv() which does not need it. */ /* Initialize iconv. */ ic = iconv_open("WCHAR_T", "UTF-16LE"); if (ic == (iconv_t)-1) { LOG("iconv_open() failed\n"); return NULL; } /* Convert to native wchar_t (UTF-32 on glibc/BSD systems). Skip the first character (2-bytes). */ inptr = buf+2; inbytes = len-2; outptr = (char*) wbuf; outbytes = sizeof(wbuf); res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes); if (res == (size_t)-1) { LOG("iconv() failed\n"); goto err; } /* Write the terminating NULL. */ wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000; if (outbytes >= sizeof(wbuf[0])) *((wchar_t*)outptr) = 0x00000000; /* Allocate and copy the string. */ str = wcsdup(wbuf); err: iconv_close(ic); #endif return str; }
API_EXPORTED int usb_get_string(usb_dev_handle *dev, int desc_index, int langid, char *buf, size_t buflen) { return libusb_get_string_descriptor(dev->handle, desc_index & 0xff, langid & 0xffff, buf, (int) buflen); }
/* 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(). */ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) { char buf[512]; int len; wchar_t *str = NULL; wchar_t wbuf[256]; /* iconv variables */ iconv_t ic; size_t inbytes; size_t outbytes; size_t res; char *inptr; char *outptr; /* Determine which language to use. */ uint16_t lang; lang = get_usb_code_for_current_locale(); if (!is_language_supported(dev, lang)) lang = get_first_language(dev); /* Get the string from libusb. */ len = libusb_get_string_descriptor(dev, idx, lang, (unsigned char*)buf, sizeof(buf)); if (len < 0) return NULL; buf[sizeof(buf)-1] = '\0'; if (len+1 < sizeof(buf)) buf[len+1] = '\0'; /* Initialize iconv. */ ic = iconv_open("UTF-32", "UTF-16"); if (ic == (iconv_t)-1) return NULL; /* Convert to UTF-32 (wchar_t on glibc systems). Skip the first character (2-bytes). */ inptr = buf+2; inbytes = len-2; outptr = (char*) wbuf; outbytes = sizeof(wbuf); res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes); if (res == (size_t)-1) goto err; /* Write the terminating NULL. */ wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000; if (outbytes >= sizeof(wbuf[0])) *((wchar_t*)outptr) = 0x00000000; /* Allocate and copy the string. */ str = wcsdup(wbuf+1); err: iconv_close(ic); return str; }
int cyusb_get_string_descriptor(cyusb_handle *h, unsigned char desc_index, unsigned short langid, unsigned char *data, int len) { return ( libusb_get_string_descriptor(h, desc_index, langid, data, len) ); }