descriptor.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
  2. /*
  3. * USB descriptor handling functions for libusbx
  4. * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
  5. * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <errno.h>
  22. #include <stdint.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "libusbi.h"
  26. #define DESC_HEADER_LENGTH 2
  27. #define DEVICE_DESC_LENGTH 18
  28. #define CONFIG_DESC_LENGTH 9
  29. #define INTERFACE_DESC_LENGTH 9
  30. #define ENDPOINT_DESC_LENGTH 7
  31. #define ENDPOINT_AUDIO_DESC_LENGTH 9
  32. /** @defgroup desc USB descriptors
  33. * This page details how to examine the various standard USB descriptors
  34. * for detected devices
  35. */
  36. /* set host_endian if the w values are already in host endian format,
  37. * as opposed to bus endian. */
  38. int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
  39. void *dest, int host_endian)
  40. {
  41. const unsigned char *sp = source;
  42. unsigned char *dp = dest;
  43. uint16_t w;
  44. const char *cp;
  45. uint32_t d;
  46. for (cp = descriptor; *cp; cp++) {
  47. switch (*cp) {
  48. case 'b': /* 8-bit byte */
  49. *dp++ = *sp++;
  50. break;
  51. case 'w': /* 16-bit word, convert from little endian to CPU */
  52. dp += ((uintptr_t)dp & 1); /* Align to word boundary */
  53. if (host_endian) {
  54. memcpy(dp, sp, 2);
  55. } else {
  56. w = (sp[1] << 8) | sp[0];
  57. *((uint16_t *)dp) = w;
  58. }
  59. sp += 2;
  60. dp += 2;
  61. break;
  62. case 'd': /* 32-bit word, convert from little endian to CPU */
  63. dp += ((uintptr_t)dp & 1); /* Align to word boundary */
  64. if (host_endian) {
  65. memcpy(dp, sp, 4);
  66. } else {
  67. d = (sp[3] << 24) | (sp[2] << 16) |
  68. (sp[1] << 8) | sp[0];
  69. *((uint32_t *)dp) = d;
  70. }
  71. sp += 4;
  72. dp += 4;
  73. break;
  74. case 'u': /* 16 byte UUID */
  75. memcpy(dp, sp, 16);
  76. sp += 16;
  77. dp += 16;
  78. break;
  79. }
  80. }
  81. return (int) (sp - source);
  82. }
  83. static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
  84. {
  85. if (endpoint->extra)
  86. free((unsigned char *) endpoint->extra);
  87. }
  88. static int parse_endpoint(struct libusb_context *ctx,
  89. struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer,
  90. int size, int host_endian)
  91. {
  92. struct usb_descriptor_header header;
  93. unsigned char *extra;
  94. unsigned char *begin;
  95. int parsed = 0;
  96. int len;
  97. if (size < DESC_HEADER_LENGTH) {
  98. usbi_err(ctx, "short endpoint descriptor read %d/%d",
  99. size, DESC_HEADER_LENGTH);
  100. return LIBUSB_ERROR_IO;
  101. }
  102. usbi_parse_descriptor(buffer, "bb", &header, 0);
  103. if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) {
  104. usbi_err(ctx, "unexpected descriptor %x (expected %x)",
  105. header.bDescriptorType, LIBUSB_DT_ENDPOINT);
  106. return parsed;
  107. }
  108. if (header.bLength > size) {
  109. usbi_warn(ctx, "short endpoint descriptor read %d/%d",
  110. size, header.bLength);
  111. return parsed;
  112. }
  113. if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH)
  114. usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian);
  115. else if (header.bLength >= ENDPOINT_DESC_LENGTH)
  116. usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian);
  117. else {
  118. usbi_err(ctx, "invalid endpoint bLength (%d)", header.bLength);
  119. return LIBUSB_ERROR_IO;
  120. }
  121. buffer += header.bLength;
  122. size -= header.bLength;
  123. parsed += header.bLength;
  124. /* Skip over the rest of the Class Specific or Vendor Specific */
  125. /* descriptors */
  126. begin = buffer;
  127. while (size >= DESC_HEADER_LENGTH) {
  128. usbi_parse_descriptor(buffer, "bb", &header, 0);
  129. if (header.bLength < DESC_HEADER_LENGTH) {
  130. usbi_err(ctx, "invalid extra ep desc len (%d)",
  131. header.bLength);
  132. return LIBUSB_ERROR_IO;
  133. } else if (header.bLength > size) {
  134. usbi_warn(ctx, "short extra ep desc read %d/%d",
  135. size, header.bLength);
  136. return parsed;
  137. }
  138. /* If we find another "proper" descriptor then we're done */
  139. if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
  140. (header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
  141. (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
  142. (header.bDescriptorType == LIBUSB_DT_DEVICE))
  143. break;
  144. usbi_dbg("skipping descriptor %x", header.bDescriptorType);
  145. buffer += header.bLength;
  146. size -= header.bLength;
  147. parsed += header.bLength;
  148. }
  149. /* Copy any unknown descriptors into a storage area for drivers */
  150. /* to later parse */
  151. len = (int)(buffer - begin);
  152. if (!len) {
  153. endpoint->extra = NULL;
  154. endpoint->extra_length = 0;
  155. return parsed;
  156. }
  157. extra = malloc(len);
  158. endpoint->extra = extra;
  159. if (!extra) {
  160. endpoint->extra_length = 0;
  161. return LIBUSB_ERROR_NO_MEM;
  162. }
  163. memcpy(extra, begin, len);
  164. endpoint->extra_length = len;
  165. return parsed;
  166. }
  167. static void clear_interface(struct libusb_interface *usb_interface)
  168. {
  169. int i;
  170. int j;
  171. if (usb_interface->altsetting) {
  172. for (i = 0; i < usb_interface->num_altsetting; i++) {
  173. struct libusb_interface_descriptor *ifp =
  174. (struct libusb_interface_descriptor *)
  175. usb_interface->altsetting + i;
  176. if (ifp->extra)
  177. free((void *) ifp->extra);
  178. if (ifp->endpoint) {
  179. for (j = 0; j < ifp->bNumEndpoints; j++)
  180. clear_endpoint((struct libusb_endpoint_descriptor *)
  181. ifp->endpoint + j);
  182. free((void *) ifp->endpoint);
  183. }
  184. }
  185. free((void *) usb_interface->altsetting);
  186. usb_interface->altsetting = NULL;
  187. }
  188. }
  189. static int parse_interface(libusb_context *ctx,
  190. struct libusb_interface *usb_interface, unsigned char *buffer, int size,
  191. int host_endian)
  192. {
  193. int i;
  194. int len;
  195. int r;
  196. int parsed = 0;
  197. int interface_number = -1;
  198. size_t tmp;
  199. struct usb_descriptor_header header;
  200. struct libusb_interface_descriptor *ifp;
  201. unsigned char *begin;
  202. usb_interface->num_altsetting = 0;
  203. while (size >= INTERFACE_DESC_LENGTH) {
  204. struct libusb_interface_descriptor *altsetting =
  205. (struct libusb_interface_descriptor *) usb_interface->altsetting;
  206. altsetting = usbi_reallocf(altsetting,
  207. sizeof(struct libusb_interface_descriptor) *
  208. (usb_interface->num_altsetting + 1));
  209. if (!altsetting) {
  210. r = LIBUSB_ERROR_NO_MEM;
  211. goto err;
  212. }
  213. usb_interface->altsetting = altsetting;
  214. ifp = altsetting + usb_interface->num_altsetting;
  215. usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
  216. if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) {
  217. usbi_err(ctx, "unexpected descriptor %x (expected %x)",
  218. ifp->bDescriptorType, LIBUSB_DT_INTERFACE);
  219. return parsed;
  220. }
  221. if (ifp->bLength < INTERFACE_DESC_LENGTH) {
  222. usbi_err(ctx, "invalid interface bLength (%d)",
  223. ifp->bLength);
  224. r = LIBUSB_ERROR_IO;
  225. goto err;
  226. }
  227. if (ifp->bLength > size) {
  228. usbi_warn(ctx, "short intf descriptor read %d/%d",
  229. size, ifp->bLength);
  230. return parsed;
  231. }
  232. if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
  233. usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints);
  234. r = LIBUSB_ERROR_IO;
  235. goto err;
  236. }
  237. usb_interface->num_altsetting++;
  238. ifp->extra = NULL;
  239. ifp->extra_length = 0;
  240. ifp->endpoint = NULL;
  241. if (interface_number == -1)
  242. interface_number = ifp->bInterfaceNumber;
  243. /* Skip over the interface */
  244. buffer += ifp->bLength;
  245. parsed += ifp->bLength;
  246. size -= ifp->bLength;
  247. begin = buffer;
  248. /* Skip over any interface, class or vendor descriptors */
  249. while (size >= DESC_HEADER_LENGTH) {
  250. usbi_parse_descriptor(buffer, "bb", &header, 0);
  251. if (header.bLength < DESC_HEADER_LENGTH) {
  252. usbi_err(ctx,
  253. "invalid extra intf desc len (%d)",
  254. header.bLength);
  255. r = LIBUSB_ERROR_IO;
  256. goto err;
  257. } else if (header.bLength > size) {
  258. usbi_warn(ctx,
  259. "short extra intf desc read %d/%d",
  260. size, header.bLength);
  261. return parsed;
  262. }
  263. /* If we find another "proper" descriptor then we're done */
  264. if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
  265. (header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
  266. (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
  267. (header.bDescriptorType == LIBUSB_DT_DEVICE))
  268. break;
  269. buffer += header.bLength;
  270. parsed += header.bLength;
  271. size -= header.bLength;
  272. }
  273. /* Copy any unknown descriptors into a storage area for */
  274. /* drivers to later parse */
  275. len = (int)(buffer - begin);
  276. if (len) {
  277. ifp->extra = malloc(len);
  278. if (!ifp->extra) {
  279. r = LIBUSB_ERROR_NO_MEM;
  280. goto err;
  281. }
  282. memcpy((unsigned char *) ifp->extra, begin, len);
  283. ifp->extra_length = len;
  284. }
  285. if (ifp->bNumEndpoints > 0) {
  286. struct libusb_endpoint_descriptor *endpoint;
  287. tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint_descriptor);
  288. endpoint = malloc(tmp);
  289. ifp->endpoint = endpoint;
  290. if (!endpoint) {
  291. r = LIBUSB_ERROR_NO_MEM;
  292. goto err;
  293. }
  294. memset(endpoint, 0, tmp);
  295. for (i = 0; i < ifp->bNumEndpoints; i++) {
  296. r = parse_endpoint(ctx, endpoint + i, buffer, size,
  297. host_endian);
  298. if (r < 0)
  299. goto err;
  300. if (r == 0) {
  301. ifp->bNumEndpoints = (uint8_t)i;
  302. break;;
  303. }
  304. buffer += r;
  305. parsed += r;
  306. size -= r;
  307. }
  308. }
  309. /* We check to see if it's an alternate to this one */
  310. ifp = (struct libusb_interface_descriptor *) buffer;
  311. if (size < LIBUSB_DT_INTERFACE_SIZE ||
  312. ifp->bDescriptorType != LIBUSB_DT_INTERFACE ||
  313. ifp->bInterfaceNumber != interface_number)
  314. return parsed;
  315. }
  316. return parsed;
  317. err:
  318. clear_interface(usb_interface);
  319. return r;
  320. }
  321. static void clear_configuration(struct libusb_config_descriptor *config)
  322. {
  323. if (config->interface) {
  324. int i;
  325. for (i = 0; i < config->bNumInterfaces; i++)
  326. clear_interface((struct libusb_interface *)
  327. config->interface + i);
  328. free((void *) config->interface);
  329. }
  330. if (config->extra)
  331. free((void *) config->extra);
  332. }
  333. static int parse_configuration(struct libusb_context *ctx,
  334. struct libusb_config_descriptor *config, unsigned char *buffer,
  335. int size, int host_endian)
  336. {
  337. int i;
  338. int r;
  339. size_t tmp;
  340. struct usb_descriptor_header header;
  341. struct libusb_interface *usb_interface;
  342. if (size < LIBUSB_DT_CONFIG_SIZE) {
  343. usbi_err(ctx, "short config descriptor read %d/%d",
  344. size, LIBUSB_DT_CONFIG_SIZE);
  345. return LIBUSB_ERROR_IO;
  346. }
  347. usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian);
  348. if (config->bDescriptorType != LIBUSB_DT_CONFIG) {
  349. usbi_err(ctx, "unexpected descriptor %x (expected %x)",
  350. config->bDescriptorType, LIBUSB_DT_CONFIG);
  351. return LIBUSB_ERROR_IO;
  352. }
  353. if (config->bLength < LIBUSB_DT_CONFIG_SIZE) {
  354. usbi_err(ctx, "invalid config bLength (%d)", config->bLength);
  355. return LIBUSB_ERROR_IO;
  356. }
  357. if (config->bLength > size) {
  358. usbi_err(ctx, "short config descriptor read %d/%d",
  359. size, config->bLength);
  360. return LIBUSB_ERROR_IO;
  361. }
  362. if (config->bNumInterfaces > USB_MAXINTERFACES) {
  363. usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces);
  364. return LIBUSB_ERROR_IO;
  365. }
  366. tmp = config->bNumInterfaces * sizeof(struct libusb_interface);
  367. usb_interface = malloc(tmp);
  368. config->interface = usb_interface;
  369. if (!config->interface)
  370. return LIBUSB_ERROR_NO_MEM;
  371. memset(usb_interface, 0, tmp);
  372. buffer += config->bLength;
  373. size -= config->bLength;
  374. config->extra = NULL;
  375. config->extra_length = 0;
  376. for (i = 0; i < config->bNumInterfaces; i++) {
  377. int len;
  378. unsigned char *begin;
  379. /* Skip over the rest of the Class Specific or Vendor */
  380. /* Specific descriptors */
  381. begin = buffer;
  382. while (size >= DESC_HEADER_LENGTH) {
  383. usbi_parse_descriptor(buffer, "bb", &header, 0);
  384. if (header.bLength < DESC_HEADER_LENGTH) {
  385. usbi_err(ctx,
  386. "invalid extra config desc len (%d)",
  387. header.bLength);
  388. r = LIBUSB_ERROR_IO;
  389. goto err;
  390. } else if (header.bLength > size) {
  391. usbi_warn(ctx,
  392. "short extra config desc read %d/%d",
  393. size, header.bLength);
  394. config->bNumInterfaces = (uint8_t)i;
  395. return size;
  396. }
  397. /* If we find another "proper" descriptor then we're done */
  398. if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
  399. (header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
  400. (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
  401. (header.bDescriptorType == LIBUSB_DT_DEVICE))
  402. break;
  403. usbi_dbg("skipping descriptor 0x%x\n", header.bDescriptorType);
  404. buffer += header.bLength;
  405. size -= header.bLength;
  406. }
  407. /* Copy any unknown descriptors into a storage area for */
  408. /* drivers to later parse */
  409. len = (int)(buffer - begin);
  410. if (len) {
  411. /* FIXME: We should realloc and append here */
  412. if (!config->extra_length) {
  413. config->extra = malloc(len);
  414. if (!config->extra) {
  415. r = LIBUSB_ERROR_NO_MEM;
  416. goto err;
  417. }
  418. memcpy((unsigned char *) config->extra, begin, len);
  419. config->extra_length = len;
  420. }
  421. }
  422. r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian);
  423. if (r < 0)
  424. goto err;
  425. if (r == 0) {
  426. config->bNumInterfaces = (uint8_t)i;
  427. break;
  428. }
  429. buffer += r;
  430. size -= r;
  431. }
  432. return size;
  433. err:
  434. clear_configuration(config);
  435. return r;
  436. }
  437. static int raw_desc_to_config(struct libusb_context *ctx,
  438. unsigned char *buf, int size, int host_endian,
  439. struct libusb_config_descriptor **config)
  440. {
  441. struct libusb_config_descriptor *_config = malloc(sizeof(*_config));
  442. int r;
  443. if (!_config)
  444. return LIBUSB_ERROR_NO_MEM;
  445. r = parse_configuration(ctx, _config, buf, size, host_endian);
  446. if (r < 0) {
  447. usbi_err(ctx, "parse_configuration failed with error %d", r);
  448. free(_config);
  449. return r;
  450. } else if (r > 0) {
  451. usbi_warn(ctx, "still %d bytes of descriptor data left", r);
  452. }
  453. *config = _config;
  454. return LIBUSB_SUCCESS;
  455. }
  456. int usbi_device_cache_descriptor(libusb_device *dev)
  457. {
  458. int r, host_endian = 0;
  459. r = usbi_backend->get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor,
  460. &host_endian);
  461. if (r < 0)
  462. return r;
  463. if (!host_endian) {
  464. dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB);
  465. dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor);
  466. dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct);
  467. dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice);
  468. }
  469. return LIBUSB_SUCCESS;
  470. }
  471. /** \ingroup desc
  472. * Get the USB device descriptor for a given device.
  473. *
  474. * This is a non-blocking function; the device descriptor is cached in memory.
  475. *
  476. * Note since libusbx-1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102, this
  477. * function always succeeds.
  478. *
  479. * \param dev the device
  480. * \param desc output location for the descriptor data
  481. * \returns 0 on success or a LIBUSB_ERROR code on failure
  482. */
  483. int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
  484. struct libusb_device_descriptor *desc)
  485. {
  486. usbi_dbg("");
  487. memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor,
  488. sizeof (dev->device_descriptor));
  489. return 0;
  490. }
  491. /** \ingroup desc
  492. * Get the USB configuration descriptor for the currently active configuration.
  493. * This is a non-blocking function which does not involve any requests being
  494. * sent to the device.
  495. *
  496. * \param dev a device
  497. * \param config output location for the USB configuration descriptor. Only
  498. * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
  499. * after use.
  500. * \returns 0 on success
  501. * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
  502. * \returns another LIBUSB_ERROR code on error
  503. * \see libusb_get_config_descriptor
  504. */
  505. int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
  506. struct libusb_config_descriptor **config)
  507. {
  508. struct libusb_config_descriptor _config;
  509. unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
  510. unsigned char *buf = NULL;
  511. int host_endian = 0;
  512. int r;
  513. r = usbi_backend->get_active_config_descriptor(dev, tmp,
  514. LIBUSB_DT_CONFIG_SIZE, &host_endian);
  515. if (r < 0)
  516. return r;
  517. if (r < LIBUSB_DT_CONFIG_SIZE) {
  518. usbi_err(dev->ctx, "short config descriptor read %d/%d",
  519. r, LIBUSB_DT_CONFIG_SIZE);
  520. return LIBUSB_ERROR_IO;
  521. }
  522. usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
  523. buf = malloc(_config.wTotalLength);
  524. if (!buf)
  525. return LIBUSB_ERROR_NO_MEM;
  526. r = usbi_backend->get_active_config_descriptor(dev, buf,
  527. _config.wTotalLength, &host_endian);
  528. if (r >= 0)
  529. r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
  530. free(buf);
  531. return r;
  532. }
  533. /** \ingroup desc
  534. * Get a USB configuration descriptor based on its index.
  535. * This is a non-blocking function which does not involve any requests being
  536. * sent to the device.
  537. *
  538. * \param dev a device
  539. * \param config_index the index of the configuration you wish to retrieve
  540. * \param config output location for the USB configuration descriptor. Only
  541. * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
  542. * after use.
  543. * \returns 0 on success
  544. * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
  545. * \returns another LIBUSB_ERROR code on error
  546. * \see libusb_get_active_config_descriptor()
  547. * \see libusb_get_config_descriptor_by_value()
  548. */
  549. int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
  550. uint8_t config_index, struct libusb_config_descriptor **config)
  551. {
  552. struct libusb_config_descriptor _config;
  553. unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
  554. unsigned char *buf = NULL;
  555. int host_endian = 0;
  556. int r;
  557. usbi_dbg("index %d", config_index);
  558. if (config_index >= dev->num_configurations)
  559. return LIBUSB_ERROR_NOT_FOUND;
  560. r = usbi_backend->get_config_descriptor(dev, config_index, tmp,
  561. LIBUSB_DT_CONFIG_SIZE, &host_endian);
  562. if (r < 0)
  563. return r;
  564. if (r < LIBUSB_DT_CONFIG_SIZE) {
  565. usbi_err(dev->ctx, "short config descriptor read %d/%d",
  566. r, LIBUSB_DT_CONFIG_SIZE);
  567. return LIBUSB_ERROR_IO;
  568. }
  569. usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
  570. buf = malloc(_config.wTotalLength);
  571. if (!buf)
  572. return LIBUSB_ERROR_NO_MEM;
  573. r = usbi_backend->get_config_descriptor(dev, config_index, buf,
  574. _config.wTotalLength, &host_endian);
  575. if (r >= 0)
  576. r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
  577. free(buf);
  578. return r;
  579. }
  580. /* iterate through all configurations, returning the index of the configuration
  581. * matching a specific bConfigurationValue in the idx output parameter, or -1
  582. * if the config was not found.
  583. * returns 0 on success or a LIBUSB_ERROR code
  584. */
  585. int usbi_get_config_index_by_value(struct libusb_device *dev,
  586. uint8_t bConfigurationValue, int *idx)
  587. {
  588. uint8_t i;
  589. usbi_dbg("value %d", bConfigurationValue);
  590. for (i = 0; i < dev->num_configurations; i++) {
  591. unsigned char tmp[6];
  592. int host_endian;
  593. int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp),
  594. &host_endian);
  595. if (r < 0) {
  596. *idx = -1;
  597. return r;
  598. }
  599. if (tmp[5] == bConfigurationValue) {
  600. *idx = i;
  601. return 0;
  602. }
  603. }
  604. *idx = -1;
  605. return 0;
  606. }
  607. /** \ingroup desc
  608. * Get a USB configuration descriptor with a specific bConfigurationValue.
  609. * This is a non-blocking function which does not involve any requests being
  610. * sent to the device.
  611. *
  612. * \param dev a device
  613. * \param bConfigurationValue the bConfigurationValue of the configuration you
  614. * wish to retrieve
  615. * \param config output location for the USB configuration descriptor. Only
  616. * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
  617. * after use.
  618. * \returns 0 on success
  619. * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
  620. * \returns another LIBUSB_ERROR code on error
  621. * \see libusb_get_active_config_descriptor()
  622. * \see libusb_get_config_descriptor()
  623. */
  624. int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
  625. uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
  626. {
  627. int r, idx, host_endian;
  628. unsigned char *buf = NULL;
  629. if (usbi_backend->get_config_descriptor_by_value) {
  630. r = usbi_backend->get_config_descriptor_by_value(dev,
  631. bConfigurationValue, &buf, &host_endian);
  632. if (r < 0)
  633. return r;
  634. return raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
  635. }
  636. r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
  637. if (r < 0)
  638. return r;
  639. else if (idx == -1)
  640. return LIBUSB_ERROR_NOT_FOUND;
  641. else
  642. return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
  643. }
  644. /** \ingroup desc
  645. * Free a configuration descriptor obtained from
  646. * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
  647. * It is safe to call this function with a NULL config parameter, in which
  648. * case the function simply returns.
  649. *
  650. * \param config the configuration descriptor to free
  651. */
  652. void API_EXPORTED libusb_free_config_descriptor(
  653. struct libusb_config_descriptor *config)
  654. {
  655. if (!config)
  656. return;
  657. clear_configuration(config);
  658. free(config);
  659. }
  660. /** \ingroup desc
  661. * Get an endpoints superspeed endpoint companion descriptor (if any)
  662. *
  663. * \param ctx the context to operate on, or NULL for the default context
  664. * \param endpoint endpoint descriptor from which to get the superspeed
  665. * endpoint companion descriptor
  666. * \param ep_comp output location for the superspeed endpoint companion
  667. * descriptor. Only valid if 0 was returned. Must be freed with
  668. * libusb_free_ss_endpoint_companion_descriptor() after use.
  669. * \returns 0 on success
  670. * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
  671. * \returns another LIBUSB_ERROR code on error
  672. */
  673. int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
  674. struct libusb_context *ctx,
  675. const struct libusb_endpoint_descriptor *endpoint,
  676. struct libusb_ss_endpoint_companion_descriptor **ep_comp)
  677. {
  678. struct usb_descriptor_header header;
  679. int size = endpoint->extra_length;
  680. const unsigned char *buffer = endpoint->extra;
  681. *ep_comp = NULL;
  682. while (size >= DESC_HEADER_LENGTH) {
  683. usbi_parse_descriptor(buffer, "bb", &header, 0);
  684. if (header.bLength < 2 || header.bLength > size) {
  685. usbi_err(ctx, "invalid descriptor length %d",
  686. header.bLength);
  687. return LIBUSB_ERROR_IO;
  688. }
  689. if (header.bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
  690. buffer += header.bLength;
  691. size -= header.bLength;
  692. continue;
  693. }
  694. if (header.bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) {
  695. usbi_err(ctx, "invalid ss-ep-comp-desc length %d",
  696. header.bLength);
  697. return LIBUSB_ERROR_IO;
  698. }
  699. *ep_comp = malloc(sizeof(**ep_comp));
  700. if (*ep_comp == NULL)
  701. return LIBUSB_ERROR_NO_MEM;
  702. usbi_parse_descriptor(buffer, "bbbbw", *ep_comp, 0);
  703. return LIBUSB_SUCCESS;
  704. }
  705. return LIBUSB_ERROR_NOT_FOUND;
  706. }
  707. /** \ingroup desc
  708. * Free a superspeed endpoint companion descriptor obtained from
  709. * libusb_get_ss_endpoint_companion_descriptor().
  710. * It is safe to call this function with a NULL ep_comp parameter, in which
  711. * case the function simply returns.
  712. *
  713. * \param ep_comp the superspeed endpoint companion descriptor to free
  714. */
  715. void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor(
  716. struct libusb_ss_endpoint_companion_descriptor *ep_comp)
  717. {
  718. free(ep_comp);
  719. }
  720. static int parse_bos(struct libusb_context *ctx,
  721. struct libusb_bos_descriptor **bos,
  722. unsigned char *buffer, int size, int host_endian)
  723. {
  724. struct libusb_bos_descriptor bos_header, *_bos;
  725. struct libusb_bos_dev_capability_descriptor dev_cap;
  726. int i;
  727. if (size < LIBUSB_DT_BOS_SIZE) {
  728. usbi_err(ctx, "short bos descriptor read %d/%d",
  729. size, LIBUSB_DT_BOS_SIZE);
  730. return LIBUSB_ERROR_IO;
  731. }
  732. usbi_parse_descriptor(buffer, "bbwb", &bos_header, host_endian);
  733. if (bos_header.bDescriptorType != LIBUSB_DT_BOS) {
  734. usbi_err(ctx, "unexpected descriptor %x (expected %x)",
  735. bos_header.bDescriptorType, LIBUSB_DT_BOS);
  736. return LIBUSB_ERROR_IO;
  737. }
  738. if (bos_header.bLength < LIBUSB_DT_BOS_SIZE) {
  739. usbi_err(ctx, "invalid bos bLength (%d)", bos_header.bLength);
  740. return LIBUSB_ERROR_IO;
  741. }
  742. if (bos_header.bLength > size) {
  743. usbi_err(ctx, "short bos descriptor read %d/%d",
  744. size, bos_header.bLength);
  745. return LIBUSB_ERROR_IO;
  746. }
  747. _bos = calloc (1,
  748. sizeof(*_bos) + bos_header.bNumDeviceCaps * sizeof(void *));
  749. if (!_bos)
  750. return LIBUSB_ERROR_NO_MEM;
  751. usbi_parse_descriptor(buffer, "bbwb", _bos, host_endian);
  752. buffer += bos_header.bLength;
  753. size -= bos_header.bLength;
  754. /* Get the device capability descriptors */
  755. for (i = 0; i < bos_header.bNumDeviceCaps; i++) {
  756. if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
  757. usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
  758. size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
  759. break;
  760. }
  761. usbi_parse_descriptor(buffer, "bbb", &dev_cap, host_endian);
  762. if (dev_cap.bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
  763. usbi_warn(ctx, "unexpected descriptor %x (expected %x)",
  764. dev_cap.bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY);
  765. break;
  766. }
  767. if (dev_cap.bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
  768. usbi_err(ctx, "invalid dev-cap bLength (%d)",
  769. dev_cap.bLength);
  770. libusb_free_bos_descriptor(_bos);
  771. return LIBUSB_ERROR_IO;
  772. }
  773. if (dev_cap.bLength > size) {
  774. usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
  775. size, dev_cap.bLength);
  776. break;
  777. }
  778. _bos->dev_capability[i] = malloc(dev_cap.bLength);
  779. if (!_bos->dev_capability[i]) {
  780. libusb_free_bos_descriptor(_bos);
  781. return LIBUSB_ERROR_NO_MEM;
  782. }
  783. memcpy(_bos->dev_capability[i], buffer, dev_cap.bLength);
  784. buffer += dev_cap.bLength;
  785. size -= dev_cap.bLength;
  786. }
  787. _bos->bNumDeviceCaps = (uint8_t)i;
  788. *bos = _bos;
  789. return LIBUSB_SUCCESS;
  790. }
  791. /** \ingroup desc
  792. * Get a Binary Object Store (BOS) descriptor
  793. * This is a BLOCKING function, which will send requests to the device.
  794. *
  795. * \param handle the handle of an open libusb device
  796. * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
  797. * Must be freed with \ref libusb_free_bos_descriptor() after use.
  798. * \returns 0 on success
  799. * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
  800. * \returns another LIBUSB_ERROR code on error
  801. */
  802. int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle,
  803. struct libusb_bos_descriptor **bos)
  804. {
  805. struct libusb_bos_descriptor _bos;
  806. uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0};
  807. unsigned char *bos_data = NULL;
  808. const int host_endian = 0;
  809. int r;
  810. /* Read the BOS. This generates 2 requests on the bus,
  811. * one for the header, and one for the full BOS */
  812. r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_header,
  813. LIBUSB_DT_BOS_SIZE);
  814. if (r < 0) {
  815. if (r != LIBUSB_ERROR_PIPE)
  816. usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);
  817. return r;
  818. }
  819. if (r < LIBUSB_DT_BOS_SIZE) {
  820. usbi_err(handle->dev->ctx, "short BOS read %d/%d",
  821. r, LIBUSB_DT_BOS_SIZE);
  822. return LIBUSB_ERROR_IO;
  823. }
  824. usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian);
  825. usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities",
  826. _bos.wTotalLength, _bos.bNumDeviceCaps);
  827. bos_data = calloc(_bos.wTotalLength, 1);
  828. if (bos_data == NULL)
  829. return LIBUSB_ERROR_NO_MEM;
  830. r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_data,
  831. _bos.wTotalLength);
  832. if (r >= 0)
  833. r = parse_bos(handle->dev->ctx, bos, bos_data, r, host_endian);
  834. else
  835. usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);
  836. free(bos_data);
  837. return r;
  838. }
  839. /** \ingroup desc
  840. * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
  841. * It is safe to call this function with a NULL bos parameter, in which
  842. * case the function simply returns.
  843. *
  844. * \param bos the BOS descriptor to free
  845. */
  846. void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
  847. {
  848. int i;
  849. if (!bos)
  850. return;
  851. for (i = 0; i < bos->bNumDeviceCaps; i++)
  852. free(bos->dev_capability[i]);
  853. free(bos);
  854. }
  855. /** \ingroup desc
  856. * Get an USB 2.0 Extension descriptor
  857. *
  858. * \param ctx the context to operate on, or NULL for the default context
  859. * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
  860. * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
  861. * LIBUSB_BT_USB_2_0_EXTENSION
  862. * \param usb_2_0_extension output location for the USB 2.0 Extension
  863. * descriptor. Only valid if 0 was returned. Must be freed with
  864. * libusb_free_usb_2_0_extension_descriptor() after use.
  865. * \returns 0 on success
  866. * \returns a LIBUSB_ERROR code on error
  867. */
  868. int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
  869. struct libusb_context *ctx,
  870. struct libusb_bos_dev_capability_descriptor *dev_cap,
  871. struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
  872. {
  873. struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension;
  874. const int host_endian = 0;
  875. if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) {
  876. usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
  877. dev_cap->bDevCapabilityType,
  878. LIBUSB_BT_USB_2_0_EXTENSION);
  879. return LIBUSB_ERROR_INVALID_PARAM;
  880. }
  881. if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) {
  882. usbi_err(ctx, "short dev-cap descriptor read %d/%d",
  883. dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE);
  884. return LIBUSB_ERROR_IO;
  885. }
  886. _usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension));
  887. if (!_usb_2_0_extension)
  888. return LIBUSB_ERROR_NO_MEM;
  889. usbi_parse_descriptor((unsigned char *)dev_cap, "bbbd",
  890. _usb_2_0_extension, host_endian);
  891. *usb_2_0_extension = _usb_2_0_extension;
  892. return LIBUSB_SUCCESS;
  893. }
  894. /** \ingroup desc
  895. * Free a USB 2.0 Extension descriptor obtained from
  896. * libusb_get_usb_2_0_extension_descriptor().
  897. * It is safe to call this function with a NULL usb_2_0_extension parameter,
  898. * in which case the function simply returns.
  899. *
  900. * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
  901. */
  902. void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
  903. struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
  904. {
  905. free(usb_2_0_extension);
  906. }
  907. /** \ingroup desc
  908. * Get a SuperSpeed USB Device Capability descriptor
  909. *
  910. * \param ctx the context to operate on, or NULL for the default context
  911. * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
  912. * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
  913. * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
  914. * \param ss_usb_device_cap output location for the SuperSpeed USB Device
  915. * Capability descriptor. Only valid if 0 was returned. Must be freed with
  916. * libusb_free_ss_usb_device_capability_descriptor() after use.
  917. * \returns 0 on success
  918. * \returns a LIBUSB_ERROR code on error
  919. */
  920. int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
  921. struct libusb_context *ctx,
  922. struct libusb_bos_dev_capability_descriptor *dev_cap,
  923. struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
  924. {
  925. struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap;
  926. const int host_endian = 0;
  927. if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
  928. usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
  929. dev_cap->bDevCapabilityType,
  930. LIBUSB_BT_SS_USB_DEVICE_CAPABILITY);
  931. return LIBUSB_ERROR_INVALID_PARAM;
  932. }
  933. if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) {
  934. usbi_err(ctx, "short dev-cap descriptor read %d/%d",
  935. dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE);
  936. return LIBUSB_ERROR_IO;
  937. }
  938. _ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap));
  939. if (!_ss_usb_device_cap)
  940. return LIBUSB_ERROR_NO_MEM;
  941. usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw",
  942. _ss_usb_device_cap, host_endian);
  943. *ss_usb_device_cap = _ss_usb_device_cap;
  944. return LIBUSB_SUCCESS;
  945. }
  946. /** \ingroup desc
  947. * Free a SuperSpeed USB Device Capability descriptor obtained from
  948. * libusb_get_ss_usb_device_capability_descriptor().
  949. * It is safe to call this function with a NULL ss_usb_device_cap
  950. * parameter, in which case the function simply returns.
  951. *
  952. * \param ss_usb_device_cap the USB 2.0 Extension descriptor to free
  953. */
  954. void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
  955. struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
  956. {
  957. free(ss_usb_device_cap);
  958. }
  959. /** \ingroup desc
  960. * Get a Container ID descriptor
  961. *
  962. * \param ctx the context to operate on, or NULL for the default context
  963. * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
  964. * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
  965. * LIBUSB_BT_CONTAINER_ID
  966. * \param container_id output location for the Container ID descriptor.
  967. * Only valid if 0 was returned. Must be freed with
  968. * libusb_free_container_id_descriptor() after use.
  969. * \returns 0 on success
  970. * \returns a LIBUSB_ERROR code on error
  971. */
  972. int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx,
  973. struct libusb_bos_dev_capability_descriptor *dev_cap,
  974. struct libusb_container_id_descriptor **container_id)
  975. {
  976. struct libusb_container_id_descriptor *_container_id;
  977. const int host_endian = 0;
  978. if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) {
  979. usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
  980. dev_cap->bDevCapabilityType,
  981. LIBUSB_BT_CONTAINER_ID);
  982. return LIBUSB_ERROR_INVALID_PARAM;
  983. }
  984. if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) {
  985. usbi_err(ctx, "short dev-cap descriptor read %d/%d",
  986. dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE);
  987. return LIBUSB_ERROR_IO;
  988. }
  989. _container_id = malloc(sizeof(*_container_id));
  990. if (!_container_id)
  991. return LIBUSB_ERROR_NO_MEM;
  992. usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbu",
  993. _container_id, host_endian);
  994. *container_id = _container_id;
  995. return LIBUSB_SUCCESS;
  996. }
  997. /** \ingroup desc
  998. * Free a Container ID descriptor obtained from
  999. * libusb_get_container_id_descriptor().
  1000. * It is safe to call this function with a NULL container_id parameter,
  1001. * in which case the function simply returns.
  1002. *
  1003. * \param container_id the USB 2.0 Extension descriptor to free
  1004. */
  1005. void API_EXPORTED libusb_free_container_id_descriptor(
  1006. struct libusb_container_id_descriptor *container_id)
  1007. {
  1008. free(container_id);
  1009. }
  1010. /** \ingroup desc
  1011. * Retrieve a string descriptor in C style ASCII.
  1012. *
  1013. * Wrapper around libusb_get_string_descriptor(). Uses the first language
  1014. * supported by the device.
  1015. *
  1016. * \param dev a device handle
  1017. * \param desc_index the index of the descriptor to retrieve
  1018. * \param data output buffer for ASCII string descriptor
  1019. * \param length size of data buffer
  1020. * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
  1021. */
  1022. int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
  1023. uint8_t desc_index, unsigned char *data, int length)
  1024. {
  1025. unsigned char tbuf[255]; /* Some devices choke on size > 255 */
  1026. int r, si, di;
  1027. uint16_t langid;
  1028. /* Asking for the zero'th index is special - it returns a string
  1029. * descriptor that contains all the language IDs supported by the
  1030. * device. Typically there aren't many - often only one. Language
  1031. * IDs are 16 bit numbers, and they start at the third byte in the
  1032. * descriptor. There's also no point in trying to read descriptor 0
  1033. * with this function. See USB 2.0 specification section 9.6.7 for
  1034. * more information.
  1035. */
  1036. if (desc_index == 0)
  1037. return LIBUSB_ERROR_INVALID_PARAM;
  1038. r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf));
  1039. if (r < 0)
  1040. return r;
  1041. if (r < 4)
  1042. return LIBUSB_ERROR_IO;
  1043. langid = tbuf[2] | (tbuf[3] << 8);
  1044. r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf,
  1045. sizeof(tbuf));
  1046. if (r < 0)
  1047. return r;
  1048. if (tbuf[1] != LIBUSB_DT_STRING)
  1049. return LIBUSB_ERROR_IO;
  1050. if (tbuf[0] > r)
  1051. return LIBUSB_ERROR_IO;
  1052. for (di = 0, si = 2; si < tbuf[0]; si += 2) {
  1053. if (di >= (length - 1))
  1054. break;
  1055. if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */
  1056. data[di++] = '?';
  1057. else
  1058. data[di++] = tbuf[si];
  1059. }
  1060. data[di] = 0;
  1061. return di;
  1062. }