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