1 /*
2 * windows backend for libusbx 1.0
3 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4 * With contributions from Michael Plante, Orin Eman et al.
5 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
6 * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
7 * Hash table functions adapted from glibc, by Ulrich Drepper et al.
8 * Major code testing contribution by Xiaofan Chen
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #define INITGUID
26 #include <config.h>
27 #include <windows.h>
28 #include <cfgmgr32.h>
29 #include <setupapi.h>
30 #include <usbioctl.h>
31 #include <winusb.h>
32 #include <ctype.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <process.h>
36 #include <stdio.h>
37 #include <inttypes.h>
38 #include <objbase.h>
39 #include <winioctl.h>
40
41 #include "libusbi.h"
42 #include "poll_windows.h"
43 #include "windows_usb.h"
44
45 // The 2 macros below are used in conjunction with safe loops.
46 #define LOOP_CHECK(fcall) { r=fcall; if (r != LIBUSB_SUCCESS) continue; }
47 #define LOOP_BREAK(err) { r=err; continue; }
48
49 // Helper prototypes
50 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian);
51 static int windows_clock_gettime(int clk_id, struct timespec *tp);
52 unsigned __stdcall windows_clock_gettime_threaded(void* param);
53 // Common calls
54 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
55
56 // WinUSB-like API prototypes
57 static int winusbx_init(int sub_api, struct libusb_context *ctx);
58 static int winusbx_exit(int sub_api);
59 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle);
60 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle);
61 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
62 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
63 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
64 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
65 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
66 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
67 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
68 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
69 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer);
70 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
71 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
72 // Composite API prototypes
73 static int composite_init(int sub_api, struct libusb_context *ctx);
74 static int composite_exit(int sub_api);
75 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle);
76 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle);
77 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
78 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
79 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
80 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
81 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
82 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
83 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
84 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
85 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer);
86 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
87 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
88
89
90 // Global variables
91 uint64_t hires_frequency, hires_ticks_to_ps;
92 const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
93 enum windows_version windows_version = WINDOWS_UNSUPPORTED;
94 // Concurrency
95 static int concurrent_usage = -1;
96 usbi_mutex_t autoclaim_lock;
97 // Timer thread
98 // NB: index 0 is for monotonic and 1 is for the thread exit event
99 HANDLE timer_thread = NULL;
100 HANDLE timer_mutex = NULL;
101 struct timespec timer_tp;
102 volatile LONG request_count[2] = {0, 1}; // last one must be > 0
103 HANDLE timer_request[2] = { NULL, NULL };
104 HANDLE timer_response = NULL;
105 // API globals
106 const char* sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES;
107
guid_eq(const GUID * guid1,const GUID * guid2)108 static inline BOOLEAN guid_eq(const GUID *guid1, const GUID *guid2) {
109 if ((guid1 != NULL) && (guid2 != NULL)) {
110 return (memcmp(guid1, guid2, sizeof(GUID)) == 0);
111 }
112 return false;
113 }
114
115 #if defined(ENABLE_LOGGING)
guid_to_string(const GUID * guid)116 static char* guid_to_string(const GUID* guid)
117 {
118 static char guid_string[MAX_GUID_STRING_LENGTH];
119
120 if (guid == NULL) return NULL;
121 sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
122 (unsigned int)guid->Data1, guid->Data2, guid->Data3,
123 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
124 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
125 return guid_string;
126 }
127 #endif
128
129 /*
130 * Converts a windows error to human readable string
131 * uses retval as errorcode, or, if 0, use GetLastError()
132 */
133 #if defined(ENABLE_LOGGING)
windows_error_str(uint32_t retval)134 static char *windows_error_str(uint32_t retval)
135 {
136 static char err_string[ERR_BUFFER_SIZE];
137
138 DWORD size;
139 ssize_t i;
140 uint32_t error_code, format_error;
141
142 error_code = retval?retval:GetLastError();
143
144 safe_sprintf(err_string, ERR_BUFFER_SIZE, "[%u] ", error_code);
145
146 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
147 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
148 ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
149 if (size == 0) {
150 format_error = GetLastError();
151 if (format_error)
152 safe_sprintf(err_string, ERR_BUFFER_SIZE,
153 "Windows error code %u (FormatMessage error code %u)", error_code, format_error);
154 else
155 safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
156 } else {
157 // Remove CR/LF terminators
158 for (i=safe_strlen(err_string)-1; (i>=0) && ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
159 err_string[i] = 0;
160 }
161 }
162 return err_string;
163 }
164 #endif
165
166 /*
167 * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
168 * Return an allocated sanitized string or NULL on error.
169 */
sanitize_path(const char * path)170 static char* sanitize_path(const char* path)
171 {
172 const char root_prefix[] = "\\\\.\\";
173 size_t j, size, root_size;
174 char* ret_path = NULL;
175 size_t add_root = 0;
176
177 if (path == NULL)
178 return NULL;
179
180 size = safe_strlen(path)+1;
181 root_size = sizeof(root_prefix)-1;
182
183 // Microsoft indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
184 if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
185 ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
186 add_root = root_size;
187 size += add_root;
188 }
189
190 if ((ret_path = (char*) calloc(size, 1)) == NULL)
191 return NULL;
192
193 safe_strcpy(&ret_path[add_root], size-add_root, path);
194
195 // Ensure consistancy with root prefix
196 for (j=0; j<root_size; j++)
197 ret_path[j] = root_prefix[j];
198
199 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
200 for(j=root_size; j<size; j++) {
201 ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
202 if (ret_path[j] == '\\')
203 ret_path[j] = '#';
204 }
205
206 return ret_path;
207 }
208
209 /*
210 * enumerate interfaces for the whole USB class
211 *
212 * Parameters:
213 * dev_info: a pointer to a dev_info list
214 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
215 * usb_class: the generic USB class for which to retrieve interface details
216 * index: zero based index of the interface in the device info list
217 *
218 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
219 * structure returned and call this function repeatedly using the same guid (with an
220 * incremented index starting at zero) until all interfaces have been returned.
221 */
get_devinfo_data(struct libusb_context * ctx,HDEVINFO * dev_info,SP_DEVINFO_DATA * dev_info_data,const char * usb_class,unsigned _index)222 static bool get_devinfo_data(struct libusb_context *ctx,
223 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char* usb_class, unsigned _index)
224 {
225 if (_index <= 0) {
226 *dev_info = SetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
227 if (*dev_info == INVALID_HANDLE_VALUE) {
228 return false;
229 }
230 }
231
232 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
233 if (!SetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
234 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
235 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
236 _index, windows_error_str(0));
237 }
238 SetupDiDestroyDeviceInfoList(*dev_info);
239 *dev_info = INVALID_HANDLE_VALUE;
240 return false;
241 }
242 return true;
243 }
244
245 /*
246 * enumerate interfaces for a specific GUID
247 *
248 * Parameters:
249 * dev_info: a pointer to a dev_info list
250 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
251 * guid: the GUID for which to retrieve interface details
252 * index: zero based index of the interface in the device info list
253 *
254 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
255 * structure returned and call this function repeatedly using the same guid (with an
256 * incremented index starting at zero) until all interfaces have been returned.
257 */
get_interface_details(struct libusb_context * ctx,HDEVINFO * dev_info,SP_DEVINFO_DATA * dev_info_data,const GUID * guid,unsigned _index)258 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details(struct libusb_context *ctx,
259 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index)
260 {
261 SP_DEVICE_INTERFACE_DATA dev_interface_data;
262 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
263 DWORD size;
264
265 if (_index <= 0) {
266 *dev_info = SetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
267 }
268
269 if (dev_info_data != NULL) {
270 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
271 if (!SetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
272 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
273 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
274 _index, windows_error_str(0));
275 }
276 SetupDiDestroyDeviceInfoList(*dev_info);
277 *dev_info = INVALID_HANDLE_VALUE;
278 return NULL;
279 }
280 }
281
282 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
283 if (!SetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
284 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
285 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
286 _index, windows_error_str(0));
287 }
288 SetupDiDestroyDeviceInfoList(*dev_info);
289 *dev_info = INVALID_HANDLE_VALUE;
290 return NULL;
291 }
292
293 // Read interface data (dummy + actual) to access the device path
294 if (!SetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
295 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
296 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
297 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
298 _index, windows_error_str(0));
299 goto err_exit;
300 }
301 } else {
302 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
303 goto err_exit;
304 }
305
306 if ((dev_interface_details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) calloc(size, 1)) == NULL) {
307 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
308 goto err_exit;
309 }
310
311 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
312 if (!SetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
313 dev_interface_details, size, &size, NULL)) {
314 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
315 _index, windows_error_str(0));
316 }
317
318 return dev_interface_details;
319
320 err_exit:
321 SetupDiDestroyDeviceInfoList(*dev_info);
322 *dev_info = INVALID_HANDLE_VALUE;
323 return NULL;
324 }
325
326 /* For libusb0 filter */
get_interface_details_filter(struct libusb_context * ctx,HDEVINFO * dev_info,SP_DEVINFO_DATA * dev_info_data,const GUID * guid,unsigned _index,char * filter_path)327 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
328 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index, char* filter_path){
329 SP_DEVICE_INTERFACE_DATA dev_interface_data;
330 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
331 DWORD size;
332 if (_index <= 0) {
333 *dev_info = SetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
334 }
335 if (dev_info_data != NULL) {
336 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
337 if (!SetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
338 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
339 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
340 _index, windows_error_str(0));
341 }
342 SetupDiDestroyDeviceInfoList(*dev_info);
343 *dev_info = INVALID_HANDLE_VALUE;
344 return NULL;
345 }
346 }
347 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
348 if (!SetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
349 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
350 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
351 _index, windows_error_str(0));
352 }
353 SetupDiDestroyDeviceInfoList(*dev_info);
354 *dev_info = INVALID_HANDLE_VALUE;
355 return NULL;
356 }
357 // Read interface data (dummy + actual) to access the device path
358 if (!SetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
359 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
360 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
361 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
362 _index, windows_error_str(0));
363 goto err_exit;
364 }
365 } else {
366 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
367 goto err_exit;
368 }
369 if ((dev_interface_details = malloc(size)) == NULL) {
370 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
371 goto err_exit;
372 }
373 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
374 if (!SetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
375 dev_interface_details, size, &size, NULL)) {
376 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
377 _index, windows_error_str(0));
378 }
379 // [trobinso] lookup the libusb0 symbolic index.
380 if (dev_interface_details) {
381 HKEY hkey_device_interface=SetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ);
382 if (hkey_device_interface != INVALID_HANDLE_VALUE) {
383 DWORD libusb0_symboliclink_index=0;
384 DWORD value_length=sizeof(DWORD);
385 DWORD value_type=0;
386 LONG status;
387 status = RegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type,
388 (LPBYTE) &libusb0_symboliclink_index, &value_length);
389 if (status == ERROR_SUCCESS) {
390 if (libusb0_symboliclink_index < 256) {
391 // libusb0.sys is connected to this device instance.
392 // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
393 safe_sprintf(filter_path, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index);
394 usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
395 } else {
396 // libusb0.sys was connected to this device instance at one time; but not anymore.
397 }
398 }
399 RegCloseKey(hkey_device_interface);
400 }
401 }
402 return dev_interface_details;
403 err_exit:
404 SetupDiDestroyDeviceInfoList(*dev_info);
405 *dev_info = INVALID_HANDLE_VALUE;
406 return NULL;}
407
408 /* Hash table functions - modified From glibc 2.3.2:
409 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
410 [Knuth] The Art of Computer Programming, part 3 (6.4) */
411 typedef struct htab_entry {
412 unsigned long used;
413 char* str;
414 } htab_entry;
415 htab_entry* htab_table = NULL;
416 usbi_mutex_t htab_write_mutex = NULL;
417 unsigned long htab_size, htab_filled;
418
419 /* For the used double hash method the table size has to be a prime. To
420 correct the user given table size we need a prime test. This trivial
421 algorithm is adequate because the code is called only during init and
422 the number is likely to be small */
isprime(unsigned long number)423 static int isprime(unsigned long number)
424 {
425 // no even number will be passed
426 unsigned int divider = 3;
427
428 while((divider * divider < number) && (number % divider != 0))
429 divider += 2;
430
431 return (number % divider != 0);
432 }
433
434 /* Before using the hash table we must allocate memory for it.
435 We allocate one element more as the found prime number says.
436 This is done for more effective indexing as explained in the
437 comment for the hash function. */
htab_create(struct libusb_context * ctx,unsigned long nel)438 static int htab_create(struct libusb_context *ctx, unsigned long nel)
439 {
440 if (htab_table != NULL) {
441 usbi_err(ctx, "hash table already allocated");
442 }
443
444 // Create a mutex
445 usbi_mutex_init(&htab_write_mutex, NULL);
446
447 // Change nel to the first prime number not smaller as nel.
448 nel |= 1;
449 while(!isprime(nel))
450 nel += 2;
451
452 htab_size = nel;
453 usbi_dbg("using %d entries hash table", nel);
454 htab_filled = 0;
455
456 // allocate memory and zero out.
457 htab_table = (htab_entry*) calloc(htab_size + 1, sizeof(htab_entry));
458 if (htab_table == NULL) {
459 usbi_err(ctx, "could not allocate space for hash table");
460 return 0;
461 }
462
463 return 1;
464 }
465
466 /* After using the hash table it has to be destroyed. */
htab_destroy(void)467 static void htab_destroy(void)
468 {
469 size_t i;
470 if (htab_table == NULL) {
471 return;
472 }
473
474 for (i=0; i<htab_size; i++) {
475 if (htab_table[i].used) {
476 safe_free(htab_table[i].str);
477 }
478 }
479 usbi_mutex_destroy(&htab_write_mutex);
480 safe_free(htab_table);
481 }
482
483 /* This is the search function. It uses double hashing with open addressing.
484 We use an trick to speed up the lookup. The table is created with one
485 more element available. This enables us to use the index zero special.
486 This index will never be used because we store the first hash index in
487 the field used where zero means not used. Every other value means used.
488 The used field can be used as a first fast comparison for equality of
489 the stored and the parameter value. This helps to prevent unnecessary
490 expensive calls of strcmp. */
htab_hash(char * str)491 static unsigned long htab_hash(char* str)
492 {
493 unsigned long hval, hval2;
494 unsigned long idx;
495 unsigned long r = 5381;
496 int c;
497 char* sz = str;
498
499 if (str == NULL)
500 return 0;
501
502 // Compute main hash value (algorithm suggested by Nokia)
503 while ((c = *sz++) != 0)
504 r = ((r << 5) + r) + c;
505 if (r == 0)
506 ++r;
507
508 // compute table hash: simply take the modulus
509 hval = r % htab_size;
510 if (hval == 0)
511 ++hval;
512
513 // Try the first index
514 idx = hval;
515
516 if (htab_table[idx].used) {
517 if ( (htab_table[idx].used == hval)
518 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
519 // existing hash
520 return idx;
521 }
522 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
523
524 // Second hash function, as suggested in [Knuth]
525 hval2 = 1 + hval % (htab_size - 2);
526
527 do {
528 // Because size is prime this guarantees to step through all available indexes
529 if (idx <= hval2) {
530 idx = htab_size + idx - hval2;
531 } else {
532 idx -= hval2;
533 }
534
535 // If we visited all entries leave the loop unsuccessfully
536 if (idx == hval) {
537 break;
538 }
539
540 // If entry is found use it.
541 if ( (htab_table[idx].used == hval)
542 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
543 return idx;
544 }
545 }
546 while (htab_table[idx].used);
547 }
548
549 // Not found => New entry
550
551 // If the table is full return an error
552 if (htab_filled >= htab_size) {
553 usbi_err(NULL, "hash table is full (%d entries)", htab_size);
554 return 0;
555 }
556
557 // Concurrent threads might be storing the same entry at the same time
558 // (eg. "simultaneous" enums from different threads) => use a mutex
559 usbi_mutex_lock(&htab_write_mutex);
560 // Just free any previously allocated string (which should be the same as
561 // new one). The possibility of concurrent threads storing a collision
562 // string (same hash, different string) at the same time is extremely low
563 safe_free(htab_table[idx].str);
564 htab_table[idx].used = hval;
565 htab_table[idx].str = (char*) malloc(safe_strlen(str)+1);
566 if (htab_table[idx].str == NULL) {
567 usbi_err(NULL, "could not duplicate string for hash table");
568 usbi_mutex_unlock(&htab_write_mutex);
569 return 0;
570 }
571 memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
572 ++htab_filled;
573 usbi_mutex_unlock(&htab_write_mutex);
574
575 return idx;
576 }
577
578 /*
579 * Returns the session ID of a device's nth level ancestor
580 * If there's no device at the nth level, return 0
581 */
get_ancestor_session_id(DWORD devinst,unsigned level)582 static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
583 {
584 DWORD parent_devinst;
585 unsigned long session_id = 0;
586 char* sanitized_path = NULL;
587 char path[MAX_PATH_LENGTH];
588 unsigned i;
589
590 if (level < 1) return 0;
591 for (i = 0; i<level; i++) {
592 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
593 return 0;
594 }
595 devinst = parent_devinst;
596 }
597 if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
598 return 0;
599 }
600 // TODO: (post hotplug): try without sanitizing
601 sanitized_path = sanitize_path(path);
602 if (sanitized_path == NULL) {
603 return 0;
604 }
605 session_id = htab_hash(sanitized_path);
606 safe_free(sanitized_path);
607 return session_id;
608 }
609
610 /*
611 * Populate the endpoints addresses of the device_priv interface helper structs
612 */
windows_assign_endpoints(struct libusb_device_handle * dev_handle,int iface,int altsetting)613 static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
614 {
615 int i, r;
616 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
617 struct libusb_config_descriptor *conf_desc;
618 const struct libusb_interface_descriptor *if_desc;
619 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
620
621 r = libusb_get_config_descriptor(dev_handle->dev, 0, &conf_desc);
622 if (r != LIBUSB_SUCCESS) {
623 usbi_warn(ctx, "could not read config descriptor: error %d", r);
624 return r;
625 }
626
627 if (iface >= conf_desc->bNumInterfaces ||
628 altsetting >= conf_desc->interface[iface].num_altsetting) {
629 usbi_dbg("interface %d, altsetting %d out of range", iface, altsetting);
630 return LIBUSB_ERROR_INVALID_PARAM;
631 }
632
633 if_desc = &conf_desc->interface[iface].altsetting[altsetting];
634 safe_free(priv->usb_interface[iface].endpoint);
635
636 if (if_desc->bNumEndpoints == 0) {
637 usbi_dbg("no endpoints found for interface %d", iface);
638 return LIBUSB_SUCCESS;
639 }
640
641 priv->usb_interface[iface].endpoint = (uint8_t*) malloc(if_desc->bNumEndpoints);
642 if (priv->usb_interface[iface].endpoint == NULL) {
643 return LIBUSB_ERROR_NO_MEM;
644 }
645
646 priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
647 for (i=0; i<if_desc->bNumEndpoints; i++) {
648 priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
649 usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface);
650 }
651 libusb_free_config_descriptor(conf_desc);
652
653 // Extra init may be required to configure endpoints
654 return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
655 }
656
657 // Lookup for a match in the list of API driver names
658 // return -1 if not found, driver match number otherwise
get_sub_api(char * driver,int api)659 static int get_sub_api(char* driver, int api){
660 int i;
661 const char sep_str[2] = {LIST_SEPARATOR, 0};
662 char *tok, *tmp_str;
663 size_t len = safe_strlen(driver);
664
665 if (len == 0) return SUB_API_NOTSET;
666 tmp_str = (char*) calloc(len+1, 1);
667 if (tmp_str == NULL) return SUB_API_NOTSET;
668 memcpy(tmp_str, driver, len+1);
669 tok = strtok(tmp_str, sep_str);
670 while (tok != NULL) {
671 for (i=0; i<usb_api_backend[api].nb_driver_names; i++) {
672 if (safe_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
673 free(tmp_str);
674 return i;
675 }
676 }
677 tok = strtok(NULL, sep_str);
678 }
679 free (tmp_str);
680 return SUB_API_NOTSET;
681 }
682
683 /*
684 * auto-claiming and auto-release helper functions
685 */
auto_claim(struct libusb_transfer * transfer,int * interface_number,int api_type)686 static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
687 {
688 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
689 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
690 transfer->dev_handle);
691 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
692 int current_interface = *interface_number;
693 int r = LIBUSB_SUCCESS;
694
695 switch(api_type) {
696 case USB_API_WINUSBX:
697 break;
698 default:
699 return LIBUSB_ERROR_INVALID_PARAM;
700 }
701
702 usbi_mutex_lock(&autoclaim_lock);
703 if (current_interface < 0) // No serviceable interface was found
704 {
705 for (current_interface=0; current_interface<USB_MAXINTERFACES; current_interface++) {
706 // Must claim an interface of the same API type
707 if ( (priv->usb_interface[current_interface].apib->id == api_type)
708 && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS) ) {
709 usbi_dbg("auto-claimed interface %d for control request", current_interface);
710 if (handle_priv->autoclaim_count[current_interface] != 0) {
711 usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero");
712 }
713 handle_priv->autoclaim_count[current_interface]++;
714 break;
715 }
716 }
717 if (current_interface == USB_MAXINTERFACES) {
718 usbi_err(ctx, "could not auto-claim any interface");
719 r = LIBUSB_ERROR_NOT_FOUND;
720 }
721 } else {
722 // If we have a valid interface that was autoclaimed, we must increment
723 // its autoclaim count so that we can prevent an early release.
724 if (handle_priv->autoclaim_count[current_interface] != 0) {
725 handle_priv->autoclaim_count[current_interface]++;
726 }
727 }
728 usbi_mutex_unlock(&autoclaim_lock);
729
730 *interface_number = current_interface;
731 return r;
732
733 }
734
auto_release(struct usbi_transfer * itransfer)735 static void auto_release(struct usbi_transfer *itransfer)
736 {
737 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
738 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
739 libusb_device_handle *dev_handle = transfer->dev_handle;
740 struct windows_device_handle_priv* handle_priv = _device_handle_priv(dev_handle);
741 int r;
742
743 usbi_mutex_lock(&autoclaim_lock);
744 if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
745 handle_priv->autoclaim_count[transfer_priv->interface_number]--;
746 if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
747 r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
748 if (r == LIBUSB_SUCCESS) {
749 usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
750 } else {
751 usbi_dbg("failed to auto-release interface %d (%s)",
752 transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
753 }
754 }
755 }
756 usbi_mutex_unlock(&autoclaim_lock);
757 }
758
759 /*
760 * init: libusbx backend init function
761 *
762 * This function enumerates the HCDs (Host Controller Drivers) and populates our private HCD list
763 * In our implementation, we equate Windows' "HCD" to libusbx's "bus". Note that bus is zero indexed.
764 * HCDs are not expected to change after init (might not hold true for hot pluggable USB PCI card?)
765 */
windows_init(struct libusb_context * ctx)766 static int windows_init(struct libusb_context *ctx)
767 {
768 int i, r = LIBUSB_ERROR_OTHER;
769 OSVERSIONINFO os_version;
770 HANDLE semaphore;
771 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
772
773 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
774 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
775 if (semaphore == NULL) {
776 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
777 return LIBUSB_ERROR_NO_MEM;
778 }
779
780 // A successful wait brings our semaphore count to 0 (unsignaled)
781 // => any concurent wait stalls until the semaphore's release
782 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
783 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
784 CloseHandle(semaphore);
785 return LIBUSB_ERROR_NO_MEM;
786 }
787
788 // NB: concurrent usage supposes that init calls are equally balanced with
789 // exit calls. If init is called more than exit, we will not exit properly
790 if ( ++concurrent_usage == 0 ) { // First init?
791 // Detect OS version
792 memset(&os_version, 0, sizeof(OSVERSIONINFO));
793 os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
794 windows_version = WINDOWS_UNSUPPORTED;
795 if ((GetVersionEx(&os_version) != 0) && (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
796 if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 1)) {
797 windows_version = WINDOWS_XP;
798 } else if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 2)) {
799 windows_version = WINDOWS_2003; // also includes XP 64
800 } else if (os_version.dwMajorVersion >= 6) {
801 windows_version = WINDOWS_VISTA_AND_LATER;
802 }
803 }
804 if (windows_version == WINDOWS_UNSUPPORTED) {
805 usbi_err(ctx, "This version of Windows is NOT supported");
806 r = LIBUSB_ERROR_NOT_SUPPORTED;
807 goto init_exit;
808 }
809
810 // We need a lock for proper auto-release
811 usbi_mutex_init(&autoclaim_lock, NULL);
812
813 // Initialize pollable file descriptors
814 init_polling();
815
816 // Initialize the low level APIs (we don't care about errors at this stage)
817 for (i=0; i<USB_API_MAX; i++) {
818 usb_api_backend[i].init(SUB_API_NOTSET, ctx);
819 }
820
821 // Because QueryPerformanceCounter might report different values when
822 // running on different cores, we create a separate thread for the timer
823 // calls, which we glue to the first core always to prevent timing discrepancies.
824 r = LIBUSB_ERROR_NO_MEM;
825 for (i = 0; i < 2; i++) {
826 timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
827 if (timer_request[i] == NULL) {
828 usbi_err(ctx, "could not create timer request event %d - aborting", i);
829 goto init_exit;
830 }
831 }
832 timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
833 if (timer_response == NULL) {
834 usbi_err(ctx, "could not create timer response semaphore - aborting");
835 goto init_exit;
836 }
837 timer_mutex = CreateMutex(NULL, FALSE, NULL);
838 if (timer_mutex == NULL) {
839 usbi_err(ctx, "could not create timer mutex - aborting");
840 goto init_exit;
841 }
842 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, NULL, 0, NULL);
843 if (timer_thread == NULL) {
844 usbi_err(ctx, "Unable to create timer thread - aborting");
845 goto init_exit;
846 }
847 SetThreadAffinityMask(timer_thread, 0);
848
849 // Wait for timer thread to init before continuing.
850 if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
851 usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
852 goto init_exit;
853 }
854
855 // Create a hash table to store session ids. Second parameter is better if prime
856 htab_create(ctx, HTAB_SIZE);
857 }
858 // At this stage, either we went through full init successfully, or didn't need to
859 r = LIBUSB_SUCCESS;
860
861 init_exit: // Holds semaphore here.
862 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
863 if (timer_thread) {
864 SetEvent(timer_request[1]); // actually the signal to quit the thread.
865 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
866 usbi_warn(ctx, "could not wait for timer thread to quit");
867 TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
868 // all objects it might have held anyway.
869 }
870 CloseHandle(timer_thread);
871 timer_thread = NULL;
872 }
873 for (i = 0; i < 2; i++) {
874 if (timer_request[i]) {
875 CloseHandle(timer_request[i]);
876 timer_request[i] = NULL;
877 }
878 }
879 if (timer_response) {
880 CloseHandle(timer_response);
881 timer_response = NULL;
882 }
883 if (timer_mutex) {
884 CloseHandle(timer_mutex);
885 timer_mutex = NULL;
886 }
887 htab_destroy();
888 }
889
890 if (r != LIBUSB_SUCCESS)
891 --concurrent_usage; // Not expected to call libusb_exit if we failed.
892
893 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
894 CloseHandle(semaphore);
895 return r;
896 }
897
898 /*
899 * HCD (root) hubs need to have their device descriptor manually populated
900 *
901 * Note that, like Microsoft does in the device manager, we populate the
902 * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device.
903 */
force_hcd_device_descriptor(struct libusb_device * dev)904 static int force_hcd_device_descriptor(struct libusb_device *dev)
905 {
906 struct windows_device_priv *parent_priv, *priv = _device_priv(dev);
907 struct libusb_context *ctx = DEVICE_CTX(dev);
908 int vid, pid;
909
910 dev->num_configurations = 1;
911 priv->dev_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
912 priv->dev_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
913 priv->dev_descriptor.bNumConfigurations = 1;
914 priv->active_config = 1;
915
916 if (priv->parent_dev == NULL) {
917 usbi_err(ctx, "program assertion failed - HCD hub has no parent");
918 return LIBUSB_ERROR_NO_DEVICE;
919 }
920 parent_priv = _device_priv(priv->parent_dev);
921 if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) {
922 priv->dev_descriptor.idVendor = (uint16_t)vid;
923 priv->dev_descriptor.idProduct = (uint16_t)pid;
924 } else {
925 usbi_warn(ctx, "could not infer VID/PID of HCD hub from '%s'", parent_priv->path);
926 priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub
927 priv->dev_descriptor.idProduct = 1;
928 }
929 return LIBUSB_SUCCESS;
930 }
931
932 /*
933 * fetch and cache all the config descriptors through I/O
934 */
cache_config_descriptors(struct libusb_device * dev,HANDLE hub_handle,char * device_id)935 static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char* device_id)
936 {
937 DWORD size, ret_size;
938 struct libusb_context *ctx = DEVICE_CTX(dev);
939 struct windows_device_priv *priv = _device_priv(dev);
940 int r;
941 uint8_t i;
942
943 USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
944 PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
945 PUSB_CONFIGURATION_DESCRIPTOR cd_data = NULL;
946
947 if (dev->num_configurations == 0)
948 return LIBUSB_ERROR_INVALID_PARAM;
949
950 priv->config_descriptor = (unsigned char**) calloc(dev->num_configurations, sizeof(unsigned char*));
951 if (priv->config_descriptor == NULL)
952 return LIBUSB_ERROR_NO_MEM;
953 for (i=0; i<dev->num_configurations; i++)
954 priv->config_descriptor[i] = NULL;
955
956 for (i=0, r=LIBUSB_SUCCESS; ; i++)
957 {
958 // safe loop: release all dynamic resources
959 safe_free(cd_buf_actual);
960
961 // safe loop: end of loop condition
962 if ((i >= dev->num_configurations) || (r != LIBUSB_SUCCESS))
963 break;
964
965 size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT);
966 memset(&cd_buf_short, 0, size);
967
968 cd_buf_short.req.ConnectionIndex = (ULONG)priv->port;
969 cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
970 cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
971 cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
972 cd_buf_short.req.SetupPacket.wIndex = i;
973 cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
974
975 // Dummy call to get the required data size. Initial failures are reported as info rather
976 // than error as they can occur for non-penalizing situations, such as with some hubs.
977 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
978 &cd_buf_short, size, &ret_size, NULL)) {
979 usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
980 LOOP_BREAK(LIBUSB_ERROR_IO);
981 }
982
983 if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
984 usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
985 LOOP_BREAK(LIBUSB_ERROR_IO);
986 }
987
988 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
989 if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
990 usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
991 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
992 }
993 memset(cd_buf_actual, 0, size);
994
995 // Actual call
996 cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
997 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
998 cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
999 cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1000 cd_buf_actual->SetupPacket.wIndex = i;
1001 cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1002
1003 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1004 cd_buf_actual, size, &ret_size, NULL)) {
1005 usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1006 LOOP_BREAK(LIBUSB_ERROR_IO);
1007 }
1008
1009 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1010
1011 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1012 usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1013 LOOP_BREAK(LIBUSB_ERROR_IO);
1014 }
1015
1016 if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1017 usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1018 LOOP_BREAK(LIBUSB_ERROR_IO);
1019 }
1020
1021 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1022 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1023
1024 // Cache the descriptor
1025 priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1026 if (priv->config_descriptor[i] == NULL)
1027 return LIBUSB_ERROR_NO_MEM;
1028 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1029 }
1030 return LIBUSB_SUCCESS;
1031 }
1032
1033 /*
1034 * Populate a libusbx device structure
1035 */
init_device(struct libusb_device * dev,struct libusb_device * parent_dev,uint8_t port_number,char * device_id,DWORD devinst)1036 static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1037 uint8_t port_number, char* device_id, DWORD devinst)
1038 {
1039 HANDLE handle;
1040 DWORD size;
1041 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1042 struct windows_device_priv *priv, *parent_priv;
1043 struct libusb_context *ctx = DEVICE_CTX(dev);
1044 struct libusb_device* tmp_dev;
1045 unsigned i;
1046
1047 if ((dev == NULL) || (parent_dev == NULL)) {
1048 return LIBUSB_ERROR_NOT_FOUND;
1049 }
1050 priv = _device_priv(dev);
1051 parent_priv = _device_priv(parent_dev);
1052 if (parent_priv->apib->id != USB_API_HUB) {
1053 usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1054 return LIBUSB_ERROR_NOT_FOUND;
1055 }
1056
1057 // It is possible for the parent hub not to have been initialized yet
1058 // If that's the case, lookup the ancestors to set the bus number
1059 if (parent_dev->bus_number == 0) {
1060 for (i=2; ; i++) {
1061 tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
1062 if (tmp_dev == NULL) break;
1063 if (tmp_dev->bus_number != 0) {
1064 usbi_dbg("got bus number from ancestor #%d", i);
1065 parent_dev->bus_number = tmp_dev->bus_number;
1066 break;
1067 }
1068 }
1069 }
1070 if (parent_dev->bus_number == 0) {
1071 usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1072 return LIBUSB_ERROR_NOT_FOUND;
1073 }
1074 dev->bus_number = parent_dev->bus_number;
1075 priv->port = port_number;
1076 dev->port_number = port_number;
1077 priv->depth = parent_priv->depth + 1;
1078 priv->parent_dev = parent_dev;
1079 if (dev->parent_dev != parent_dev) {
1080 safe_unref_device(dev->parent_dev);
1081 dev->parent_dev = libusb_ref_device(parent_dev);
1082 }
1083
1084 // If the device address is already set, we can stop here
1085 if (dev->device_address != 0) {
1086 return LIBUSB_SUCCESS;
1087 }
1088 memset(&conn_info, 0, sizeof(conn_info));
1089 if (priv->depth != 0) { // Not a HCD hub
1090 handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1091 FILE_FLAG_OVERLAPPED, NULL);
1092 if (handle == INVALID_HANDLE_VALUE) {
1093 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1094 return LIBUSB_ERROR_ACCESS;
1095 }
1096 size = sizeof(conn_info);
1097 conn_info.ConnectionIndex = (ULONG)port_number;
1098 if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1099 &conn_info, size, &size, NULL)) {
1100 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1101 device_id, windows_error_str(0));
1102 safe_closehandle(handle);
1103 return LIBUSB_ERROR_NO_DEVICE;
1104 }
1105 if (conn_info.ConnectionStatus == NoDeviceConnected) {
1106 usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1107 safe_closehandle(handle);
1108 return LIBUSB_ERROR_NO_DEVICE;
1109 }
1110 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1111 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1112 priv->active_config = conn_info.CurrentConfigurationValue;
1113 usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1114 // If we can't read the config descriptors, just set the number of confs to zero
1115 if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1116 dev->num_configurations = 0;
1117 priv->dev_descriptor.bNumConfigurations = 0;
1118 }
1119 safe_closehandle(handle);
1120
1121 if (conn_info.DeviceAddress > UINT8_MAX) {
1122 usbi_err(ctx, "program assertion failed: device address overflow");
1123 }
1124 dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1125 if (dev->device_address == 1) {
1126 usbi_err(ctx, "program assertion failed: device address collision with root hub");
1127 }
1128 switch (conn_info.Speed) {
1129 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1130 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1131 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1132 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1133 default:
1134 usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1135 break;
1136 }
1137 } else {
1138 dev->device_address = 1; // root hubs are set to use device number 1
1139 force_hcd_device_descriptor(dev);
1140 }
1141
1142 usbi_sanitize_device(dev);
1143
1144 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1145 dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1146
1147 return LIBUSB_SUCCESS;
1148 }
1149
1150 // Returns the api type, or 0 if not found/unsupported
get_api_type(struct libusb_context * ctx,HDEVINFO * dev_info,SP_DEVINFO_DATA * dev_info_data,int * api,int * sub_api)1151 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1152 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1153 {
1154 // Precedence for filter drivers vs driver is in the order of this array
1155 struct driver_lookup lookup[3] = {
1156 {"\0\0", SPDRP_SERVICE, "driver"},
1157 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1158 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1159 };
1160 DWORD size, reg_type;
1161 unsigned k, l;
1162 int i, j;
1163
1164 *api = USB_API_UNSUPPORTED;
1165 *sub_api = SUB_API_NOTSET;
1166 // Check the service & filter names to know the API we should use
1167 for (k=0; k<3; k++) {
1168 if (SetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1169 ®_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1170 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1171 if (lookup[k].reg_prop == SPDRP_SERVICE) {
1172 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1173 lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1174 }
1175 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1176 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1177 // (currently ';'), so even if an unsuported one does, it's not an issue
1178 for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1179 if (lookup[k].list[l] == 0) {
1180 lookup[k].list[l] = LIST_SEPARATOR;
1181 }
1182 }
1183 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1184 } else {
1185 if (GetLastError() != ERROR_INVALID_DATA) {
1186 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1187 }
1188 lookup[k].list[0] = 0;
1189 }
1190 }
1191
1192 for (i=1; i<USB_API_MAX; i++) {
1193 for (k=0; k<3; k++) {
1194 j = get_sub_api(lookup[k].list, i);
1195 if (j >= 0) {
1196 usbi_dbg("matched %s name against %s API",
1197 lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1198 *api = i;
1199 *sub_api = j;
1200 return;
1201 }
1202 }
1203 }
1204 }
1205
set_composite_interface(struct libusb_context * ctx,struct libusb_device * dev,char * dev_interface_path,char * device_id,int api,int sub_api)1206 static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1207 char* dev_interface_path, char* device_id, int api, int sub_api)
1208 {
1209 unsigned i;
1210 struct windows_device_priv *priv = _device_priv(dev);
1211 int interface_number;
1212
1213 if (priv->apib->id != USB_API_COMPOSITE) {
1214 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1215 return LIBUSB_ERROR_NO_DEVICE;
1216 }
1217
1218 // Because MI_## are not necessarily in sequential order (some composite
1219 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1220 // interface number from the path's MI value
1221 interface_number = 0;
1222 for (i=0; device_id[i] != 0; ) {
1223 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1224 && (device_id[i++] == '_') ) {
1225 interface_number = (device_id[i++] - '0')*10;
1226 interface_number += device_id[i] - '0';
1227 break;
1228 }
1229 }
1230
1231 if (device_id[i] == 0) {
1232 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1233 device_id, interface_number);
1234 }
1235
1236 if (priv->usb_interface[interface_number].path != NULL) {
1237 safe_free(priv->usb_interface[interface_number].path);
1238 }
1239
1240 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1241 priv->usb_interface[interface_number].path = dev_interface_path;
1242 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1243 priv->usb_interface[interface_number].sub_api = sub_api;
1244
1245 return LIBUSB_SUCCESS;
1246 }
1247
1248 /*
1249 * get_device_list: libusbx backend device enumeration function
1250 */
windows_get_device_list(struct libusb_context * ctx,struct discovered_devs ** _discdevs)1251 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1252 {
1253 struct discovered_devs *discdevs;
1254 HDEVINFO dev_info = { 0 };
1255 const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1256 SP_DEVINFO_DATA dev_info_data = { 0 };
1257 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1258 #define MAX_ENUM_GUIDS 64
1259 const GUID* guid[MAX_ENUM_GUIDS];
1260 #define HCD_PASS 0
1261 #define HUB_PASS 1
1262 #define GEN_PASS 2
1263 #define DEV_PASS 3
1264 int r = LIBUSB_SUCCESS;
1265 int api, sub_api;
1266 size_t class_index = 0;
1267 unsigned int nb_guids, pass, i, j, ancestor;
1268 char path[MAX_PATH_LENGTH];
1269 char strbuf[MAX_PATH_LENGTH];
1270 struct libusb_device *dev, *parent_dev;
1271 struct windows_device_priv *priv, *parent_priv;
1272 char* dev_interface_path = NULL;
1273 char* dev_id_path = NULL;
1274 unsigned long session_id;
1275 DWORD size, reg_type, port_nr, install_state;
1276 HKEY key;
1277 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1278 GUID* if_guid;
1279 LONG s;
1280 // Keep a list of newly allocated devs to unref
1281 libusb_device** unref_list;
1282 unsigned int unref_size = 64;
1283 unsigned int unref_cur = 0;
1284
1285 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1286 // PASS 2 : (re)enumerate HUBS
1287 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1288 // and list additional USB device interface GUIDs to explore
1289 // PASS 4 : (re)enumerate master USB devices that have a device interface
1290 // PASS 5+: (re)enumerate device interfaced GUIDs and set the device interfaces.
1291
1292 // Init the GUID table
1293 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1294 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1295 guid[GEN_PASS] = NULL;
1296 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1297 nb_guids = DEV_PASS+1;
1298
1299 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1300 if (unref_list == NULL) {
1301 return LIBUSB_ERROR_NO_MEM;
1302 }
1303
1304 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1305 //#define ENUM_DEBUG
1306 #ifdef ENUM_DEBUG
1307 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "EXT" };
1308 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=DEV_PASS)?pass:DEV_PASS+1],
1309 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1310 #endif
1311 for (i = 0; ; i++) {
1312 // safe loop: free up any (unprotected) dynamic resource
1313 // NB: this is always executed before breaking the loop
1314 safe_free(dev_interface_details);
1315 safe_free(dev_interface_path);
1316 safe_free(dev_id_path);
1317 priv = parent_priv = NULL;
1318 dev = parent_dev = NULL;
1319
1320 // Safe loop: end of loop conditions
1321 if (r != LIBUSB_SUCCESS) {
1322 break;
1323 }
1324 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1325 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1326 break;
1327 }
1328 if (pass != GEN_PASS) {
1329 // Except for GEN, all passes deal with device interfaces
1330 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1331 if (dev_interface_details == NULL) {
1332 break;
1333 } else {
1334 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1335 if (dev_interface_path == NULL) {
1336 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1337 continue;
1338 }
1339 }
1340 } else {
1341 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1342 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1343 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1344 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1345 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1346 break;
1347 i = 0;
1348 }
1349 if (class_index >= ARRAYSIZE(usb_class))
1350 break;
1351 }
1352
1353 // Read the Device ID path. This is what we'll use as UID
1354 // Note that if the device is plugged in a different port or hub, the Device ID changes
1355 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1356 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1357 dev_info_data.DevInst);
1358 continue;
1359 }
1360 dev_id_path = sanitize_path(path);
1361 if (dev_id_path == NULL) {
1362 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1363 dev_info_data.DevInst);
1364 continue;
1365 }
1366 #ifdef ENUM_DEBUG
1367 usbi_dbg("PRO: %s", dev_id_path);
1368 #endif
1369
1370 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1371 port_nr = 0;
1372 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1373 if ( (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1374 ®_type, (BYTE*)&port_nr, 4, &size))
1375 || (size != 4) ) {
1376 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1377 dev_id_path, windows_error_str(0));
1378 continue;
1379 }
1380 }
1381
1382 // Set API to use or get additional data from generic pass
1383 api = USB_API_UNSUPPORTED;
1384 sub_api = SUB_API_NOTSET;
1385 switch (pass) {
1386 case HCD_PASS:
1387 break;
1388 case GEN_PASS:
1389 // We use the GEN pass to detect driverless devices...
1390 size = sizeof(strbuf);
1391 if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1392 ®_type, (BYTE*)strbuf, size, &size)) {
1393 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1394 usbi_info(ctx, "libusbx will not be able to access it.");
1395 }
1396 // ...and to add the additional device interface GUIDs
1397 key = SetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1398 if (key != INVALID_HANDLE_VALUE) {
1399 size = sizeof(guid_string_w);
1400 s = RegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1401 (BYTE*)guid_string_w, &size);
1402 RegCloseKey(key);
1403 if (s == ERROR_SUCCESS) {
1404 if (nb_guids >= MAX_ENUM_GUIDS) {
1405 // If this assert is ever reported, grow a GUID table dynamically
1406 usbi_err(ctx, "program assertion failed: too many GUIDs");
1407 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1408 }
1409 if_guid = (GUID*) calloc(1, sizeof(GUID));
1410 CLSIDFromString(guid_string_w, if_guid);
1411 guid[nb_guids++] = if_guid;
1412 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1413 }
1414 }
1415 break;
1416 default:
1417 // Get the API type (after checking that the driver installation is OK)
1418 if ( (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1419 ®_type, (BYTE*)&install_state, 4, &size))
1420 || (size != 4) ){
1421 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1422 dev_id_path, windows_error_str(0));
1423 } else if (install_state != 0) {
1424 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1425 dev_id_path, install_state);
1426 continue;
1427 }
1428 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1429 break;
1430 }
1431
1432 // Find parent device (for the passes that need it)
1433 switch (pass) {
1434 case HCD_PASS:
1435 case DEV_PASS:
1436 case HUB_PASS:
1437 break;
1438 default:
1439 // Go through the ancestors until we see a face we recognize
1440 parent_dev = NULL;
1441 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1442 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1443 if (session_id == 0) {
1444 break;
1445 }
1446 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1447 }
1448 if (parent_dev == NULL) {
1449 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1450 continue;
1451 }
1452 parent_priv = _device_priv(parent_dev);
1453 // virtual USB devices are also listed during GEN - don't process these yet
1454 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1455 continue;
1456 }
1457 break;
1458 }
1459
1460 // Create new or match existing device, using the (hashed) device_id as session id
1461 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1462 // These are the passes that create "new" devices
1463 session_id = htab_hash(dev_id_path);
1464 dev = usbi_get_device_by_session_id(ctx, session_id);
1465 if (dev == NULL) {
1466 if (pass == DEV_PASS) {
1467 // This can occur if the OS only reports a newly plugged device after we started enum
1468 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1469 " - ignoring", dev_id_path);
1470 continue;
1471 }
1472 usbi_dbg("allocating new device for session [%X]", session_id);
1473 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1474 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1475 }
1476 windows_device_priv_init(dev);
1477 // Keep track of devices that need unref
1478 unref_list[unref_cur++] = dev;
1479 if (unref_cur >= unref_size) {
1480 unref_size += 64;
1481 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1482 if (unref_list == NULL) {
1483 usbi_err(ctx, "could not realloc list for unref - aborting.");
1484 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1485 }
1486 }
1487 } else {
1488 usbi_dbg("found existing device for session [%X] (%d.%d)",
1489 session_id, dev->bus_number, dev->device_address);
1490 }
1491 priv = _device_priv(dev);
1492 }
1493
1494 // Setup device
1495 switch (pass) {
1496 case HCD_PASS:
1497 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1498 dev->device_address = 0;
1499 dev->num_configurations = 0;
1500 priv->apib = &usb_api_backend[USB_API_HUB];
1501 priv->sub_api = SUB_API_NOTSET;
1502 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1503 priv->path = dev_interface_path; dev_interface_path = NULL;
1504 break;
1505 case HUB_PASS:
1506 case DEV_PASS:
1507 // If the device has already been setup, don't do it again
1508 if (priv->path != NULL)
1509 break;
1510 // Take care of API initialization
1511 priv->path = dev_interface_path; dev_interface_path = NULL;
1512 priv->apib = &usb_api_backend[api];
1513 priv->sub_api = sub_api;
1514 switch(api) {
1515 case USB_API_COMPOSITE:
1516 case USB_API_HUB:
1517 break;
1518 default:
1519 // For other devices, the first interface is the same as the device
1520 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1521 if (priv->usb_interface[0].path != NULL) {
1522 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1523 } else {
1524 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1525 }
1526 // The following is needed if we want API calls to work for both simple
1527 // and composite devices.
1528 for(j=0; j<USB_MAXINTERFACES; j++) {
1529 priv->usb_interface[j].apib = &usb_api_backend[api];
1530 }
1531 break;
1532 }
1533 break;
1534 case GEN_PASS:
1535 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1536 if (r == LIBUSB_SUCCESS) {
1537 // Append device to the list of discovered devices
1538 discdevs = discovered_devs_append(*_discdevs, dev);
1539 if (!discdevs) {
1540 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1541 }
1542 *_discdevs = discdevs;
1543 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1544 // This can occur if the device was disconnected but Windows hasn't
1545 // refreshed its enumeration yet - in that case, we ignore the device
1546 r = LIBUSB_SUCCESS;
1547 }
1548 break;
1549 default: // later passes
1550 if (parent_priv->apib->id == USB_API_COMPOSITE) {
1551 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1552 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1553 case LIBUSB_SUCCESS:
1554 dev_interface_path = NULL;
1555 break;
1556 case LIBUSB_ERROR_ACCESS:
1557 // interface has already been set => make sure dev_interface_path is freed then
1558 break;
1559 default:
1560 LOOP_BREAK(r);
1561 break;
1562 }
1563 }
1564 break;
1565 }
1566 }
1567 }
1568
1569 // Free any additional GUIDs
1570 for (pass = DEV_PASS+1; pass < nb_guids; pass++) {
1571 safe_free(guid[pass]);
1572 }
1573
1574 // Unref newly allocated devs
1575 for (i=0; i<unref_cur; i++) {
1576 safe_unref_device(unref_list[i]);
1577 }
1578 safe_free(unref_list);
1579
1580 return r;
1581 }
1582
1583 /*
1584 * exit: libusbx backend deinitialization function
1585 */
windows_exit(void)1586 static void windows_exit(void)
1587 {
1588 int i;
1589 HANDLE semaphore;
1590 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1591
1592 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1593 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1594 if (semaphore == NULL) {
1595 return;
1596 }
1597
1598 // A successful wait brings our semaphore count to 0 (unsignaled)
1599 // => any concurent wait stalls until the semaphore release
1600 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1601 CloseHandle(semaphore);
1602 return;
1603 }
1604
1605 // Only works if exits and inits are balanced exactly
1606 if (--concurrent_usage < 0) { // Last exit
1607 for (i=0; i<USB_API_MAX; i++) {
1608 usb_api_backend[i].exit(SUB_API_NOTSET);
1609 }
1610 exit_polling();
1611
1612 if (timer_thread) {
1613 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1614 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1615 usbi_dbg("could not wait for timer thread to quit");
1616 TerminateThread(timer_thread, 1);
1617 }
1618 CloseHandle(timer_thread);
1619 timer_thread = NULL;
1620 }
1621 for (i = 0; i < 2; i++) {
1622 if (timer_request[i]) {
1623 CloseHandle(timer_request[i]);
1624 timer_request[i] = NULL;
1625 }
1626 }
1627 if (timer_response) {
1628 CloseHandle(timer_response);
1629 timer_response = NULL;
1630 }
1631 if (timer_mutex) {
1632 CloseHandle(timer_mutex);
1633 timer_mutex = NULL;
1634 }
1635 htab_destroy();
1636 }
1637
1638 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1639 CloseHandle(semaphore);
1640 }
1641
windows_get_device_descriptor(struct libusb_device * dev,unsigned char * buffer,int * host_endian)1642 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1643 {
1644 struct windows_device_priv *priv = _device_priv(dev);
1645
1646 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1647 *host_endian = 0;
1648
1649 return LIBUSB_SUCCESS;
1650 }
1651
windows_get_config_descriptor(struct libusb_device * dev,uint8_t config_index,unsigned char * buffer,size_t len,int * host_endian)1652 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1653 {
1654 struct windows_device_priv *priv = _device_priv(dev);
1655 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1656 size_t size;
1657
1658 // config index is zero based
1659 if (config_index >= dev->num_configurations)
1660 return LIBUSB_ERROR_INVALID_PARAM;
1661
1662 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1663 return LIBUSB_ERROR_NOT_FOUND;
1664
1665 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1666
1667 size = min(config_header->wTotalLength, len);
1668 memcpy(buffer, priv->config_descriptor[config_index], size);
1669 *host_endian = 0;
1670
1671 return (int)size;
1672 }
1673
1674 /*
1675 * return the cached copy of the active config descriptor
1676 */
windows_get_active_config_descriptor(struct libusb_device * dev,unsigned char * buffer,size_t len,int * host_endian)1677 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1678 {
1679 struct windows_device_priv *priv = _device_priv(dev);
1680
1681 if (priv->active_config == 0)
1682 return LIBUSB_ERROR_NOT_FOUND;
1683
1684 // config index is zero based
1685 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1686 }
1687
windows_open(struct libusb_device_handle * dev_handle)1688 static int windows_open(struct libusb_device_handle *dev_handle)
1689 {
1690 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1691 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1692
1693 if (priv->apib == NULL) {
1694 usbi_err(ctx, "program assertion failed - device is not initialized");
1695 return LIBUSB_ERROR_NO_DEVICE;
1696 }
1697
1698 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1699 }
1700
windows_close(struct libusb_device_handle * dev_handle)1701 static void windows_close(struct libusb_device_handle *dev_handle)
1702 {
1703 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1704
1705 priv->apib->close(SUB_API_NOTSET, dev_handle);
1706 }
1707
windows_get_configuration(struct libusb_device_handle * dev_handle,int * config)1708 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1709 {
1710 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1711
1712 if (priv->active_config == 0) {
1713 *config = 0;
1714 return LIBUSB_ERROR_NOT_FOUND;
1715 }
1716
1717 *config = priv->active_config;
1718 return LIBUSB_SUCCESS;
1719 }
1720
1721 /*
1722 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1723 * does not currently expose a service that allows higher-level drivers to set
1724 * the configuration."
1725 */
windows_set_configuration(struct libusb_device_handle * dev_handle,int config)1726 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1727 {
1728 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1729 int r = LIBUSB_SUCCESS;
1730
1731 if (config >= USB_MAXCONFIG)
1732 return LIBUSB_ERROR_INVALID_PARAM;
1733
1734 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1735 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1736 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1737 0, NULL, 0, 1000);
1738
1739 if (r == LIBUSB_SUCCESS) {
1740 priv->active_config = (uint8_t)config;
1741 }
1742 return r;
1743 }
1744
windows_claim_interface(struct libusb_device_handle * dev_handle,int iface)1745 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1746 {
1747 int r = LIBUSB_SUCCESS;
1748 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1749
1750 if (iface >= USB_MAXINTERFACES)
1751 return LIBUSB_ERROR_INVALID_PARAM;
1752
1753 safe_free(priv->usb_interface[iface].endpoint);
1754 priv->usb_interface[iface].nb_endpoints= 0;
1755
1756 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1757
1758 if (r == LIBUSB_SUCCESS) {
1759 r = windows_assign_endpoints(dev_handle, iface, 0);
1760 }
1761
1762 return r;
1763 }
1764
windows_set_interface_altsetting(struct libusb_device_handle * dev_handle,int iface,int altsetting)1765 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1766 {
1767 int r = LIBUSB_SUCCESS;
1768 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1769
1770 safe_free(priv->usb_interface[iface].endpoint);
1771 priv->usb_interface[iface].nb_endpoints= 0;
1772
1773 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1774
1775 if (r == LIBUSB_SUCCESS) {
1776 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1777 }
1778
1779 return r;
1780 }
1781
windows_release_interface(struct libusb_device_handle * dev_handle,int iface)1782 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1783 {
1784 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1785
1786 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1787 }
1788
windows_clear_halt(struct libusb_device_handle * dev_handle,unsigned char endpoint)1789 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1790 {
1791 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1792 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1793 }
1794
windows_reset_device(struct libusb_device_handle * dev_handle)1795 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1796 {
1797 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1798 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1799 }
1800
1801 // The 3 functions below are unlikely to ever get supported on Windows
windows_kernel_driver_active(struct libusb_device_handle * dev_handle,int iface)1802 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1803 {
1804 return LIBUSB_ERROR_NOT_SUPPORTED;
1805 }
1806
windows_attach_kernel_driver(struct libusb_device_handle * dev_handle,int iface)1807 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1808 {
1809 return LIBUSB_ERROR_NOT_SUPPORTED;
1810 }
1811
windows_detach_kernel_driver(struct libusb_device_handle * dev_handle,int iface)1812 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1813 {
1814 return LIBUSB_ERROR_NOT_SUPPORTED;
1815 }
1816
windows_destroy_device(struct libusb_device * dev)1817 static void windows_destroy_device(struct libusb_device *dev)
1818 {
1819 windows_device_priv_release(dev);
1820 }
1821
windows_clear_transfer_priv(struct usbi_transfer * itransfer)1822 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1823 {
1824 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1825
1826 usbi_free_fd(&transfer_priv->pollable_fd);
1827 // When auto claim is in use, attempt to release the auto-claimed interface
1828 auto_release(itransfer);
1829 }
1830
submit_bulk_transfer(struct usbi_transfer * itransfer)1831 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1832 {
1833 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1834 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1835 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1836 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1837 int r;
1838
1839 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1840 if (r != LIBUSB_SUCCESS) {
1841 return r;
1842 }
1843
1844 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1845 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1846
1847 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1848 return LIBUSB_SUCCESS;
1849 }
1850
submit_iso_transfer(struct usbi_transfer * itransfer)1851 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1852 {
1853 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1854 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1855 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1856 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1857 int r;
1858
1859 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1860 if (r != LIBUSB_SUCCESS) {
1861 return r;
1862 }
1863
1864 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1865 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1866
1867 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1868 return LIBUSB_SUCCESS;
1869 }
1870
submit_control_transfer(struct usbi_transfer * itransfer)1871 static int submit_control_transfer(struct usbi_transfer *itransfer)
1872 {
1873 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1874 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1875 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1876 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1877 int r;
1878
1879 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1880 if (r != LIBUSB_SUCCESS) {
1881 return r;
1882 }
1883
1884 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
1885
1886 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1887 return LIBUSB_SUCCESS;
1888
1889 }
1890
windows_submit_transfer(struct usbi_transfer * itransfer)1891 static int windows_submit_transfer(struct usbi_transfer *itransfer)
1892 {
1893 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1894
1895 switch (transfer->type) {
1896 case LIBUSB_TRANSFER_TYPE_CONTROL:
1897 return submit_control_transfer(itransfer);
1898 case LIBUSB_TRANSFER_TYPE_BULK:
1899 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1900 if (IS_XFEROUT(transfer) &&
1901 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
1902 return LIBUSB_ERROR_NOT_SUPPORTED;
1903 return submit_bulk_transfer(itransfer);
1904 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1905 return submit_iso_transfer(itransfer);
1906 default:
1907 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1908 return LIBUSB_ERROR_INVALID_PARAM;
1909 }
1910 }
1911
windows_abort_control(struct usbi_transfer * itransfer)1912 static int windows_abort_control(struct usbi_transfer *itransfer)
1913 {
1914 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1915 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1916
1917 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
1918 }
1919
windows_abort_transfers(struct usbi_transfer * itransfer)1920 static int windows_abort_transfers(struct usbi_transfer *itransfer)
1921 {
1922 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1923 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1924
1925 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
1926 }
1927
windows_cancel_transfer(struct usbi_transfer * itransfer)1928 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
1929 {
1930 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1931
1932 switch (transfer->type) {
1933 case LIBUSB_TRANSFER_TYPE_CONTROL:
1934 return windows_abort_control(itransfer);
1935 case LIBUSB_TRANSFER_TYPE_BULK:
1936 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1937 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1938 return windows_abort_transfers(itransfer);
1939 default:
1940 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
1941 return LIBUSB_ERROR_INVALID_PARAM;
1942 }
1943 }
1944
windows_transfer_callback(struct usbi_transfer * itransfer,uint32_t io_result,uint32_t io_size)1945 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
1946 {
1947 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1948 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1949 int status, istatus;
1950
1951 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
1952
1953 switch(io_result) {
1954 case NO_ERROR:
1955 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
1956 break;
1957 case ERROR_GEN_FAILURE:
1958 usbi_dbg("detected endpoint stall");
1959 status = LIBUSB_TRANSFER_STALL;
1960 break;
1961 case ERROR_SEM_TIMEOUT:
1962 usbi_dbg("detected semaphore timeout");
1963 status = LIBUSB_TRANSFER_TIMED_OUT;
1964 break;
1965 case ERROR_OPERATION_ABORTED:
1966 istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
1967 if (istatus != LIBUSB_TRANSFER_COMPLETED) {
1968 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
1969 }
1970 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
1971 usbi_dbg("detected timeout");
1972 status = LIBUSB_TRANSFER_TIMED_OUT;
1973 } else {
1974 usbi_dbg("detected operation aborted");
1975 status = LIBUSB_TRANSFER_CANCELLED;
1976 }
1977 break;
1978 default:
1979 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(0));
1980 status = LIBUSB_TRANSFER_ERROR;
1981 break;
1982 }
1983 windows_clear_transfer_priv(itransfer); // Cancel polling
1984 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
1985 }
1986
windows_handle_callback(struct usbi_transfer * itransfer,uint32_t io_result,uint32_t io_size)1987 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
1988 {
1989 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1990
1991 switch (transfer->type) {
1992 case LIBUSB_TRANSFER_TYPE_CONTROL:
1993 case LIBUSB_TRANSFER_TYPE_BULK:
1994 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1995 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1996 windows_transfer_callback (itransfer, io_result, io_size);
1997 break;
1998 default:
1999 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2000 }
2001 }
2002
windows_handle_events(struct libusb_context * ctx,struct pollfd * fds,POLL_NFDS_TYPE nfds,int num_ready)2003 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2004 {
2005 struct windows_transfer_priv* transfer_priv = NULL;
2006 POLL_NFDS_TYPE i = 0;
2007 bool found = false;
2008 struct usbi_transfer *transfer;
2009 DWORD io_size, io_result;
2010
2011 usbi_mutex_lock(&ctx->open_devs_lock);
2012 for (i = 0; i < nfds && num_ready > 0; i++) {
2013
2014 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2015
2016 if (!fds[i].revents) {
2017 continue;
2018 }
2019
2020 num_ready--;
2021
2022 // Because a Windows OVERLAPPED is used for poll emulation,
2023 // a pollable fd is created and stored with each transfer
2024 usbi_mutex_lock(&ctx->flying_transfers_lock);
2025 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2026 transfer_priv = usbi_transfer_get_os_priv(transfer);
2027 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2028 found = true;
2029 break;
2030 }
2031 }
2032 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2033
2034 if (found) {
2035 // Handle async requests that completed synchronously first
2036 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2037 io_result = NO_ERROR;
2038 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2039 // Regular async overlapped
2040 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2041 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2042 io_result = NO_ERROR;
2043 } else {
2044 io_result = GetLastError();
2045 }
2046 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2047 // let handle_callback free the event using the transfer wfd
2048 // If you don't use the transfer wfd, you run a risk of trying to free a
2049 // newly allocated wfd that took the place of the one from the transfer.
2050 windows_handle_callback(transfer, io_result, io_size);
2051 } else {
2052 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2053 usbi_mutex_unlock(&ctx->open_devs_lock);
2054 return LIBUSB_ERROR_NOT_FOUND;
2055 }
2056 }
2057
2058 usbi_mutex_unlock(&ctx->open_devs_lock);
2059 return LIBUSB_SUCCESS;
2060 }
2061
2062 /*
2063 * Monotonic and real time functions
2064 */
windows_clock_gettime_threaded(void * param)2065 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2066 {
2067 LARGE_INTEGER hires_counter, li_frequency;
2068 LONG nb_responses;
2069 int timer_index;
2070
2071 // Init - find out if we have access to a monotonic (hires) timer
2072 if (!QueryPerformanceFrequency(&li_frequency)) {
2073 usbi_dbg("no hires timer available on this platform");
2074 hires_frequency = 0;
2075 hires_ticks_to_ps = UINT64_C(0);
2076 } else {
2077 hires_frequency = li_frequency.QuadPart;
2078 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2079 // to picoseconds to compute the tv_nsecs part in clock_gettime
2080 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2081 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2082 }
2083
2084 // Signal windows_init() that we're ready to service requests
2085 if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
2086 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2087 }
2088
2089 // Main loop - wait for requests
2090 while (1) {
2091 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2092 if ( (timer_index != 0) && (timer_index != 1) ) {
2093 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2094 continue;
2095 }
2096 if (request_count[timer_index] == 0) {
2097 // Request already handled
2098 ResetEvent(timer_request[timer_index]);
2099 // There's still a possiblity that a thread sends a request between the
2100 // time we test request_count[] == 0 and we reset the event, in which case
2101 // the request would be ignored. The simple solution to that is to test
2102 // request_count again and process requests if non zero.
2103 if (request_count[timer_index] == 0)
2104 continue;
2105 }
2106 switch (timer_index) {
2107 case 0:
2108 WaitForSingleObject(timer_mutex, INFINITE);
2109 // Requests to this thread are for hires always
2110 if (QueryPerformanceCounter(&hires_counter) != 0) {
2111 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2112 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2113 } else {
2114 // Fallback to real-time if we can't get monotonic value
2115 // Note that real-time clock does not wait on the mutex or this thread.
2116 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2117 }
2118 ReleaseMutex(timer_mutex);
2119
2120 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2121 if ( (nb_responses)
2122 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2123 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2124 }
2125 continue;
2126 case 1: // time to quit
2127 usbi_dbg("timer thread quitting");
2128 return 0;
2129 }
2130 }
2131 }
2132
windows_clock_gettime(int clk_id,struct timespec * tp)2133 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2134 {
2135 FILETIME filetime;
2136 ULARGE_INTEGER rtime;
2137 DWORD r;
2138 switch(clk_id) {
2139 case USBI_CLOCK_MONOTONIC:
2140 if (hires_frequency != 0) {
2141 while (1) {
2142 InterlockedIncrement((LONG*)&request_count[0]);
2143 SetEvent(timer_request[0]);
2144 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2145 switch(r) {
2146 case WAIT_OBJECT_0:
2147 WaitForSingleObject(timer_mutex, INFINITE);
2148 *tp = timer_tp;
2149 ReleaseMutex(timer_mutex);
2150 return LIBUSB_SUCCESS;
2151 case WAIT_TIMEOUT:
2152 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2153 break; // Retry until successful
2154 default:
2155 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2156 return LIBUSB_ERROR_OTHER;
2157 }
2158 }
2159 }
2160 // Fall through and return real-time if monotonic was not detected @ timer init
2161 case USBI_CLOCK_REALTIME:
2162 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2163 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2164 // Note however that our resolution is bounded by the Windows system time
2165 // functions and is at best of the order of 1 ms (or, usually, worse)
2166 GetSystemTimeAsFileTime(&filetime);
2167 rtime.LowPart = filetime.dwLowDateTime;
2168 rtime.HighPart = filetime.dwHighDateTime;
2169 rtime.QuadPart -= epoch_time;
2170 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2171 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2172 return LIBUSB_SUCCESS;
2173 default:
2174 return LIBUSB_ERROR_INVALID_PARAM;
2175 }
2176 }
2177
2178
2179 // NB: MSVC6 does not support named initializers.
2180 const struct usbi_os_backend windows_backend = {
2181 "Windows",
2182 USBI_CAP_HAS_HID_ACCESS,
2183 windows_init,
2184 windows_exit,
2185
2186 windows_get_device_list,
2187 NULL, /* hotplug_poll */
2188 windows_open,
2189 NULL, /* open_fd */
2190 windows_close,
2191
2192 windows_get_device_descriptor,
2193 windows_get_active_config_descriptor,
2194 windows_get_config_descriptor,
2195 NULL, /* get_config_descriptor_by_value() */
2196
2197 windows_get_configuration,
2198 windows_set_configuration,
2199 windows_claim_interface,
2200 windows_release_interface,
2201
2202 windows_set_interface_altsetting,
2203 windows_clear_halt,
2204 windows_reset_device,
2205
2206 windows_kernel_driver_active,
2207 windows_detach_kernel_driver,
2208 windows_attach_kernel_driver,
2209
2210 windows_destroy_device,
2211
2212 windows_submit_transfer,
2213 windows_cancel_transfer,
2214 windows_clear_transfer_priv,
2215
2216 windows_handle_events,
2217
2218 windows_clock_gettime,
2219 #if defined(USBI_TIMERFD_AVAILABLE)
2220 NULL,
2221 #endif
2222 sizeof(struct windows_device_priv),
2223 sizeof(struct windows_device_handle_priv),
2224 sizeof(struct windows_transfer_priv),
2225 0,
2226 };
2227
2228
2229 /*
2230 * USB API backends
2231 */
unsupported_init(int sub_api,struct libusb_context * ctx)2232 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2233 return LIBUSB_SUCCESS;
2234 }
unsupported_exit(int sub_api)2235 static int unsupported_exit(int sub_api) {
2236 return LIBUSB_SUCCESS;
2237 }
unsupported_open(int sub_api,struct libusb_device_handle * dev_handle)2238 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2239 PRINT_UNSUPPORTED_API(open);
2240 }
unsupported_close(int sub_api,struct libusb_device_handle * dev_handle)2241 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2242 usbi_dbg("unsupported API call for 'close'");
2243 }
unsupported_configure_endpoints(int sub_api,struct libusb_device_handle * dev_handle,int iface)2244 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2245 PRINT_UNSUPPORTED_API(configure_endpoints);
2246 }
unsupported_claim_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2247 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2248 PRINT_UNSUPPORTED_API(claim_interface);
2249 }
unsupported_set_interface_altsetting(int sub_api,struct libusb_device_handle * dev_handle,int iface,int altsetting)2250 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2251 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2252 }
unsupported_release_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2253 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2254 PRINT_UNSUPPORTED_API(release_interface);
2255 }
unsupported_clear_halt(int sub_api,struct libusb_device_handle * dev_handle,unsigned char endpoint)2256 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2257 PRINT_UNSUPPORTED_API(clear_halt);
2258 }
unsupported_reset_device(int sub_api,struct libusb_device_handle * dev_handle)2259 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2260 PRINT_UNSUPPORTED_API(reset_device);
2261 }
unsupported_submit_bulk_transfer(int sub_api,struct usbi_transfer * itransfer)2262 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2263 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2264 }
unsupported_submit_iso_transfer(int sub_api,struct usbi_transfer * itransfer)2265 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2266 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2267 }
unsupported_submit_control_transfer(int sub_api,struct usbi_transfer * itransfer)2268 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2269 PRINT_UNSUPPORTED_API(submit_control_transfer);
2270 }
unsupported_abort_control(int sub_api,struct usbi_transfer * itransfer)2271 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2272 PRINT_UNSUPPORTED_API(abort_control);
2273 }
unsupported_abort_transfers(int sub_api,struct usbi_transfer * itransfer)2274 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2275 PRINT_UNSUPPORTED_API(abort_transfers);
2276 }
unsupported_copy_transfer_data(int sub_api,struct usbi_transfer * itransfer,uint32_t io_size)2277 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2278 PRINT_UNSUPPORTED_API(copy_transfer_data);
2279 }
common_configure_endpoints(int sub_api,struct libusb_device_handle * dev_handle,int iface)2280 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2281 return LIBUSB_SUCCESS;
2282 }
2283 // These names must be uppercase
2284 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2285 const char* composite_driver_names[] = {"USBCCGP"};
2286 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2287 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2288 {
2289 USB_API_UNSUPPORTED,
2290 "Unsupported API",
2291 NULL,
2292 0,
2293 unsupported_init,
2294 unsupported_exit,
2295 unsupported_open,
2296 unsupported_close,
2297 unsupported_configure_endpoints,
2298 unsupported_claim_interface,
2299 unsupported_set_interface_altsetting,
2300 unsupported_release_interface,
2301 unsupported_clear_halt,
2302 unsupported_reset_device,
2303 unsupported_submit_bulk_transfer,
2304 unsupported_submit_iso_transfer,
2305 unsupported_submit_control_transfer,
2306 unsupported_abort_control,
2307 unsupported_abort_transfers,
2308 unsupported_copy_transfer_data,
2309 }, {
2310 USB_API_HUB,
2311 "HUB API",
2312 hub_driver_names,
2313 ARRAYSIZE(hub_driver_names),
2314 unsupported_init,
2315 unsupported_exit,
2316 unsupported_open,
2317 unsupported_close,
2318 unsupported_configure_endpoints,
2319 unsupported_claim_interface,
2320 unsupported_set_interface_altsetting,
2321 unsupported_release_interface,
2322 unsupported_clear_halt,
2323 unsupported_reset_device,
2324 unsupported_submit_bulk_transfer,
2325 unsupported_submit_iso_transfer,
2326 unsupported_submit_control_transfer,
2327 unsupported_abort_control,
2328 unsupported_abort_transfers,
2329 unsupported_copy_transfer_data,
2330 }, {
2331 USB_API_COMPOSITE,
2332 "Composite API",
2333 composite_driver_names,
2334 ARRAYSIZE(composite_driver_names),
2335 composite_init,
2336 composite_exit,
2337 composite_open,
2338 composite_close,
2339 common_configure_endpoints,
2340 composite_claim_interface,
2341 composite_set_interface_altsetting,
2342 composite_release_interface,
2343 composite_clear_halt,
2344 composite_reset_device,
2345 composite_submit_bulk_transfer,
2346 composite_submit_iso_transfer,
2347 composite_submit_control_transfer,
2348 composite_abort_control,
2349 composite_abort_transfers,
2350 composite_copy_transfer_data,
2351 }, {
2352 USB_API_WINUSBX,
2353 "WinUSB-like APIs",
2354 winusbx_driver_names,
2355 ARRAYSIZE(winusbx_driver_names),
2356 winusbx_init,
2357 winusbx_exit,
2358 winusbx_open,
2359 winusbx_close,
2360 winusbx_configure_endpoints,
2361 winusbx_claim_interface,
2362 winusbx_set_interface_altsetting,
2363 winusbx_release_interface,
2364 winusbx_clear_halt,
2365 winusbx_reset_device,
2366 winusbx_submit_bulk_transfer,
2367 unsupported_submit_iso_transfer,
2368 winusbx_submit_control_transfer,
2369 winusbx_abort_control,
2370 winusbx_abort_transfers,
2371 winusbx_copy_transfer_data,
2372 },
2373 };
2374
2375
2376 /*
2377 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2378 */
2379
winusbx_init(int sub_api,struct libusb_context * ctx)2380 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2381 {
2382 return LIBUSB_SUCCESS;
2383 }
2384
winusbx_exit(int sub_api)2385 static int winusbx_exit(int sub_api)
2386 {
2387 return LIBUSB_SUCCESS;
2388 }
2389
2390 // NB: open and close must ensure that they only handle interface of
2391 // the right API type, as these functions can be called wholesale from
2392 // composite_open(), with interfaces belonging to different APIs
winusbx_open(int sub_api,struct libusb_device_handle * dev_handle)2393 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2394 {
2395 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2396 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2397 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2398
2399 HANDLE file_handle;
2400 int i;
2401
2402 // WinUSB requires a seperate handle for each interface
2403 for (i = 0; i < USB_MAXINTERFACES; i++) {
2404 if ( (priv->usb_interface[i].path != NULL)
2405 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2406 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2407 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2408 if (file_handle == INVALID_HANDLE_VALUE) {
2409 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2410 switch(GetLastError()) {
2411 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2412 return LIBUSB_ERROR_NO_DEVICE;
2413 case ERROR_ACCESS_DENIED:
2414 return LIBUSB_ERROR_ACCESS;
2415 default:
2416 return LIBUSB_ERROR_IO;
2417 }
2418 }
2419 handle_priv->interface_handle[i].dev_handle = file_handle;
2420 }
2421 }
2422
2423 return LIBUSB_SUCCESS;
2424 }
2425
winusbx_close(int sub_api,struct libusb_device_handle * dev_handle)2426 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2427 {
2428 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2429 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2430 HANDLE file_handle;
2431 int i;
2432
2433 if (sub_api == SUB_API_NOTSET)
2434 sub_api = priv->sub_api;
2435
2436 for (i = 0; i < USB_MAXINTERFACES; i++) {
2437 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2438 file_handle = handle_priv->interface_handle[i].dev_handle;
2439 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2440 CloseHandle(file_handle);
2441 }
2442 }
2443 }
2444 }
2445
winusbx_configure_endpoints(int sub_api,struct libusb_device_handle * dev_handle,int iface)2446 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2447 {
2448 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2449 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2450 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2451 UCHAR policy;
2452 ULONG timeout = 0;
2453 uint8_t endpoint_address;
2454 int i;
2455
2456 // With handle and enpoints set (in parent), we can setup the default pipe properties
2457 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2458 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2459 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2460 if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address,
2461 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2462 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2463 }
2464 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2465 continue; // Other policies don't apply to control endpoint or libusb0
2466 }
2467 policy = false;
2468 if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address,
2469 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2470 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2471 }
2472 if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address,
2473 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2474 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2475 }
2476 policy = true;
2477 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2478 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2479 if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address,
2480 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2481 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2482 }
2483 if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address,
2484 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2485 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2486 }
2487 }
2488
2489 return LIBUSB_SUCCESS;
2490 }
2491
winusbx_claim_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2492 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2493 {
2494 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2495 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2496 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2497 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2498 HANDLE file_handle, winusb_handle;
2499 DWORD err;
2500 int i;
2501 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2502 HDEVINFO dev_info = INVALID_HANDLE_VALUE;
2503 SP_DEVINFO_DATA dev_info_data;
2504 char* dev_path_no_guid = NULL;
2505 char filter_path[] = "\\\\.\\libusb0-0000";
2506 bool found_filter = false;
2507
2508 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2509 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2510 if ((is_using_usbccgp) || (iface == 0)) {
2511 // composite device (independent interfaces) or interface 0
2512 file_handle = handle_priv->interface_handle[iface].dev_handle;
2513 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2514 return LIBUSB_ERROR_NOT_FOUND;
2515 }
2516
2517 if (!WinUsb_Initialize(file_handle, &winusb_handle)) {
2518 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2519 err = GetLastError();
2520 switch(err) {
2521 case ERROR_BAD_COMMAND:
2522 // The device was disconnected
2523 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2524 return LIBUSB_ERROR_NO_DEVICE;
2525 default:
2526 // it may be that we're using the libusb0 filter driver.
2527 // TODO: can we move this whole business into the K/0 DLL?
2528 for (i = 0; ; i++) {
2529 safe_free(dev_interface_details);
2530 safe_free(dev_path_no_guid);
2531 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2532 if ((found_filter) || (dev_interface_details == NULL)) {
2533 break;
2534 }
2535 // ignore GUID part
2536 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2537 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2538 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2539 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2540 if (file_handle == INVALID_HANDLE_VALUE) {
2541 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2542 } else {
2543 WinUsb_Free(winusb_handle);
2544 if (!WinUsb_Initialize(file_handle, &winusb_handle)) {
2545 continue;
2546 }
2547 found_filter = true;
2548 break;
2549 }
2550 }
2551 }
2552 if (!found_filter) {
2553 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2554 return LIBUSB_ERROR_ACCESS;
2555 }
2556 }
2557 }
2558 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2559 } else {
2560 // For all other interfaces, use GetAssociatedInterface()
2561 winusb_handle = handle_priv->interface_handle[0].api_handle;
2562 // It is a requirement for multiple interface devices on Windows that, to you
2563 // must first claim the first interface before you claim the others
2564 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2565 file_handle = handle_priv->interface_handle[0].dev_handle;
2566 if (WinUsb_Initialize(file_handle, &winusb_handle)) {
2567 handle_priv->interface_handle[0].api_handle = winusb_handle;
2568 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2569 } else {
2570 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2571 return LIBUSB_ERROR_ACCESS;
2572 }
2573 }
2574 if (!WinUsb_GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2575 &handle_priv->interface_handle[iface].api_handle)) {
2576 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2577 switch(GetLastError()) {
2578 case ERROR_NO_MORE_ITEMS: // invalid iface
2579 return LIBUSB_ERROR_NOT_FOUND;
2580 case ERROR_BAD_COMMAND: // The device was disconnected
2581 return LIBUSB_ERROR_NO_DEVICE;
2582 case ERROR_ALREADY_EXISTS: // already claimed
2583 return LIBUSB_ERROR_BUSY;
2584 default:
2585 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2586 return LIBUSB_ERROR_ACCESS;
2587 }
2588 }
2589 }
2590 usbi_dbg("claimed interface %d", iface);
2591 handle_priv->active_interface = iface;
2592
2593 return LIBUSB_SUCCESS;
2594 }
2595
winusbx_release_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2596 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2597 {
2598 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2599 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2600 HANDLE winusb_handle;
2601
2602 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2603 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2604 return LIBUSB_ERROR_NOT_FOUND;
2605 }
2606
2607 WinUsb_Free(winusb_handle);
2608 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2609
2610 return LIBUSB_SUCCESS;
2611 }
2612
2613 /*
2614 * Return the first valid interface (of the same API type), for control transfers
2615 */
get_valid_interface(struct libusb_device_handle * dev_handle,int api_id)2616 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2617 {
2618 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2619 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2620 int i;
2621
2622 if ((api_id < USB_API_WINUSBX) || (api_id >= USB_API_MAX)) {
2623 usbi_dbg("unsupported API ID");
2624 return -1;
2625 }
2626
2627 for (i=0; i<USB_MAXINTERFACES; i++) {
2628 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2629 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2630 && (handle_priv->interface_handle[i].api_handle != 0)
2631 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2632 && (priv->usb_interface[i].apib->id == api_id) ) {
2633 return i;
2634 }
2635 }
2636 return -1;
2637 }
2638
2639 /*
2640 * Lookup interface by endpoint address. -1 if not found
2641 */
interface_by_endpoint(struct windows_device_priv * priv,struct windows_device_handle_priv * handle_priv,uint8_t endpoint_address)2642 static int interface_by_endpoint(struct windows_device_priv *priv,
2643 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2644 {
2645 int i, j;
2646 for (i=0; i<USB_MAXINTERFACES; i++) {
2647 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2648 continue;
2649 if (handle_priv->interface_handle[i].api_handle == 0)
2650 continue;
2651 if (priv->usb_interface[i].endpoint == NULL)
2652 continue;
2653 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2654 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2655 return i;
2656 }
2657 }
2658 }
2659 return -1;
2660 }
2661
winusbx_submit_control_transfer(int sub_api,struct usbi_transfer * itransfer)2662 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2663 {
2664 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2665 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2666 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2667 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2668 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2669 transfer->dev_handle);
2670 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2671 ULONG size;
2672 HANDLE winusb_handle;
2673 int current_interface;
2674 struct winfd wfd;
2675
2676 transfer_priv->pollable_fd = INVALID_WINFD;
2677 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2678
2679 if (size > MAX_CTRL_BUFFER_LENGTH)
2680 return LIBUSB_ERROR_INVALID_PARAM;
2681
2682 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2683 if (current_interface < 0) {
2684 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2685 return LIBUSB_ERROR_NOT_FOUND;
2686 }
2687 }
2688
2689 usbi_dbg("will use interface %d", current_interface);
2690 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2691
2692 wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
2693 // Always use the handle returned from usbi_create_fd (wfd.handle)
2694 if (wfd.fd < 0) {
2695 return LIBUSB_ERROR_NO_MEM;
2696 }
2697
2698 // Sending of set configuration control requests from WinUSB creates issues
2699 if ( ((setup->RequestType & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2700 && (setup->Request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2701 if (setup->Value != priv->active_config) {
2702 usbi_warn(ctx, "cannot set configuration other than the default one");
2703 usbi_free_fd(&wfd);
2704 return LIBUSB_ERROR_INVALID_PARAM;
2705 }
2706 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2707 wfd.overlapped->InternalHigh = 0;
2708 } else {
2709 if (!WinUsb_ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2710 if(GetLastError() != ERROR_IO_PENDING) {
2711 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2712 usbi_free_fd(&wfd);
2713 return LIBUSB_ERROR_IO;
2714 }
2715 } else {
2716 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2717 wfd.overlapped->InternalHigh = (DWORD)size;
2718 }
2719 }
2720
2721 // Use priv_transfer to store data needed for async polling
2722 transfer_priv->pollable_fd = wfd;
2723 transfer_priv->interface_number = (uint8_t)current_interface;
2724
2725 return LIBUSB_SUCCESS;
2726 }
2727
winusbx_set_interface_altsetting(int sub_api,struct libusb_device_handle * dev_handle,int iface,int altsetting)2728 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2729 {
2730 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2731 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2732 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2733 HANDLE winusb_handle;
2734
2735 if (altsetting > 255) {
2736 return LIBUSB_ERROR_INVALID_PARAM;
2737 }
2738
2739 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2740 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2741 usbi_err(ctx, "interface must be claimed first");
2742 return LIBUSB_ERROR_NOT_FOUND;
2743 }
2744
2745 if (!WinUsb_SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2746 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2747 return LIBUSB_ERROR_IO;
2748 }
2749
2750 return LIBUSB_SUCCESS;
2751 }
2752
winusbx_submit_bulk_transfer(int sub_api,struct usbi_transfer * itransfer)2753 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2754 {
2755 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2756 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2757 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2758 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2759 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2760 HANDLE winusb_handle;
2761 bool ret;
2762 int current_interface;
2763 struct winfd wfd;
2764
2765 transfer_priv->pollable_fd = INVALID_WINFD;
2766
2767 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2768 if (current_interface < 0) {
2769 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2770 return LIBUSB_ERROR_NOT_FOUND;
2771 }
2772
2773 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2774
2775 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2776
2777 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
2778 // Always use the handle returned from usbi_create_fd (wfd.handle)
2779 if (wfd.fd < 0) {
2780 return LIBUSB_ERROR_NO_MEM;
2781 }
2782
2783 if (IS_XFERIN(transfer)) {
2784 usbi_dbg("reading %d bytes", transfer->length);
2785 ret = WinUsb_ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2786 } else {
2787 usbi_dbg("writing %d bytes", transfer->length);
2788 ret = WinUsb_WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2789 }
2790 if (!ret) {
2791 if(GetLastError() != ERROR_IO_PENDING) {
2792 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2793 usbi_free_fd(&wfd);
2794 return LIBUSB_ERROR_IO;
2795 }
2796 } else {
2797 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2798 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
2799 }
2800
2801 transfer_priv->pollable_fd = wfd;
2802 transfer_priv->interface_number = (uint8_t)current_interface;
2803
2804 return LIBUSB_SUCCESS;
2805 }
2806
winusbx_clear_halt(int sub_api,struct libusb_device_handle * dev_handle,unsigned char endpoint)2807 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
2808 {
2809 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2810 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2811 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2812 HANDLE winusb_handle;
2813 int current_interface;
2814
2815 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
2816 if (current_interface < 0) {
2817 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
2818 return LIBUSB_ERROR_NOT_FOUND;
2819 }
2820
2821 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
2822 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2823
2824 if (!WinUsb_ResetPipe(winusb_handle, endpoint)) {
2825 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
2826 return LIBUSB_ERROR_NO_DEVICE;
2827 }
2828
2829 return LIBUSB_SUCCESS;
2830 }
2831
2832 /*
2833 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
2834 * through testing as well):
2835 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
2836 * the control transfer using CancelIo"
2837 */
winusbx_abort_control(int sub_api,struct usbi_transfer * itransfer)2838 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
2839 {
2840 // Cancelling of the I/O is done in the parent
2841 return LIBUSB_SUCCESS;
2842 }
2843
winusbx_abort_transfers(int sub_api,struct usbi_transfer * itransfer)2844 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
2845 {
2846 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2847 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2848 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2849 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2850 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2851 HANDLE winusb_handle;
2852 int current_interface;
2853
2854 current_interface = transfer_priv->interface_number;
2855 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
2856 usbi_err(ctx, "program assertion failed: invalid interface_number");
2857 return LIBUSB_ERROR_NOT_FOUND;
2858 }
2859 usbi_dbg("will use interface %d", current_interface);
2860
2861 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2862
2863 if (!WinUsb_AbortPipe(winusb_handle, transfer->endpoint)) {
2864 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
2865 return LIBUSB_ERROR_NO_DEVICE;
2866 }
2867
2868 return LIBUSB_SUCCESS;
2869 }
2870
2871 /*
2872 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
2873 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
2874 * "WinUSB does not support host-initiated reset port and cycle port operations" and
2875 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
2876 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
2877 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
2878 */
2879 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
winusbx_reset_device(int sub_api,struct libusb_device_handle * dev_handle)2880 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
2881 {
2882 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2883 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2884 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2885 struct winfd wfd;
2886 HANDLE winusb_handle;
2887 int i, j;
2888
2889 // Reset any available pipe (except control)
2890 for (i=0; i<USB_MAXINTERFACES; i++) {
2891 winusb_handle = handle_priv->interface_handle[i].api_handle;
2892 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
2893 {
2894 // Cancel any pollable I/O
2895 usbi_remove_pollfd(ctx, wfd.fd);
2896 usbi_free_fd(&wfd);
2897 wfd = handle_to_winfd(winusb_handle);
2898 }
2899
2900 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
2901 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2902 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
2903 if (!WinUsb_AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
2904 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
2905 priv->usb_interface[i].endpoint[j], windows_error_str(0));
2906 }
2907 // FlushPipe seems to fail on OUT pipes
2908 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
2909 && (!WinUsb_FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
2910 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
2911 priv->usb_interface[i].endpoint[j], windows_error_str(0));
2912 }
2913 if (!WinUsb_ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
2914 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
2915 priv->usb_interface[i].endpoint[j], windows_error_str(0));
2916 }
2917 }
2918 }
2919 }
2920
2921 return LIBUSB_SUCCESS;
2922 }
2923
winusbx_copy_transfer_data(int sub_api,struct usbi_transfer * itransfer,uint32_t io_size)2924 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
2925 {
2926 itransfer->transferred += io_size;
2927 return LIBUSB_TRANSFER_COMPLETED;
2928 }
2929
2930 /*
2931 * Composite API functions
2932 */
composite_init(int sub_api,struct libusb_context * ctx)2933 static int composite_init(int sub_api, struct libusb_context *ctx)
2934 {
2935 return LIBUSB_SUCCESS;
2936 }
2937
composite_exit(int sub_api)2938 static int composite_exit(int sub_api)
2939 {
2940 return LIBUSB_SUCCESS;
2941 }
2942
composite_open(int sub_api,struct libusb_device_handle * dev_handle)2943 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
2944 {
2945 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2946 int r = LIBUSB_ERROR_NOT_FOUND;
2947 uint8_t i;
2948 bool available[SUB_API_MAX] = {0};
2949
2950 for (i=0; i<USB_MAXINTERFACES; i++) {
2951 switch (priv->usb_interface[i].apib->id) {
2952 case USB_API_WINUSBX:
2953 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
2954 available[priv->usb_interface[i].sub_api] = true;
2955 break;
2956 default:
2957 break;
2958 }
2959 }
2960
2961 for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
2962 if (available[i]) {
2963 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
2964 if (r != LIBUSB_SUCCESS) {
2965 return r;
2966 }
2967 }
2968 }
2969 return r;
2970 }
2971
composite_close(int sub_api,struct libusb_device_handle * dev_handle)2972 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
2973 {
2974 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2975 uint8_t i;
2976 bool available[SUB_API_MAX];
2977
2978 for (i = 0; i<SUB_API_MAX; i++) {
2979 available[i] = false;
2980 }
2981
2982 for (i=0; i<USB_MAXINTERFACES; i++) {
2983 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
2984 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
2985 available[priv->usb_interface[i].sub_api] = true;
2986 }
2987 }
2988
2989 for (i=0; i<SUB_API_MAX; i++) {
2990 if (available[i]) {
2991 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
2992 }
2993 }
2994 }
2995
composite_claim_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2996 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2997 {
2998 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2999 return priv->usb_interface[iface].apib->
3000 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
3001 }
3002
composite_set_interface_altsetting(int sub_api,struct libusb_device_handle * dev_handle,int iface,int altsetting)3003 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3004 {
3005 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3006 return priv->usb_interface[iface].apib->
3007 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
3008 }
3009
composite_release_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)3010 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3011 {
3012 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3013 return priv->usb_interface[iface].apib->
3014 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
3015 }
3016
composite_submit_control_transfer(int sub_api,struct usbi_transfer * itransfer)3017 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3018 {
3019 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3020 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3021 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3022 int i, pass;
3023
3024 // Interface shouldn't matter for control, but it does in practice, with Windows'
3025 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
3026 for (pass = 0; pass < 2; pass++) {
3027 for (i=0; i<USB_MAXINTERFACES; i++) {
3028 if (priv->usb_interface[i].path != NULL) {
3029 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
3030 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
3031 continue;
3032 }
3033 usbi_dbg("using interface %d", i);
3034 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
3035 }
3036 }
3037 }
3038
3039 usbi_err(ctx, "no libusbx supported interfaces to complete request");
3040 return LIBUSB_ERROR_NOT_FOUND;
3041 }
3042
composite_submit_bulk_transfer(int sub_api,struct usbi_transfer * itransfer)3043 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3044 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3045 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3046 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3047 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3048 int current_interface;
3049
3050 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3051 if (current_interface < 0) {
3052 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3053 return LIBUSB_ERROR_NOT_FOUND;
3054 }
3055
3056 return priv->usb_interface[current_interface].apib->
3057 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
3058
composite_submit_iso_transfer(int sub_api,struct usbi_transfer * itransfer)3059 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
3060 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3061 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3062 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3063 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3064 int current_interface;
3065
3066 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3067 if (current_interface < 0) {
3068 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3069 return LIBUSB_ERROR_NOT_FOUND;
3070 }
3071
3072 return priv->usb_interface[current_interface].apib->
3073 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
3074
composite_clear_halt(int sub_api,struct libusb_device_handle * dev_handle,unsigned char endpoint)3075 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3076 {
3077 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3078 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3079 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3080 int current_interface;
3081
3082 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3083 if (current_interface < 0) {
3084 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3085 return LIBUSB_ERROR_NOT_FOUND;
3086 }
3087
3088 return priv->usb_interface[current_interface].apib->
3089 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
3090
composite_abort_control(int sub_api,struct usbi_transfer * itransfer)3091 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
3092 {
3093 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3094 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
3095 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3096
3097 return priv->usb_interface[transfer_priv->interface_number].apib->
3098 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
3099
composite_abort_transfers(int sub_api,struct usbi_transfer * itransfer)3100 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3101 {
3102 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3103 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
3104 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3105
3106 return priv->usb_interface[transfer_priv->interface_number].apib->
3107 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
3108
composite_reset_device(int sub_api,struct libusb_device_handle * dev_handle)3109 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3110 {
3111 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3112 int r;
3113 uint8_t i;
3114 bool available[SUB_API_MAX];
3115 for (i = 0; i<SUB_API_MAX; i++) {
3116 available[i] = false;
3117 }
3118 for (i=0; i<USB_MAXINTERFACES; i++) {
3119 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
3120 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
3121 available[priv->usb_interface[i].sub_api] = true;
3122 }
3123 }
3124 for (i=0; i<SUB_API_MAX; i++) {
3125 if (available[i]) {
3126 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
3127 if (r != LIBUSB_SUCCESS) {
3128 return r;
3129 }
3130 }
3131 }
3132 return LIBUSB_SUCCESS;
3133 }
3134
composite_copy_transfer_data(int sub_api,struct usbi_transfer * itransfer,uint32_t io_size)3135 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3136 {
3137 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3138 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
3139 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3140
3141 return priv->usb_interface[transfer_priv->interface_number].apib->
3142 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);
3143 }
3144