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