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
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.
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.
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
38 #include "poll_windows.h"
39 #include "windows_usb.h"
41 // The 2 macros below are used in conjunction with safe loops.
42 #define LOOP_CHECK(fcall) { r=fcall; if (r != LIBUSB_SUCCESS) continue; }
43 #define LOOP_BREAK(err) { r=err; continue; }
45 extern void usbi_fd_notification(struct libusb_context *ctx);
48 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian);
49 static int windows_clock_gettime(int clk_id, struct timespec *tp);
50 unsigned __stdcall windows_clock_gettime_threaded(void* param);
52 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
54 // WinUSB-like API prototypes
55 static int winusbx_init(int sub_api, struct libusb_context *ctx);
56 static int winusbx_exit(int sub_api);
57 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle);
58 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle);
59 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
60 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
61 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
62 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
63 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
64 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
65 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
66 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
67 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer);
68 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
69 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
71 static int hid_init(int sub_api, struct libusb_context *ctx);
72 static int hid_exit(int sub_api);
73 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle);
74 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle);
75 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
76 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
77 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
78 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
79 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
80 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
81 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
82 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
83 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
84 // Composite API prototypes
85 static int composite_init(int sub_api, struct libusb_context *ctx);
86 static int composite_exit(int sub_api);
87 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle);
88 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle);
89 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
90 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
91 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
92 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
93 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
94 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
95 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
96 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
97 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer);
98 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
99 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
103 uint64_t hires_frequency, hires_ticks_to_ps;
104 const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
105 enum windows_version windows_version = WINDOWS_UNSUPPORTED;
107 static int concurrent_usage = -1;
108 usbi_mutex_t autoclaim_lock;
110 // NB: index 0 is for monotonic and 1 is for the thread exit event
111 HANDLE timer_thread = NULL;
112 HANDLE timer_mutex = NULL;
113 struct timespec timer_tp;
114 volatile LONG request_count[2] = {0, 1}; // last one must be > 0
115 HANDLE timer_request[2] = { NULL, NULL };
116 HANDLE timer_response = NULL;
118 #define CHECK_WINUSBX_AVAILABLE(sub_api) do { if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; \
119 if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0)
120 static struct winusb_interface WinUSBX[SUB_API_MAX];
121 const char* sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES;
122 bool api_hid_available = false;
123 #define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0)
125 static inline BOOLEAN guid_eq(const GUID *guid1, const GUID *guid2) {
126 if ((guid1 != NULL) && (guid2 != NULL)) {
127 return (memcmp(guid1, guid2, sizeof(GUID)) == 0);
132 #if defined(ENABLE_LOGGING)
133 static char* guid_to_string(const GUID* guid)
135 static char guid_string[MAX_GUID_STRING_LENGTH];
137 if (guid == NULL) return NULL;
138 sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
139 (unsigned int)guid->Data1, guid->Data2, guid->Data3,
140 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
141 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
147 * Converts a windows error to human readable string
148 * uses retval as errorcode, or, if 0, use GetLastError()
150 #if defined(ENABLE_LOGGING)
151 static char *windows_error_str(uint32_t retval)
153 static char err_string[ERR_BUFFER_SIZE];
157 uint32_t error_code, format_error;
159 error_code = retval?retval:GetLastError();
161 safe_sprintf(err_string, ERR_BUFFER_SIZE, "[%u] ", error_code);
163 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
164 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
165 ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
167 format_error = GetLastError();
169 safe_sprintf(err_string, ERR_BUFFER_SIZE,
170 "Windows error code %u (FormatMessage error code %u)", error_code, format_error);
172 safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
174 // Remove CR/LF terminators
175 for (i=safe_strlen(err_string)-1; ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
184 * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
185 * Return an allocated sanitized string or NULL on error.
187 static char* sanitize_path(const char* path)
189 const char root_prefix[] = "\\\\.\\";
190 size_t j, size, root_size;
191 char* ret_path = NULL;
197 size = safe_strlen(path)+1;
198 root_size = sizeof(root_prefix)-1;
200 // Microsoft indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
201 if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
202 ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
203 add_root = root_size;
207 if ((ret_path = (char*) calloc(size, 1)) == NULL)
210 safe_strcpy(&ret_path[add_root], size-add_root, path);
212 // Ensure consistancy with root prefix
213 for (j=0; j<root_size; j++)
214 ret_path[j] = root_prefix[j];
216 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
217 for(j=root_size; j<size; j++) {
218 ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
219 if (ret_path[j] == '\\')
227 * Cfgmgr32, OLE32 and SetupAPI DLL functions
229 static int init_dlls(void)
231 DLL_LOAD(Cfgmgr32.dll, CM_Get_Parent, TRUE);
232 DLL_LOAD(Cfgmgr32.dll, CM_Get_Child, TRUE);
233 DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE);
234 DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE);
235 // Prefixed to avoid conflict with header files
236 DLL_LOAD_PREFIXED(OLE32.dll, p, CLSIDFromString, TRUE);
237 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE);
238 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE);
239 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE);
240 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
241 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
242 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
243 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
244 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
245 DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
246 DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
247 return LIBUSB_SUCCESS;
251 * enumerate interfaces for the whole USB class
254 * dev_info: a pointer to a dev_info list
255 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
256 * usb_class: the generic USB class for which to retrieve interface details
257 * index: zero based index of the interface in the device info list
259 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
260 * structure returned and call this function repeatedly using the same guid (with an
261 * incremented index starting at zero) until all interfaces have been returned.
263 static bool get_devinfo_data(struct libusb_context *ctx,
264 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, char* usb_class, unsigned _index)
267 *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
268 if (*dev_info == INVALID_HANDLE_VALUE) {
273 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
274 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
275 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
276 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
277 _index, windows_error_str(0));
279 pSetupDiDestroyDeviceInfoList(*dev_info);
280 *dev_info = INVALID_HANDLE_VALUE;
287 * enumerate interfaces for a specific GUID
290 * dev_info: a pointer to a dev_info list
291 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
292 * guid: the GUID for which to retrieve interface details
293 * index: zero based index of the interface in the device info list
295 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
296 * structure returned and call this function repeatedly using the same guid (with an
297 * incremented index starting at zero) until all interfaces have been returned.
299 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details(struct libusb_context *ctx,
300 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index)
302 SP_DEVICE_INTERFACE_DATA dev_interface_data;
303 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
307 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
310 if (dev_info_data != NULL) {
311 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
312 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
313 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
314 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
315 _index, windows_error_str(0));
317 pSetupDiDestroyDeviceInfoList(*dev_info);
318 *dev_info = INVALID_HANDLE_VALUE;
323 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
324 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
325 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
326 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
327 _index, windows_error_str(0));
329 pSetupDiDestroyDeviceInfoList(*dev_info);
330 *dev_info = INVALID_HANDLE_VALUE;
334 // Read interface data (dummy + actual) to access the device path
335 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
336 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
337 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
338 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
339 _index, windows_error_str(0));
343 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
347 if ((dev_interface_details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) calloc(size, 1)) == NULL) {
348 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
352 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
353 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
354 dev_interface_details, size, &size, NULL)) {
355 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
356 _index, windows_error_str(0));
359 return dev_interface_details;
362 pSetupDiDestroyDeviceInfoList(*dev_info);
363 *dev_info = INVALID_HANDLE_VALUE;
367 /* For libusb0 filter */
368 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
369 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index, char* filter_path){
370 SP_DEVICE_INTERFACE_DATA dev_interface_data;
371 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
374 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
376 if (dev_info_data != NULL) {
377 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
378 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
379 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
380 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
381 _index, windows_error_str(0));
383 pSetupDiDestroyDeviceInfoList(*dev_info);
384 *dev_info = INVALID_HANDLE_VALUE;
388 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
389 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
390 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
391 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
392 _index, windows_error_str(0));
394 pSetupDiDestroyDeviceInfoList(*dev_info);
395 *dev_info = INVALID_HANDLE_VALUE;
398 // Read interface data (dummy + actual) to access the device path
399 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
400 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
401 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
402 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
403 _index, windows_error_str(0));
407 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
410 if ((dev_interface_details = malloc(size)) == NULL) {
411 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
414 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
415 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
416 dev_interface_details, size, &size, NULL)) {
417 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
418 _index, windows_error_str(0));
420 // [trobinso] lookup the libusb0 symbolic index.
421 if (dev_interface_details) {
422 HKEY hkey_device_interface=pSetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ);
423 if (hkey_device_interface != INVALID_HANDLE_VALUE) {
424 DWORD libusb0_symboliclink_index=0;
425 DWORD value_length=sizeof(DWORD);
428 status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type,
429 (LPBYTE) &libusb0_symboliclink_index, &value_length);
430 if (status == ERROR_SUCCESS) {
431 if (libusb0_symboliclink_index < 256) {
432 // libusb0.sys is connected to this device instance.
433 // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
434 safe_sprintf(filter_path, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index);
435 usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
437 // libusb0.sys was connected to this device instance at one time; but not anymore.
440 pRegCloseKey(hkey_device_interface);
443 return dev_interface_details;
445 pSetupDiDestroyDeviceInfoList(*dev_info);
446 *dev_info = INVALID_HANDLE_VALUE;
449 /* Hash table functions - modified From glibc 2.3.2:
450 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
451 [Knuth] The Art of Computer Programming, part 3 (6.4) */
452 typedef struct htab_entry {
456 htab_entry* htab_table = NULL;
457 usbi_mutex_t htab_write_mutex = NULL;
458 unsigned long htab_size, htab_filled;
460 /* For the used double hash method the table size has to be a prime. To
461 correct the user given table size we need a prime test. This trivial
462 algorithm is adequate because the code is called only during init and
463 the number is likely to be small */
464 static int isprime(unsigned long number)
466 // no even number will be passed
467 unsigned int divider = 3;
469 while((divider * divider < number) && (number % divider != 0))
472 return (number % divider != 0);
475 /* Before using the hash table we must allocate memory for it.
476 We allocate one element more as the found prime number says.
477 This is done for more effective indexing as explained in the
478 comment for the hash function. */
479 static int htab_create(struct libusb_context *ctx, unsigned long nel)
481 if (htab_table != NULL) {
482 usbi_err(ctx, "hash table already allocated");
486 usbi_mutex_init(&htab_write_mutex, NULL);
488 // Change nel to the first prime number not smaller as nel.
494 usbi_dbg("using %d entries hash table", nel);
497 // allocate memory and zero out.
498 htab_table = (htab_entry*) calloc(htab_size + 1, sizeof(htab_entry));
499 if (htab_table == NULL) {
500 usbi_err(ctx, "could not allocate space for hash table");
507 /* After using the hash table it has to be destroyed. */
508 static void htab_destroy(void)
511 if (htab_table == NULL) {
515 for (i=0; i<htab_size; i++) {
516 if (htab_table[i].used) {
517 safe_free(htab_table[i].str);
520 usbi_mutex_destroy(&htab_write_mutex);
521 safe_free(htab_table);
524 /* This is the search function. It uses double hashing with open addressing.
525 We use an trick to speed up the lookup. The table is created with one
526 more element available. This enables us to use the index zero special.
527 This index will never be used because we store the first hash index in
528 the field used where zero means not used. Every other value means used.
529 The used field can be used as a first fast comparison for equality of
530 the stored and the parameter value. This helps to prevent unnecessary
531 expensive calls of strcmp. */
532 static unsigned long htab_hash(char* str)
534 unsigned long hval, hval2;
536 unsigned long r = 5381;
540 // Compute main hash value (algorithm suggested by Nokia)
541 while ((c = *sz++) != 0)
542 r = ((r << 5) + r) + c;
546 // compute table hash: simply take the modulus
547 hval = r % htab_size;
551 // Try the first index
554 if (htab_table[idx].used) {
555 if ( (htab_table[idx].used == hval)
556 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
560 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
562 // Second hash function, as suggested in [Knuth]
563 hval2 = 1 + hval % (htab_size - 2);
566 // Because size is prime this guarantees to step through all available indexes
568 idx = htab_size + idx - hval2;
573 // If we visited all entries leave the loop unsuccessfully
578 // If entry is found use it.
579 if ( (htab_table[idx].used == hval)
580 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
584 while (htab_table[idx].used);
587 // Not found => New entry
589 // If the table is full return an error
590 if (htab_filled >= htab_size) {
591 usbi_err(NULL, "hash table is full (%d entries)", htab_size);
595 // Concurrent threads might be storing the same entry at the same time
596 // (eg. "simultaneous" enums from different threads) => use a mutex
597 usbi_mutex_lock(&htab_write_mutex);
598 // Just free any previously allocated string (which should be the same as
599 // new one). The possibility of concurrent threads storing a collision
600 // string (same hash, different string) at the same time is extremely low
601 safe_free(htab_table[idx].str);
602 htab_table[idx].used = hval;
603 htab_table[idx].str = (char*) malloc(safe_strlen(str)+1);
604 if (htab_table[idx].str == NULL) {
605 usbi_err(NULL, "could not duplicate string for hash table");
606 usbi_mutex_unlock(&htab_write_mutex);
609 memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
611 usbi_mutex_unlock(&htab_write_mutex);
617 * Returns the session ID of a device's nth level ancestor
618 * If there's no device at the nth level, return 0
620 static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
622 DWORD parent_devinst;
623 unsigned long session_id = 0;
624 char* sanitized_path = NULL;
625 char path[MAX_PATH_LENGTH];
628 if (level < 1) return 0;
629 for (i = 0; i<level; i++) {
630 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
633 devinst = parent_devinst;
635 if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
638 // TODO: (post hotplug): try without sanitizing
639 sanitized_path = sanitize_path(path);
640 if (sanitized_path == NULL) {
643 session_id = htab_hash(sanitized_path);
644 safe_free(sanitized_path);
649 * Populate the endpoints addresses of the device_priv interface helper structs
651 static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
654 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
655 struct libusb_config_descriptor *conf_desc;
656 const struct libusb_interface_descriptor *if_desc;
657 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
659 r = libusb_get_config_descriptor(dev_handle->dev, 0, &conf_desc);
660 if (r != LIBUSB_SUCCESS) {
661 usbi_warn(ctx, "could not read config descriptor: error %d", r);
665 if_desc = &conf_desc->interface[iface].altsetting[altsetting];
666 safe_free(priv->usb_interface[iface].endpoint);
668 if (if_desc->bNumEndpoints == 0) {
669 usbi_dbg("no endpoints found for interface %d", iface);
670 return LIBUSB_SUCCESS;
673 priv->usb_interface[iface].endpoint = (uint8_t*) malloc(if_desc->bNumEndpoints);
674 if (priv->usb_interface[iface].endpoint == NULL) {
675 return LIBUSB_ERROR_NO_MEM;
678 priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
679 for (i=0; i<if_desc->bNumEndpoints; i++) {
680 priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
681 usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface);
683 libusb_free_config_descriptor(conf_desc);
685 // Extra init may be required to configure endpoints
686 return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
689 // Lookup for a match in the list of API driver names
690 // return -1 if not found, driver match number otherwise
691 static int get_sub_api(char* driver, int api){
693 const char sep_str[2] = {LIST_SEPARATOR, 0};
695 size_t len = safe_strlen(driver);
697 if (len == 0) return SUB_API_NOTSET;
698 tmp_str = (char*) calloc(len+1, 1);
699 if (tmp_str == NULL) return SUB_API_NOTSET;
700 memcpy(tmp_str, driver, len+1);
701 tok = strtok(tmp_str, sep_str);
702 while (tok != NULL) {
703 for (i=0; i<usb_api_backend[api].nb_driver_names; i++) {
704 if (safe_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
709 tok = strtok(NULL, sep_str);
712 return SUB_API_NOTSET;
716 * auto-claiming and auto-release helper functions
718 static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
720 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
721 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
722 transfer->dev_handle);
723 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
724 int current_interface = *interface_number;
725 int r = LIBUSB_SUCCESS;
728 case USB_API_WINUSBX:
732 return LIBUSB_ERROR_INVALID_PARAM;
735 usbi_mutex_lock(&autoclaim_lock);
736 if (current_interface < 0) // No serviceable interface was found
738 for (current_interface=0; current_interface<USB_MAXINTERFACES; current_interface++) {
739 // Must claim an interface of the same API type
740 if ( (priv->usb_interface[current_interface].apib->id == api_type)
741 && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS) ) {
742 usbi_dbg("auto-claimed interface %d for control request", current_interface);
743 if (handle_priv->autoclaim_count[current_interface] != 0) {
744 usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero");
746 handle_priv->autoclaim_count[current_interface]++;
750 if (current_interface == USB_MAXINTERFACES) {
751 usbi_err(ctx, "could not auto-claim any interface");
752 r = LIBUSB_ERROR_NOT_FOUND;
755 // If we have a valid interface that was autoclaimed, we must increment
756 // its autoclaim count so that we can prevent an early release.
757 if (handle_priv->autoclaim_count[current_interface] != 0) {
758 handle_priv->autoclaim_count[current_interface]++;
761 usbi_mutex_unlock(&autoclaim_lock);
763 *interface_number = current_interface;
768 static void auto_release(struct usbi_transfer *itransfer)
770 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
771 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
772 libusb_device_handle *dev_handle = transfer->dev_handle;
773 struct windows_device_handle_priv* handle_priv = _device_handle_priv(dev_handle);
776 usbi_mutex_lock(&autoclaim_lock);
777 if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
778 handle_priv->autoclaim_count[transfer_priv->interface_number]--;
779 if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
780 r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
781 if (r == LIBUSB_SUCCESS) {
782 usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
784 usbi_dbg("failed to auto-release interface %d (%s)",
785 transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
789 usbi_mutex_unlock(&autoclaim_lock);
793 * init: libusbx backend init function
795 * This function enumerates the HCDs (Host Controller Drivers) and populates our private HCD list
796 * In our implementation, we equate Windows' "HCD" to libusbx's "bus". Note that bus is zero indexed.
797 * HCDs are not expected to change after init (might not hold true for hot pluggable USB PCI card?)
799 static int windows_init(struct libusb_context *ctx)
801 int i, r = LIBUSB_ERROR_OTHER;
802 OSVERSIONINFO os_version;
804 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
806 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
807 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
808 if (semaphore == NULL) {
809 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
810 return LIBUSB_ERROR_NO_MEM;
813 // A successful wait brings our semaphore count to 0 (unsignaled)
814 // => any concurent wait stalls until the semaphore's release
815 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
816 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
817 CloseHandle(semaphore);
818 return LIBUSB_ERROR_NO_MEM;
821 // NB: concurrent usage supposes that init calls are equally balanced with
822 // exit calls. If init is called more than exit, we will not exit properly
823 if ( ++concurrent_usage == 0 ) { // First init?
825 memset(&os_version, 0, sizeof(OSVERSIONINFO));
826 os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
827 windows_version = WINDOWS_UNSUPPORTED;
828 if ((GetVersionEx(&os_version) != 0) && (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
829 if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 1)) {
830 windows_version = WINDOWS_XP;
831 } else if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 2)) {
832 windows_version = WINDOWS_2003; // also includes XP 64
833 } else if (os_version.dwMajorVersion >= 6) {
834 windows_version = WINDOWS_VISTA_AND_LATER;
837 if (windows_version == WINDOWS_UNSUPPORTED) {
838 usbi_err(ctx, "This version of Windows is NOT supported");
839 r = LIBUSB_ERROR_NOT_SUPPORTED;
843 // We need a lock for proper auto-release
844 usbi_mutex_init(&autoclaim_lock, NULL);
846 // Initialize pollable file descriptors
850 if (init_dlls() != LIBUSB_SUCCESS) {
851 usbi_err(ctx, "could not resolve DLL functions");
852 return LIBUSB_ERROR_NOT_FOUND;
855 // Initialize the low level APIs (we don't care about errors at this stage)
856 for (i=0; i<USB_API_MAX; i++) {
857 usb_api_backend[i].init(SUB_API_NOTSET, ctx);
860 // Because QueryPerformanceCounter might report different values when
861 // running on different cores, we create a separate thread for the timer
862 // calls, which we glue to the first core always to prevent timing discrepancies.
863 r = LIBUSB_ERROR_NO_MEM;
864 for (i = 0; i < 2; i++) {
865 timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
866 if (timer_request[i] == NULL) {
867 usbi_err(ctx, "could not create timer request event %d - aborting", i);
871 timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
872 if (timer_response == NULL) {
873 usbi_err(ctx, "could not create timer response semaphore - aborting");
876 timer_mutex = CreateMutex(NULL, FALSE, NULL);
877 if (timer_mutex == NULL) {
878 usbi_err(ctx, "could not create timer mutex - aborting");
881 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, NULL, 0, NULL);
882 if (timer_thread == NULL) {
883 usbi_err(ctx, "Unable to create timer thread - aborting");
886 SetThreadAffinityMask(timer_thread, 0);
888 // Create a hash table to store session ids. Second parameter is better if prime
889 htab_create(ctx, HTAB_SIZE);
891 // At this stage, either we went through full init successfully, or didn't need to
894 init_exit: // Holds semaphore here.
895 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
897 SetEvent(timer_request[1]); // actually the signal to quit the thread.
898 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
899 usbi_warn(ctx, "could not wait for timer thread to quit");
900 TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
901 // all objects it might have held anyway.
903 CloseHandle(timer_thread);
906 for (i = 0; i < 2; i++) {
907 if (timer_request[i]) {
908 CloseHandle(timer_request[i]);
909 timer_request[i] = NULL;
912 if (timer_response) {
913 CloseHandle(timer_response);
914 timer_response = NULL;
917 CloseHandle(timer_mutex);
923 if (r != LIBUSB_SUCCESS)
924 --concurrent_usage; // Not expected to call libusb_exit if we failed.
926 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
927 CloseHandle(semaphore);
932 * HCD (root) hubs need to have their device descriptor manually populated
934 * Note that, like Microsoft does in the device manager, we populate the
935 * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device.
937 static int force_hcd_device_descriptor(struct libusb_device *dev)
939 struct windows_device_priv *parent_priv, *priv = _device_priv(dev);
940 struct libusb_context *ctx = DEVICE_CTX(dev);
943 dev->num_configurations = 1;
944 priv->dev_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
945 priv->dev_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
946 priv->dev_descriptor.bNumConfigurations = 1;
947 priv->active_config = 1;
949 if (priv->parent_dev == NULL) {
950 usbi_err(ctx, "program assertion failed - HCD hub has no parent");
951 return LIBUSB_ERROR_NO_DEVICE;
953 parent_priv = _device_priv(priv->parent_dev);
954 if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) {
955 priv->dev_descriptor.idVendor = (uint16_t)vid;
956 priv->dev_descriptor.idProduct = (uint16_t)pid;
958 usbi_warn(ctx, "could not infer VID/PID of HCD hub from '%s'", parent_priv->path);
959 priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub
960 priv->dev_descriptor.idProduct = 1;
962 return LIBUSB_SUCCESS;
966 * fetch and cache all the config descriptors through I/O
968 static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char* device_id)
970 DWORD size, ret_size;
971 struct libusb_context *ctx = DEVICE_CTX(dev);
972 struct windows_device_priv *priv = _device_priv(dev);
976 USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
977 PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
978 PUSB_CONFIGURATION_DESCRIPTOR cd_data = NULL;
980 if (dev->num_configurations == 0)
981 return LIBUSB_ERROR_INVALID_PARAM;
983 priv->config_descriptor = (unsigned char**) calloc(dev->num_configurations, sizeof(unsigned char*));
984 if (priv->config_descriptor == NULL)
985 return LIBUSB_ERROR_NO_MEM;
986 for (i=0; i<dev->num_configurations; i++)
987 priv->config_descriptor[i] = NULL;
989 for (i=0, r=LIBUSB_SUCCESS; ; i++)
991 // safe loop: release all dynamic resources
992 safe_free(cd_buf_actual);
994 // safe loop: end of loop condition
995 if ((i >= dev->num_configurations) || (r != LIBUSB_SUCCESS))
998 size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT);
999 memset(&cd_buf_short, 0, size);
1001 cd_buf_short.req.ConnectionIndex = (ULONG)priv->port;
1002 cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1003 cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1004 cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1005 cd_buf_short.req.SetupPacket.wIndex = i;
1006 cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1008 // Dummy call to get the required data size. Initial failures are reported as info rather
1009 // than error as they can occur for non-penalizing situations, such as with some hubs.
1010 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
1011 &cd_buf_short, size, &ret_size, NULL)) {
1012 usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
1013 LOOP_BREAK(LIBUSB_ERROR_IO);
1016 if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
1017 usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
1018 LOOP_BREAK(LIBUSB_ERROR_IO);
1021 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
1022 if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
1023 usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
1024 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1026 memset(cd_buf_actual, 0, size);
1029 cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
1030 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1031 cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1032 cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1033 cd_buf_actual->SetupPacket.wIndex = i;
1034 cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1036 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1037 cd_buf_actual, size, &ret_size, NULL)) {
1038 usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1039 LOOP_BREAK(LIBUSB_ERROR_IO);
1042 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1044 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1045 usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1046 LOOP_BREAK(LIBUSB_ERROR_IO);
1049 if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1050 usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1051 LOOP_BREAK(LIBUSB_ERROR_IO);
1054 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1055 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1057 // Cache the descriptor
1058 priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1059 if (priv->config_descriptor[i] == NULL)
1060 return LIBUSB_ERROR_NO_MEM;
1061 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1063 return LIBUSB_SUCCESS;
1067 * Populate a libusbx device structure
1069 static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1070 uint8_t port_number, char* device_id, DWORD devinst)
1074 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1075 struct windows_device_priv *priv, *parent_priv;
1076 struct libusb_context *ctx = DEVICE_CTX(dev);
1077 struct libusb_device* tmp_dev;
1080 if ((dev == NULL) || (parent_dev == NULL)) {
1081 return LIBUSB_ERROR_NOT_FOUND;
1083 priv = _device_priv(dev);
1084 parent_priv = _device_priv(parent_dev);
1085 if (parent_priv->apib->id != USB_API_HUB) {
1086 usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1087 return LIBUSB_ERROR_NOT_FOUND;
1090 // It is possible for the parent hub not to have been initialized yet
1091 // If that's the case, lookup the ancestors to set the bus number
1092 if (parent_dev->bus_number == 0) {
1094 tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
1095 if (tmp_dev == NULL) break;
1096 if (tmp_dev->bus_number != 0) {
1097 usbi_dbg("got bus number from ancestor #%d", i);
1098 parent_dev->bus_number = tmp_dev->bus_number;
1103 if (parent_dev->bus_number == 0) {
1104 usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1105 return LIBUSB_ERROR_NOT_FOUND;
1107 dev->bus_number = parent_dev->bus_number;
1108 priv->port = port_number;
1109 dev->port_number = port_number;
1110 priv->depth = parent_priv->depth + 1;
1111 priv->parent_dev = parent_dev;
1112 dev->parent_dev = parent_dev;
1114 // If the device address is already set, we can stop here
1115 if (dev->device_address != 0) {
1116 return LIBUSB_SUCCESS;
1118 memset(&conn_info, 0, sizeof(conn_info));
1119 if (priv->depth != 0) { // Not a HCD hub
1120 handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1121 FILE_FLAG_OVERLAPPED, NULL);
1122 if (handle == INVALID_HANDLE_VALUE) {
1123 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1124 return LIBUSB_ERROR_ACCESS;
1126 size = sizeof(conn_info);
1127 conn_info.ConnectionIndex = (ULONG)port_number;
1128 if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1129 &conn_info, size, &size, NULL)) {
1130 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1131 device_id, windows_error_str(0));
1132 safe_closehandle(handle);
1133 return LIBUSB_ERROR_NO_DEVICE;
1135 if (conn_info.ConnectionStatus == NoDeviceConnected) {
1136 usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1137 safe_closehandle(handle);
1138 return LIBUSB_ERROR_NO_DEVICE;
1140 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1141 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1142 priv->active_config = conn_info.CurrentConfigurationValue;
1143 usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1144 // If we can't read the config descriptors, just set the number of confs to zero
1145 if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1146 dev->num_configurations = 0;
1147 priv->dev_descriptor.bNumConfigurations = 0;
1149 safe_closehandle(handle);
1151 if (conn_info.DeviceAddress > UINT8_MAX) {
1152 usbi_err(ctx, "program assertion failed: device address overflow");
1154 dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1155 if (dev->device_address == 1) {
1156 usbi_err(ctx, "program assertion failed: device address collision with root hub");
1158 switch (conn_info.Speed) {
1159 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1160 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1161 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1162 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1164 usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1168 dev->device_address = 1; // root hubs are set to use device number 1
1169 force_hcd_device_descriptor(dev);
1172 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1173 dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1175 return LIBUSB_SUCCESS;
1178 // Returns the api type, or 0 if not found/unsupported
1179 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1180 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1182 // Precedence for filter drivers vs driver is in the order of this array
1183 struct driver_lookup lookup[3] = {
1184 {"\0\0", SPDRP_SERVICE, "driver"},
1185 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1186 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1188 DWORD size, reg_type;
1192 *api = USB_API_UNSUPPORTED;
1193 *sub_api = SUB_API_NOTSET;
1194 // Check the service & filter names to know the API we should use
1195 for (k=0; k<3; k++) {
1196 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1197 ®_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1198 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1199 if (lookup[k].reg_prop == SPDRP_SERVICE) {
1200 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1201 lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1203 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1204 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1205 // (currently ';'), so even if an unsuported one does, it's not an issue
1206 for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1207 if (lookup[k].list[l] == 0) {
1208 lookup[k].list[l] = LIST_SEPARATOR;
1211 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1213 if (GetLastError() != ERROR_INVALID_DATA) {
1214 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1216 lookup[k].list[0] = 0;
1220 for (i=1; i<USB_API_MAX; i++) {
1221 for (k=0; k<3; k++) {
1222 j = get_sub_api(lookup[k].list, i);
1224 usbi_dbg("matched %s name against %s API",
1225 lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1234 static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1235 char* dev_interface_path, char* device_id, int api, int sub_api)
1238 struct windows_device_priv *priv = _device_priv(dev);
1239 int interface_number;
1241 if (priv->apib->id != USB_API_COMPOSITE) {
1242 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1243 return LIBUSB_ERROR_NO_DEVICE;
1246 // Because MI_## are not necessarily in sequential order (some composite
1247 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1248 // interface number from the path's MI value
1249 interface_number = 0;
1250 for (i=0; device_id[i] != 0; ) {
1251 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1252 && (device_id[i++] == '_') ) {
1253 interface_number = (device_id[i++] - '0')*10;
1254 interface_number += device_id[i] - '0';
1259 if (device_id[i] == 0) {
1260 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1261 device_id, interface_number);
1264 if (priv->usb_interface[interface_number].path != NULL) {
1265 if (api == USB_API_HID) {
1266 // HID devices can have multiple collections (COL##) for each MI_## interface
1267 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1268 interface_number, device_id);
1269 return LIBUSB_ERROR_ACCESS;
1271 // In other cases, just use the latest data
1272 safe_free(priv->usb_interface[interface_number].path);
1275 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1276 priv->usb_interface[interface_number].path = dev_interface_path;
1277 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1278 priv->usb_interface[interface_number].sub_api = sub_api;
1279 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1280 priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
1281 if (priv->hid == NULL)
1282 return LIBUSB_ERROR_NO_MEM;
1285 return LIBUSB_SUCCESS;
1288 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1289 char* dev_interface_path)
1291 struct windows_device_priv *priv = _device_priv(dev);
1293 if (priv->hid == NULL) {
1294 usbi_err(ctx, "program assertion failed: parent is not HID");
1295 return LIBUSB_ERROR_NO_DEVICE;
1297 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1298 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1299 return LIBUSB_ERROR_NO_DEVICE;
1301 if (priv->usb_interface[priv->hid->nb_interfaces].path != NULL) {
1302 safe_free(priv->usb_interface[priv->hid->nb_interfaces].path);
1305 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1306 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1307 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1308 priv->hid->nb_interfaces++;
1309 return LIBUSB_SUCCESS;
1313 * get_device_list: libusbx backend device enumeration function
1315 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1317 struct discovered_devs *discdevs;
1318 HDEVINFO dev_info = { 0 };
1319 char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1320 SP_DEVINFO_DATA dev_info_data = { 0 };
1321 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1323 #define MAX_ENUM_GUIDS 64
1324 const GUID* guid[MAX_ENUM_GUIDS];
1330 int r = LIBUSB_SUCCESS;
1332 int class_index = 0;
1333 unsigned int nb_guids, pass, i, j, ancestor;
1334 char path[MAX_PATH_LENGTH];
1335 char strbuf[MAX_PATH_LENGTH];
1336 struct libusb_device *dev, *parent_dev;
1337 struct windows_device_priv *priv, *parent_priv;
1338 char* dev_interface_path = NULL;
1339 char* dev_id_path = NULL;
1340 unsigned long session_id;
1341 DWORD size, reg_type, port_nr, install_state;
1343 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1346 // Keep a list of newly allocated devs to unref
1347 libusb_device** unref_list;
1348 unsigned int unref_size = 64;
1349 unsigned int unref_cur = 0;
1351 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1352 // PASS 2 : (re)enumerate HUBS
1353 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1354 // and list additional USB device interface GUIDs to explore
1355 // PASS 4 : (re)enumerate master USB devices that have a device interface
1356 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1357 // set the device interfaces.
1359 // Init the GUID table
1360 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1361 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1362 guid[GEN_PASS] = NULL;
1363 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1364 HidD_GetHidGuid(&hid_guid);
1365 guid[HID_PASS] = &hid_guid;
1366 nb_guids = HID_PASS+1;
1368 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1369 if (unref_list == NULL) {
1370 return LIBUSB_ERROR_NO_MEM;
1373 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1374 //#define ENUM_DEBUG
1376 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1377 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1378 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1380 for (i = 0; ; i++) {
1381 // safe loop: free up any (unprotected) dynamic resource
1382 // NB: this is always executed before breaking the loop
1383 safe_free(dev_interface_details);
1384 safe_free(dev_interface_path);
1385 safe_free(dev_id_path);
1386 priv = parent_priv = NULL;
1387 dev = parent_dev = NULL;
1389 // Safe loop: end of loop conditions
1390 if (r != LIBUSB_SUCCESS) {
1393 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1394 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1397 if (pass != GEN_PASS) {
1398 // Except for GEN, all passes deal with device interfaces
1399 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1400 if (dev_interface_details == NULL) {
1403 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1404 if (dev_interface_path == NULL) {
1405 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1410 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1411 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1412 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1413 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1414 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1418 if (class_index >= ARRAYSIZE(usb_class))
1422 // Read the Device ID path. This is what we'll use as UID
1423 // Note that if the device is plugged in a different port or hub, the Device ID changes
1424 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1425 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1426 dev_info_data.DevInst);
1429 dev_id_path = sanitize_path(path);
1430 if (dev_id_path == NULL) {
1431 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1432 dev_info_data.DevInst);
1436 usbi_dbg("PRO: %s", dev_id_path);
1439 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1441 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1442 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1443 ®_type, (BYTE*)&port_nr, 4, &size))
1445 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1446 dev_id_path, windows_error_str(0));
1451 // Set API to use or get additional data from generic pass
1452 api = USB_API_UNSUPPORTED;
1453 sub_api = SUB_API_NOTSET;
1458 // We use the GEN pass to detect driverless devices...
1459 size = sizeof(strbuf);
1460 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1461 ®_type, (BYTE*)strbuf, size, &size)) {
1462 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1463 usbi_info(ctx, "libusbx will not be able to access it.");
1465 // ...and to add the additional device interface GUIDs
1466 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1467 if (key != INVALID_HANDLE_VALUE) {
1468 size = sizeof(guid_string_w);
1469 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1470 (BYTE*)guid_string_w, &size);
1472 if (s == ERROR_SUCCESS) {
1473 if (nb_guids >= MAX_ENUM_GUIDS) {
1474 // If this assert is ever reported, grow a GUID table dynamically
1475 usbi_err(ctx, "program assertion failed: too many GUIDs");
1476 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1478 if_guid = (GUID*) calloc(1, sizeof(GUID));
1479 pCLSIDFromString(guid_string_w, if_guid);
1480 guid[nb_guids++] = if_guid;
1481 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1489 // Get the API type (after checking that the driver installation is OK)
1490 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1491 ®_type, (BYTE*)&install_state, 4, &size))
1493 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1494 dev_id_path, windows_error_str(0));
1495 } else if (install_state != 0) {
1496 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1497 dev_id_path, install_state);
1500 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1504 // Find parent device (for the passes that need it)
1511 // Go through the ancestors until we see a face we recognize
1513 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1514 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1515 if (session_id == 0) {
1518 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1520 if (parent_dev == NULL) {
1521 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1524 parent_priv = _device_priv(parent_dev);
1525 // virtual USB devices are also listed during GEN - don't process these yet
1526 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1532 // Create new or match existing device, using the (hashed) device_id as session id
1533 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1534 // These are the passes that create "new" devices
1535 session_id = htab_hash(dev_id_path);
1536 dev = usbi_get_device_by_session_id(ctx, session_id);
1538 if (pass == DEV_PASS) {
1539 // This can occur if the OS only reports a newly plugged device after we started enum
1540 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1541 " - ignoring", dev_id_path);
1544 usbi_dbg("allocating new device for session [%X]", session_id);
1545 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1546 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1548 windows_device_priv_init(dev);
1549 // Keep track of devices that need unref
1550 unref_list[unref_cur++] = dev;
1551 if (unref_cur >= unref_size) {
1553 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1554 if (unref_list == NULL) {
1555 usbi_err(ctx, "could not realloc list for unref - aborting.");
1556 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1560 usbi_dbg("found existing device for session [%X] (%d.%d)",
1561 session_id, dev->bus_number, dev->device_address);
1563 priv = _device_priv(dev);
1569 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1570 dev->device_address = 0;
1571 dev->num_configurations = 0;
1572 priv->apib = &usb_api_backend[USB_API_HUB];
1573 priv->sub_api = SUB_API_NOTSET;
1574 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1575 priv->path = dev_interface_path; dev_interface_path = NULL;
1579 // If the device has already been setup, don't do it again
1580 if (priv->path != NULL)
1582 // Take care of API initialization
1583 priv->path = dev_interface_path; dev_interface_path = NULL;
1584 priv->apib = &usb_api_backend[api];
1585 priv->sub_api = sub_api;
1587 case USB_API_COMPOSITE:
1591 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1592 if (priv->hid == NULL) {
1593 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1595 priv->hid->nb_interfaces = 0;
1598 // For other devices, the first interface is the same as the device
1599 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1600 if (priv->usb_interface[0].path != NULL) {
1601 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1603 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1605 // The following is needed if we want API calls to work for both simple
1606 // and composite devices.
1607 for(j=0; j<USB_MAXINTERFACES; j++) {
1608 priv->usb_interface[j].apib = &usb_api_backend[api];
1614 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1615 if (r == LIBUSB_SUCCESS) {
1616 // Append device to the list of discovered devices
1617 discdevs = discovered_devs_append(*_discdevs, dev);
1619 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1621 *_discdevs = discdevs;
1622 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1623 // This can occur if the device was disconnected but Windows hasn't
1624 // refreshed its enumeration yet - in that case, we ignore the device
1628 default: // HID_PASS and later
1629 if (parent_priv->apib->id == USB_API_HID) {
1630 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1631 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1632 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1633 dev_interface_path = NULL;
1634 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1635 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1636 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1637 case LIBUSB_SUCCESS:
1638 dev_interface_path = NULL;
1640 case LIBUSB_ERROR_ACCESS:
1641 // interface has already been set => make sure dev_interface_path is freed then
1653 // Free any additional GUIDs
1654 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1655 safe_free(guid[pass]);
1658 // Unref newly allocated devs
1659 for (i=0; i<unref_cur; i++) {
1660 safe_unref_device(unref_list[i]);
1662 safe_free(unref_list);
1668 * exit: libusbx backend deinitialization function
1670 static void windows_exit(void)
1674 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1676 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1677 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1678 if (semaphore == NULL) {
1682 // A successful wait brings our semaphore count to 0 (unsignaled)
1683 // => any concurent wait stalls until the semaphore release
1684 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1685 CloseHandle(semaphore);
1689 // Only works if exits and inits are balanced exactly
1690 if (--concurrent_usage < 0) { // Last exit
1691 for (i=0; i<USB_API_MAX; i++) {
1692 usb_api_backend[i].exit(SUB_API_NOTSET);
1697 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1698 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1699 usbi_dbg("could not wait for timer thread to quit");
1700 TerminateThread(timer_thread, 1);
1702 CloseHandle(timer_thread);
1703 timer_thread = NULL;
1705 for (i = 0; i < 2; i++) {
1706 if (timer_request[i]) {
1707 CloseHandle(timer_request[i]);
1708 timer_request[i] = NULL;
1711 if (timer_response) {
1712 CloseHandle(timer_response);
1713 timer_response = NULL;
1716 CloseHandle(timer_mutex);
1722 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1723 CloseHandle(semaphore);
1726 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1728 struct windows_device_priv *priv = _device_priv(dev);
1730 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1733 return LIBUSB_SUCCESS;
1736 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1738 struct windows_device_priv *priv = _device_priv(dev);
1739 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1742 // config index is zero based
1743 if (config_index >= dev->num_configurations)
1744 return LIBUSB_ERROR_INVALID_PARAM;
1746 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1747 return LIBUSB_ERROR_NOT_FOUND;
1749 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1751 size = min(config_header->wTotalLength, len);
1752 memcpy(buffer, priv->config_descriptor[config_index], size);
1754 return LIBUSB_SUCCESS;
1758 * return the cached copy of the active config descriptor
1760 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1762 struct windows_device_priv *priv = _device_priv(dev);
1764 if (priv->active_config == 0)
1765 return LIBUSB_ERROR_NOT_FOUND;
1767 // config index is zero based
1768 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1771 static int windows_open(struct libusb_device_handle *dev_handle)
1773 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1774 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1776 if (priv->apib == NULL) {
1777 usbi_err(ctx, "program assertion failed - device is not initialized");
1778 return LIBUSB_ERROR_NO_DEVICE;
1781 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1784 static void windows_close(struct libusb_device_handle *dev_handle)
1786 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1788 priv->apib->close(SUB_API_NOTSET, dev_handle);
1791 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1793 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1795 if (priv->active_config == 0) {
1797 return LIBUSB_ERROR_NOT_FOUND;
1800 *config = priv->active_config;
1801 return LIBUSB_SUCCESS;
1805 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1806 * does not currently expose a service that allows higher-level drivers to set
1807 * the configuration."
1809 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1811 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1812 int r = LIBUSB_SUCCESS;
1814 if (config >= USB_MAXCONFIG)
1815 return LIBUSB_ERROR_INVALID_PARAM;
1817 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1818 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1819 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1822 if (r == LIBUSB_SUCCESS) {
1823 priv->active_config = (uint8_t)config;
1828 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1830 int r = LIBUSB_SUCCESS;
1831 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1833 if (iface >= USB_MAXINTERFACES)
1834 return LIBUSB_ERROR_INVALID_PARAM;
1836 safe_free(priv->usb_interface[iface].endpoint);
1837 priv->usb_interface[iface].nb_endpoints= 0;
1839 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1841 if (r == LIBUSB_SUCCESS) {
1842 r = windows_assign_endpoints(dev_handle, iface, 0);
1848 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1850 int r = LIBUSB_SUCCESS;
1851 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1853 safe_free(priv->usb_interface[iface].endpoint);
1854 priv->usb_interface[iface].nb_endpoints= 0;
1856 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1858 if (r == LIBUSB_SUCCESS) {
1859 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1865 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1867 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1869 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1872 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1874 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1875 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1878 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1880 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1881 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1884 // The 3 functions below are unlikely to ever get supported on Windows
1885 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1887 return LIBUSB_ERROR_NOT_SUPPORTED;
1890 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1892 return LIBUSB_ERROR_NOT_SUPPORTED;
1895 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1897 return LIBUSB_ERROR_NOT_SUPPORTED;
1900 static void windows_destroy_device(struct libusb_device *dev)
1902 windows_device_priv_release(dev);
1905 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1907 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1909 usbi_free_fd(transfer_priv->pollable_fd.fd);
1910 safe_free(transfer_priv->hid_buffer);
1911 // When auto claim is in use, attempt to release the auto-claimed interface
1912 auto_release(itransfer);
1915 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1917 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1918 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1919 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1920 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1923 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1924 if (r != LIBUSB_SUCCESS) {
1928 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1929 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1931 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1932 return LIBUSB_SUCCESS;
1935 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1937 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1938 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1939 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1940 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1943 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1944 if (r != LIBUSB_SUCCESS) {
1948 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1949 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1951 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1952 return LIBUSB_SUCCESS;
1955 static int submit_control_transfer(struct usbi_transfer *itransfer)
1957 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1958 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1959 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1960 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1963 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1964 if (r != LIBUSB_SUCCESS) {
1968 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
1970 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1971 return LIBUSB_SUCCESS;
1975 static int windows_submit_transfer(struct usbi_transfer *itransfer)
1977 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1979 switch (transfer->type) {
1980 case LIBUSB_TRANSFER_TYPE_CONTROL:
1981 return submit_control_transfer(itransfer);
1982 case LIBUSB_TRANSFER_TYPE_BULK:
1983 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1984 if (IS_XFEROUT(transfer) &&
1985 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
1986 return LIBUSB_ERROR_NOT_SUPPORTED;
1987 return submit_bulk_transfer(itransfer);
1988 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1989 return submit_iso_transfer(itransfer);
1991 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1992 return LIBUSB_ERROR_INVALID_PARAM;
1996 static int windows_abort_control(struct usbi_transfer *itransfer)
1998 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1999 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2001 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2004 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2006 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2007 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2009 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2012 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2014 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2016 switch (transfer->type) {
2017 case LIBUSB_TRANSFER_TYPE_CONTROL:
2018 return windows_abort_control(itransfer);
2019 case LIBUSB_TRANSFER_TYPE_BULK:
2020 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2021 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2022 return windows_abort_transfers(itransfer);
2024 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2025 return LIBUSB_ERROR_INVALID_PARAM;
2029 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2031 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2032 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2033 int status, istatus;
2035 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
2039 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2041 case ERROR_GEN_FAILURE:
2042 usbi_dbg("detected endpoint stall");
2043 status = LIBUSB_TRANSFER_STALL;
2045 case ERROR_SEM_TIMEOUT:
2046 usbi_dbg("detected semaphore timeout");
2047 status = LIBUSB_TRANSFER_TIMED_OUT;
2049 case ERROR_OPERATION_ABORTED:
2050 istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2051 if (istatus != LIBUSB_TRANSFER_COMPLETED) {
2052 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
2054 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2055 usbi_dbg("detected timeout");
2056 status = LIBUSB_TRANSFER_TIMED_OUT;
2058 usbi_dbg("detected operation aborted");
2059 status = LIBUSB_TRANSFER_CANCELLED;
2063 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(0));
2064 status = LIBUSB_TRANSFER_ERROR;
2067 windows_clear_transfer_priv(itransfer); // Cancel polling
2068 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2071 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2073 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2075 switch (transfer->type) {
2076 case LIBUSB_TRANSFER_TYPE_CONTROL:
2077 case LIBUSB_TRANSFER_TYPE_BULK:
2078 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2079 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2080 windows_transfer_callback (itransfer, io_result, io_size);
2083 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2087 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2089 struct windows_transfer_priv* transfer_priv = NULL;
2090 POLL_NFDS_TYPE i = 0;
2092 struct usbi_transfer *transfer;
2093 DWORD io_size, io_result;
2095 usbi_mutex_lock(&ctx->open_devs_lock);
2096 for (i = 0; i < nfds && num_ready > 0; i++) {
2098 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2100 if (!fds[i].revents) {
2106 // Because a Windows OVERLAPPED is used for poll emulation,
2107 // a pollable fd is created and stored with each transfer
2108 usbi_mutex_lock(&ctx->flying_transfers_lock);
2109 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2110 transfer_priv = usbi_transfer_get_os_priv(transfer);
2111 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2116 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2119 // Handle async requests that completed synchronously first
2120 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2121 io_result = NO_ERROR;
2122 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2123 // Regular async overlapped
2124 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2125 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2126 io_result = NO_ERROR;
2128 io_result = GetLastError();
2130 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2131 // let handle_callback free the event using the transfer wfd
2132 // If you don't use the transfer wfd, you run a risk of trying to free a
2133 // newly allocated wfd that took the place of the one from the transfer.
2134 windows_handle_callback(transfer, io_result, io_size);
2136 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2137 return LIBUSB_ERROR_NOT_FOUND;
2141 usbi_mutex_unlock(&ctx->open_devs_lock);
2142 return LIBUSB_SUCCESS;
2146 * Monotonic and real time functions
2148 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2150 LARGE_INTEGER hires_counter, li_frequency;
2154 // Init - find out if we have access to a monotonic (hires) timer
2155 if (!QueryPerformanceFrequency(&li_frequency)) {
2156 usbi_dbg("no hires timer available on this platform");
2157 hires_frequency = 0;
2158 hires_ticks_to_ps = UINT64_C(0);
2160 hires_frequency = li_frequency.QuadPart;
2161 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2162 // to picoseconds to compute the tv_nsecs part in clock_gettime
2163 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2164 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2167 // Main loop - wait for requests
2169 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2170 if ( (timer_index != 0) && (timer_index != 1) ) {
2171 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2174 if (request_count[timer_index] == 0) {
2175 // Request already handled
2176 ResetEvent(timer_request[timer_index]);
2177 // There's still a possiblity that a thread sends a request between the
2178 // time we test request_count[] == 0 and we reset the event, in which case
2179 // the request would be ignored. The simple solution to that is to test
2180 // request_count again and process requests if non zero.
2181 if (request_count[timer_index] == 0)
2184 switch (timer_index) {
2186 WaitForSingleObject(timer_mutex, INFINITE);
2187 // Requests to this thread are for hires always
2188 if (QueryPerformanceCounter(&hires_counter) != 0) {
2189 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2190 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2192 // Fallback to real-time if we can't get monotonic value
2193 // Note that real-time clock does not wait on the mutex or this thread.
2194 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2196 ReleaseMutex(timer_mutex);
2198 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2200 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2201 usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0));
2204 case 1: // time to quit
2205 usbi_dbg("timer thread quitting");
2211 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2214 ULARGE_INTEGER rtime;
2217 case USBI_CLOCK_MONOTONIC:
2218 if (hires_frequency != 0) {
2220 InterlockedIncrement((LONG*)&request_count[0]);
2221 SetEvent(timer_request[0]);
2222 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2225 WaitForSingleObject(timer_mutex, INFINITE);
2227 ReleaseMutex(timer_mutex);
2228 return LIBUSB_SUCCESS;
2230 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2231 break; // Retry until successful
2233 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2234 return LIBUSB_ERROR_OTHER;
2238 // Fall through and return real-time if monotonic was not detected @ timer init
2239 case USBI_CLOCK_REALTIME:
2240 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2241 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2242 // Note however that our resolution is bounded by the Windows system time
2243 // functions and is at best of the order of 1 ms (or, usually, worse)
2244 GetSystemTimeAsFileTime(&filetime);
2245 rtime.LowPart = filetime.dwLowDateTime;
2246 rtime.HighPart = filetime.dwHighDateTime;
2247 rtime.QuadPart -= epoch_time;
2248 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2249 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2250 return LIBUSB_SUCCESS;
2252 return LIBUSB_ERROR_INVALID_PARAM;
2257 // NB: MSVC6 does not support named initializers.
2258 const struct usbi_os_backend windows_backend = {
2263 windows_get_device_list,
2267 windows_get_device_descriptor,
2268 windows_get_active_config_descriptor,
2269 windows_get_config_descriptor,
2271 windows_get_configuration,
2272 windows_set_configuration,
2273 windows_claim_interface,
2274 windows_release_interface,
2276 windows_set_interface_altsetting,
2278 windows_reset_device,
2280 windows_kernel_driver_active,
2281 windows_detach_kernel_driver,
2282 windows_attach_kernel_driver,
2284 windows_destroy_device,
2286 windows_submit_transfer,
2287 windows_cancel_transfer,
2288 windows_clear_transfer_priv,
2290 windows_handle_events,
2292 windows_clock_gettime,
2293 #if defined(USBI_TIMERFD_AVAILABLE)
2296 sizeof(struct windows_device_priv),
2297 sizeof(struct windows_device_handle_priv),
2298 sizeof(struct windows_transfer_priv),
2306 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2307 return LIBUSB_SUCCESS;
2309 static int unsupported_exit(int sub_api) {
2310 return LIBUSB_SUCCESS;
2312 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2313 PRINT_UNSUPPORTED_API(open);
2315 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2316 usbi_dbg("unsupported API call for 'close'");
2318 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2319 PRINT_UNSUPPORTED_API(configure_endpoints);
2321 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2322 PRINT_UNSUPPORTED_API(claim_interface);
2324 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2325 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2327 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2328 PRINT_UNSUPPORTED_API(release_interface);
2330 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2331 PRINT_UNSUPPORTED_API(clear_halt);
2333 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2334 PRINT_UNSUPPORTED_API(reset_device);
2336 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2337 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2339 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2340 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2342 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2343 PRINT_UNSUPPORTED_API(submit_control_transfer);
2345 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2346 PRINT_UNSUPPORTED_API(abort_control);
2348 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2349 PRINT_UNSUPPORTED_API(abort_transfers);
2351 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2352 PRINT_UNSUPPORTED_API(copy_transfer_data);
2354 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2355 return LIBUSB_SUCCESS;
2357 // These names must be uppercase
2358 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2359 const char* composite_driver_names[] = {"USBCCGP"};
2360 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2361 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2362 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2364 USB_API_UNSUPPORTED,
2372 unsupported_configure_endpoints,
2373 unsupported_claim_interface,
2374 unsupported_set_interface_altsetting,
2375 unsupported_release_interface,
2376 unsupported_clear_halt,
2377 unsupported_reset_device,
2378 unsupported_submit_bulk_transfer,
2379 unsupported_submit_iso_transfer,
2380 unsupported_submit_control_transfer,
2381 unsupported_abort_control,
2382 unsupported_abort_transfers,
2383 unsupported_copy_transfer_data,
2388 ARRAYSIZE(hub_driver_names),
2393 unsupported_configure_endpoints,
2394 unsupported_claim_interface,
2395 unsupported_set_interface_altsetting,
2396 unsupported_release_interface,
2397 unsupported_clear_halt,
2398 unsupported_reset_device,
2399 unsupported_submit_bulk_transfer,
2400 unsupported_submit_iso_transfer,
2401 unsupported_submit_control_transfer,
2402 unsupported_abort_control,
2403 unsupported_abort_transfers,
2404 unsupported_copy_transfer_data,
2408 composite_driver_names,
2409 ARRAYSIZE(composite_driver_names),
2414 common_configure_endpoints,
2415 composite_claim_interface,
2416 composite_set_interface_altsetting,
2417 composite_release_interface,
2418 composite_clear_halt,
2419 composite_reset_device,
2420 composite_submit_bulk_transfer,
2421 composite_submit_iso_transfer,
2422 composite_submit_control_transfer,
2423 composite_abort_control,
2424 composite_abort_transfers,
2425 composite_copy_transfer_data,
2429 winusbx_driver_names,
2430 ARRAYSIZE(winusbx_driver_names),
2435 winusbx_configure_endpoints,
2436 winusbx_claim_interface,
2437 winusbx_set_interface_altsetting,
2438 winusbx_release_interface,
2440 winusbx_reset_device,
2441 winusbx_submit_bulk_transfer,
2442 unsupported_submit_iso_transfer,
2443 winusbx_submit_control_transfer,
2444 winusbx_abort_control,
2445 winusbx_abort_transfers,
2446 winusbx_copy_transfer_data,
2451 ARRAYSIZE(hid_driver_names),
2456 common_configure_endpoints,
2457 hid_claim_interface,
2458 hid_set_interface_altsetting,
2459 hid_release_interface,
2462 hid_submit_bulk_transfer,
2463 unsupported_submit_iso_transfer,
2464 hid_submit_control_transfer,
2465 hid_abort_transfers,
2466 hid_abort_transfers,
2467 hid_copy_transfer_data,
2473 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2475 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2476 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2478 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2481 bool native_winusb = false;
2483 KLIB_VERSION LibK_Version;
2484 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2485 LibK_GetVersion_t pLibK_GetVersion = NULL;
2487 h = GetModuleHandleA("libusbK");
2489 h = LoadLibraryA("libusbK");
2492 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2493 h = GetModuleHandleA("WinUSB");
2495 h = LoadLibraryA("WinUSB");
2497 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2498 "you will not be able to access devices outside of enumeration");
2499 return LIBUSB_ERROR_NOT_FOUND;
2502 usbi_dbg("using libusbK DLL for universal access");
2503 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2504 if (pLibK_GetVersion != NULL) {
2505 pLibK_GetVersion(&LibK_Version);
2506 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2507 LibK_Version.Micro, LibK_Version.Nano);
2509 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2510 if (pLibK_GetProcAddress == NULL) {
2511 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2512 return LIBUSB_ERROR_NOT_FOUND;
2515 native_winusb = (pLibK_GetProcAddress == NULL);
2516 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2517 WinUSBX_Set(AbortPipe);
2518 WinUSBX_Set(ControlTransfer);
2519 WinUSBX_Set(FlushPipe);
2521 WinUSBX_Set(GetAssociatedInterface);
2522 WinUSBX_Set(GetCurrentAlternateSetting);
2523 WinUSBX_Set(GetDescriptor);
2524 WinUSBX_Set(GetOverlappedResult);
2525 WinUSBX_Set(GetPipePolicy);
2526 WinUSBX_Set(GetPowerPolicy);
2527 WinUSBX_Set(Initialize);
2528 WinUSBX_Set(QueryDeviceInformation);
2529 WinUSBX_Set(QueryInterfaceSettings);
2530 WinUSBX_Set(QueryPipe);
2531 WinUSBX_Set(ReadPipe);
2532 WinUSBX_Set(ResetPipe);
2533 WinUSBX_Set(SetCurrentAlternateSetting);
2534 WinUSBX_Set(SetPipePolicy);
2535 WinUSBX_Set(SetPowerPolicy);
2536 WinUSBX_Set(WritePipe);
2537 if (!native_winusb) {
2538 WinUSBX_Set(ResetDevice);
2540 if (WinUSBX[i].Initialize != NULL) {
2541 WinUSBX[i].initialized = true;
2542 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2544 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2545 WinUSBX[i].initialized = false;
2548 return LIBUSB_SUCCESS;
2551 static int winusbx_exit(int sub_api)
2553 return LIBUSB_SUCCESS;
2556 // NB: open and close must ensure that they only handle interface of
2557 // the right API type, as these functions can be called wholesale from
2558 // composite_open(), with interfaces belonging to different APIs
2559 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2561 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2562 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2563 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2568 CHECK_WINUSBX_AVAILABLE(sub_api);
2570 // WinUSB requires a seperate handle for each interface
2571 for (i = 0; i < USB_MAXINTERFACES; i++) {
2572 if ( (priv->usb_interface[i].path != NULL)
2573 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2574 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2575 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2576 if (file_handle == INVALID_HANDLE_VALUE) {
2577 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2578 switch(GetLastError()) {
2579 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2580 return LIBUSB_ERROR_NO_DEVICE;
2581 case ERROR_ACCESS_DENIED:
2582 return LIBUSB_ERROR_ACCESS;
2584 return LIBUSB_ERROR_IO;
2587 handle_priv->interface_handle[i].dev_handle = file_handle;
2591 return LIBUSB_SUCCESS;
2594 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2596 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2597 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2601 if (sub_api == SUB_API_NOTSET)
2602 sub_api = priv->sub_api;
2603 if (!WinUSBX[sub_api].initialized)
2606 for (i = 0; i < USB_MAXINTERFACES; i++) {
2607 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2608 file_handle = handle_priv->interface_handle[i].dev_handle;
2609 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2610 CloseHandle(file_handle);
2616 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
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 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2623 uint8_t endpoint_address;
2626 CHECK_WINUSBX_AVAILABLE(sub_api);
2628 // With handle and enpoints set (in parent), we can setup the default pipe properties
2629 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2630 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2631 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2632 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2633 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2634 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2636 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2637 continue; // Other policies don't apply to control endpoint or libusb0
2640 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2641 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2642 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2644 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2645 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2646 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2649 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2650 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2651 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2652 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2653 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2655 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2656 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2657 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2661 return LIBUSB_SUCCESS;
2664 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2666 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2667 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2668 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2669 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2670 HANDLE file_handle, winusb_handle;
2673 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2675 SP_DEVINFO_DATA dev_info_data;
2676 char* dev_path_no_guid = NULL;
2677 char filter_path[] = "\\\\.\\libusb0-0000";
2678 bool found_filter = false;
2680 CHECK_WINUSBX_AVAILABLE(sub_api);
2682 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2683 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2684 if ((is_using_usbccgp) || (iface == 0)) {
2685 // composite device (independent interfaces) or interface 0
2686 file_handle = handle_priv->interface_handle[iface].dev_handle;
2687 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2688 return LIBUSB_ERROR_NOT_FOUND;
2691 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2692 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2693 err = GetLastError();
2695 case ERROR_BAD_COMMAND:
2696 // The device was disconnected
2697 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2698 return LIBUSB_ERROR_NO_DEVICE;
2700 // it may be that we're using the libusb0 filter driver.
2701 // TODO: can we move this whole business into the K/0 DLL?
2702 for (i = 0; ; i++) {
2703 safe_free(dev_interface_details);
2704 safe_free(dev_path_no_guid);
2705 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2706 if ((found_filter) || (dev_interface_details == NULL)) {
2710 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2711 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2712 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2713 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2714 if (file_handle == INVALID_HANDLE_VALUE) {
2715 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2717 WinUSBX[sub_api].Free(winusb_handle);
2718 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2721 found_filter = true;
2726 if (!found_filter) {
2727 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2728 return LIBUSB_ERROR_ACCESS;
2732 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2734 // For all other interfaces, use GetAssociatedInterface()
2735 winusb_handle = handle_priv->interface_handle[0].api_handle;
2736 // It is a requirement for multiple interface devices on Windows that, to you
2737 // must first claim the first interface before you claim the others
2738 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2739 file_handle = handle_priv->interface_handle[0].dev_handle;
2740 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2741 handle_priv->interface_handle[0].api_handle = winusb_handle;
2742 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2744 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2745 return LIBUSB_ERROR_ACCESS;
2748 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2749 &handle_priv->interface_handle[iface].api_handle)) {
2750 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2751 switch(GetLastError()) {
2752 case ERROR_NO_MORE_ITEMS: // invalid iface
2753 return LIBUSB_ERROR_NOT_FOUND;
2754 case ERROR_BAD_COMMAND: // The device was disconnected
2755 return LIBUSB_ERROR_NO_DEVICE;
2756 case ERROR_ALREADY_EXISTS: // already claimed
2757 return LIBUSB_ERROR_BUSY;
2759 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2760 return LIBUSB_ERROR_ACCESS;
2764 usbi_dbg("claimed interface %d", iface);
2765 handle_priv->active_interface = iface;
2767 return LIBUSB_SUCCESS;
2770 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2772 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2773 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2774 HANDLE winusb_handle;
2776 CHECK_WINUSBX_AVAILABLE(sub_api);
2778 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2779 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2780 return LIBUSB_ERROR_NOT_FOUND;
2783 WinUSBX[sub_api].Free(winusb_handle);
2784 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2786 return LIBUSB_SUCCESS;
2790 * Return the first valid interface (of the same API type), for control transfers
2792 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2794 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2795 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2798 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2799 usbi_dbg("unsupported API ID");
2803 for (i=0; i<USB_MAXINTERFACES; i++) {
2804 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2805 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2806 && (handle_priv->interface_handle[i].api_handle != 0)
2807 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2808 && (priv->usb_interface[i].apib->id == api_id) ) {
2816 * Lookup interface by endpoint address. -1 if not found
2818 static int interface_by_endpoint(struct windows_device_priv *priv,
2819 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2822 for (i=0; i<USB_MAXINTERFACES; i++) {
2823 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2825 if (handle_priv->interface_handle[i].api_handle == 0)
2827 if (priv->usb_interface[i].endpoint == NULL)
2829 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2830 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2838 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2840 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2841 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2842 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2843 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2844 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2845 transfer->dev_handle);
2846 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2848 HANDLE winusb_handle;
2849 int current_interface;
2852 CHECK_WINUSBX_AVAILABLE(sub_api);
2854 transfer_priv->pollable_fd = INVALID_WINFD;
2855 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2857 if (size > MAX_CTRL_BUFFER_LENGTH)
2858 return LIBUSB_ERROR_INVALID_PARAM;
2860 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2861 if (current_interface < 0) {
2862 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2863 return LIBUSB_ERROR_NOT_FOUND;
2867 usbi_dbg("will use interface %d", current_interface);
2868 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2870 wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
2871 // Always use the handle returned from usbi_create_fd (wfd.handle)
2873 return LIBUSB_ERROR_NO_MEM;
2876 // Sending of set configuration control requests from WinUSB creates issues
2877 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2878 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2879 if (setup->value != priv->active_config) {
2880 usbi_warn(ctx, "cannot set configuration other than the default one");
2881 usbi_free_fd(wfd.fd);
2882 return LIBUSB_ERROR_INVALID_PARAM;
2884 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2885 wfd.overlapped->InternalHigh = 0;
2887 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2888 if(GetLastError() != ERROR_IO_PENDING) {
2889 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2890 usbi_free_fd(wfd.fd);
2891 return LIBUSB_ERROR_IO;
2894 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2895 wfd.overlapped->InternalHigh = (DWORD)size;
2899 // Use priv_transfer to store data needed for async polling
2900 transfer_priv->pollable_fd = wfd;
2901 transfer_priv->interface_number = (uint8_t)current_interface;
2903 return LIBUSB_SUCCESS;
2906 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2908 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2909 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2910 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2911 HANDLE winusb_handle;
2913 CHECK_WINUSBX_AVAILABLE(sub_api);
2915 if (altsetting > 255) {
2916 return LIBUSB_ERROR_INVALID_PARAM;
2919 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2920 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2921 usbi_err(ctx, "interface must be claimed first");
2922 return LIBUSB_ERROR_NOT_FOUND;
2925 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2926 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2927 return LIBUSB_ERROR_IO;
2930 return LIBUSB_SUCCESS;
2933 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2935 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2936 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2937 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2938 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2939 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2940 HANDLE winusb_handle;
2942 int current_interface;
2945 CHECK_WINUSBX_AVAILABLE(sub_api);
2947 transfer_priv->pollable_fd = INVALID_WINFD;
2949 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2950 if (current_interface < 0) {
2951 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2952 return LIBUSB_ERROR_NOT_FOUND;
2955 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2957 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2959 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
2960 // Always use the handle returned from usbi_create_fd (wfd.handle)
2962 return LIBUSB_ERROR_NO_MEM;
2965 if (IS_XFERIN(transfer)) {
2966 usbi_dbg("reading %d bytes", transfer->length);
2967 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2969 usbi_dbg("writing %d bytes", transfer->length);
2970 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2973 if(GetLastError() != ERROR_IO_PENDING) {
2974 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2975 usbi_free_fd(wfd.fd);
2976 return LIBUSB_ERROR_IO;
2979 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2980 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
2983 transfer_priv->pollable_fd = wfd;
2984 transfer_priv->interface_number = (uint8_t)current_interface;
2986 return LIBUSB_SUCCESS;
2989 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
2991 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2992 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2993 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2994 HANDLE winusb_handle;
2995 int current_interface;
2997 CHECK_WINUSBX_AVAILABLE(sub_api);
2999 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3000 if (current_interface < 0) {
3001 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3002 return LIBUSB_ERROR_NOT_FOUND;
3005 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3006 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3008 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3009 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3010 return LIBUSB_ERROR_NO_DEVICE;
3013 return LIBUSB_SUCCESS;
3017 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3018 * through testing as well):
3019 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3020 * the control transfer using CancelIo"
3022 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3024 // Cancelling of the I/O is done in the parent
3025 return LIBUSB_SUCCESS;
3028 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3030 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3031 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3032 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3033 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3034 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3035 HANDLE winusb_handle;
3036 int current_interface;
3038 CHECK_WINUSBX_AVAILABLE(sub_api);
3040 current_interface = transfer_priv->interface_number;
3041 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3042 usbi_err(ctx, "program assertion failed: invalid interface_number");
3043 return LIBUSB_ERROR_NOT_FOUND;
3045 usbi_dbg("will use interface %d", current_interface);
3047 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3049 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3050 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3051 return LIBUSB_ERROR_NO_DEVICE;
3054 return LIBUSB_SUCCESS;
3058 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3059 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3060 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3061 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3062 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3063 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3065 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3066 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3068 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3069 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3070 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3072 HANDLE winusb_handle;
3075 CHECK_WINUSBX_AVAILABLE(sub_api);
3077 // Reset any available pipe (except control)
3078 for (i=0; i<USB_MAXINTERFACES; i++) {
3079 winusb_handle = handle_priv->interface_handle[i].api_handle;
3080 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3082 // Cancel any pollable I/O
3083 usbi_remove_pollfd(ctx, wfd.fd);
3084 usbi_free_fd(wfd.fd);
3085 wfd = handle_to_winfd(winusb_handle);
3088 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3089 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3090 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3091 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3092 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3093 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3095 // FlushPipe seems to fail on OUT pipes
3096 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3097 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3098 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3099 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3101 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3102 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3103 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3109 // libusbK & libusb0 have the ability to issue an actual device reset
3110 if (WinUSBX[sub_api].ResetDevice != NULL) {
3111 winusb_handle = handle_priv->interface_handle[0].api_handle;
3112 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3113 WinUSBX[sub_api].ResetDevice(winusb_handle);
3116 return LIBUSB_SUCCESS;
3119 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3121 itransfer->transferred += io_size;
3122 return LIBUSB_TRANSFER_COMPLETED;
3126 * Internal HID Support functions (from libusb-win32)
3127 * Note that functions that complete data transfer synchronously must return
3128 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3130 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3131 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3133 static int _hid_wcslen(WCHAR *str)
3136 while (str[i] && (str[i] != 0x409)) {
3142 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3144 struct libusb_device_descriptor d;
3146 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3147 d.bDescriptorType = LIBUSB_DT_DEVICE;
3148 d.bcdUSB = 0x0200; /* 2.00 */
3150 d.bDeviceSubClass = 0;
3151 d.bDeviceProtocol = 0;
3152 d.bMaxPacketSize0 = 64; /* fix this! */
3153 d.idVendor = (uint16_t)dev->vid;
3154 d.idProduct = (uint16_t)dev->pid;
3155 d.bcdDevice = 0x0100;
3156 d.iManufacturer = dev->string_index[0];
3157 d.iProduct = dev->string_index[1];
3158 d.iSerialNumber = dev->string_index[2];
3159 d.bNumConfigurations = 1;
3161 if (*size > LIBUSB_DT_DEVICE_SIZE)
3162 *size = LIBUSB_DT_DEVICE_SIZE;
3163 memcpy(data, &d, *size);
3164 return LIBUSB_COMPLETED;
3167 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3169 char num_endpoints = 0;
3170 size_t config_total_len = 0;
3171 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3172 struct libusb_config_descriptor *cd;
3173 struct libusb_interface_descriptor *id;
3174 struct libusb_hid_descriptor *hd;
3175 struct libusb_endpoint_descriptor *ed;
3178 if (dev->input_report_size)
3180 if (dev->output_report_size)
3183 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3184 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3187 cd = (struct libusb_config_descriptor *)tmp;
3188 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3189 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3190 + LIBUSB_DT_INTERFACE_SIZE);
3191 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3192 + LIBUSB_DT_INTERFACE_SIZE
3193 + LIBUSB_DT_HID_SIZE);
3195 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3196 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3197 cd->wTotalLength = (uint16_t) config_total_len;
3198 cd->bNumInterfaces = 1;
3199 cd->bConfigurationValue = 1;
3200 cd->iConfiguration = 0;
3201 cd->bmAttributes = 1 << 7; /* bus powered */
3204 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3205 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3206 id->bInterfaceNumber = 0;
3207 id->bAlternateSetting = 0;
3208 id->bNumEndpoints = num_endpoints;
3209 id->bInterfaceClass = 3;
3210 id->bInterfaceSubClass = 0;
3211 id->bInterfaceProtocol = 0;
3214 tmp_size = LIBUSB_DT_HID_SIZE;
3215 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3217 if (dev->input_report_size) {
3218 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3219 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3220 ed->bEndpointAddress = HID_IN_EP;
3221 ed->bmAttributes = 3;
3222 ed->wMaxPacketSize = dev->input_report_size - 1;
3228 if (dev->output_report_size) {
3229 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3230 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3231 ed->bEndpointAddress = HID_OUT_EP;
3232 ed->bmAttributes = 3;
3233 ed->wMaxPacketSize = dev->output_report_size - 1;
3237 if (*size > config_total_len)
3238 *size = config_total_len;
3239 memcpy(data, tmp, *size);
3240 return LIBUSB_COMPLETED;
3243 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3244 void *data, size_t *size)
3247 size_t tmp_size = 0;
3250 /* language ID, EN-US */
3251 char string_langid[] = {
3256 if ((*size < 2) || (*size > 255)) {
3257 return LIBUSB_ERROR_OVERFLOW;
3261 tmp = string_langid;
3262 tmp_size = sizeof(string_langid)+2;
3264 for (i=0; i<3; i++) {
3265 if (_index == (dev->string_index[i])) {
3266 tmp = dev->string[i];
3267 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3271 if (i == 3) { // not found
3272 return LIBUSB_ERROR_INVALID_PARAM;
3277 return LIBUSB_ERROR_INVALID_PARAM;
3280 if (tmp_size < *size) {
3284 ((uint8_t*)data)[0] = (uint8_t)*size;
3285 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3286 memcpy((uint8_t*)data+2, tmp, *size-2);
3287 return LIBUSB_COMPLETED;
3290 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3292 struct libusb_hid_descriptor d;
3293 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3294 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3296 _hid_get_report_descriptor(dev, tmp, &report_len);
3298 d.bLength = LIBUSB_DT_HID_SIZE;
3299 d.bDescriptorType = LIBUSB_DT_HID;
3300 d.bcdHID = 0x0110; /* 1.10 */
3302 d.bNumDescriptors = 1;
3303 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3304 d.wClassDescriptorLength = (uint16_t)report_len;
3306 if (*size > LIBUSB_DT_HID_SIZE)
3307 *size = LIBUSB_DT_HID_SIZE;
3308 memcpy(data, &d, *size);
3309 return LIBUSB_COMPLETED;
3312 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3314 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3317 /* usage page (0xFFA0 == vendor defined) */
3318 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3319 /* usage (vendor defined) */
3320 d[i++] = 0x09; d[i++] = 0x01;
3321 /* start collection (application) */
3322 d[i++] = 0xA1; d[i++] = 0x01;
3324 if (dev->input_report_size) {
3325 /* usage (vendor defined) */
3326 d[i++] = 0x09; d[i++] = 0x01;
3327 /* logical minimum (0) */
3328 d[i++] = 0x15; d[i++] = 0x00;
3329 /* logical maximum (255) */
3330 d[i++] = 0x25; d[i++] = 0xFF;
3331 /* report size (8 bits) */
3332 d[i++] = 0x75; d[i++] = 0x08;
3334 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3335 /* input (data, variable, absolute) */
3336 d[i++] = 0x81; d[i++] = 0x00;
3339 if (dev->output_report_size) {
3340 /* usage (vendor defined) */
3341 d[i++] = 0x09; d[i++] = 0x02;
3342 /* logical minimum (0) */
3343 d[i++] = 0x15; d[i++] = 0x00;
3344 /* logical maximum (255) */
3345 d[i++] = 0x25; d[i++] = 0xFF;
3346 /* report size (8 bits) */
3347 d[i++] = 0x75; d[i++] = 0x08;
3349 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3350 /* output (data, variable, absolute) */
3351 d[i++] = 0x91; d[i++] = 0x00;
3353 /* feature report */
3354 if (dev->feature_report_size) {
3355 /* usage (vendor defined) */
3356 d[i++] = 0x09; d[i++] = 0x03;
3357 /* logical minimum (0) */
3358 d[i++] = 0x15; d[i++] = 0x00;
3359 /* logical maximum (255) */
3360 d[i++] = 0x25; d[i++] = 0xFF;
3361 /* report size (8 bits) */
3362 d[i++] = 0x75; d[i++] = 0x08;
3364 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3365 /* feature (data, variable, absolute) */
3366 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3369 /* end collection */
3374 memcpy(data, d, *size);
3375 return LIBUSB_COMPLETED;
3378 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3379 int type, int _index, void *data, size_t *size)
3382 case LIBUSB_DT_DEVICE:
3383 usbi_dbg("LIBUSB_DT_DEVICE");
3384 return _hid_get_device_descriptor(dev, data, size);
3385 case LIBUSB_DT_CONFIG:
3386 usbi_dbg("LIBUSB_DT_CONFIG");
3388 return _hid_get_config_descriptor(dev, data, size);
3389 return LIBUSB_ERROR_INVALID_PARAM;
3390 case LIBUSB_DT_STRING:
3391 usbi_dbg("LIBUSB_DT_STRING");
3392 return _hid_get_string_descriptor(dev, _index, data, size);
3394 usbi_dbg("LIBUSB_DT_HID");
3396 return _hid_get_hid_descriptor(dev, data, size);
3397 return LIBUSB_ERROR_INVALID_PARAM;
3398 case LIBUSB_DT_REPORT:
3399 usbi_dbg("LIBUSB_DT_REPORT");
3401 return _hid_get_report_descriptor(dev, data, size);
3402 return LIBUSB_ERROR_INVALID_PARAM;
3403 case LIBUSB_DT_PHYSICAL:
3404 usbi_dbg("LIBUSB_DT_PHYSICAL");
3405 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3406 return LIBUSB_COMPLETED;
3407 return LIBUSB_ERROR_OTHER;
3409 usbi_dbg("unsupported");
3410 return LIBUSB_ERROR_INVALID_PARAM;
3413 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3414 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3418 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3419 int r = LIBUSB_SUCCESS;
3421 if (tp->hid_buffer != NULL) {
3422 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3425 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3426 usbi_dbg("invalid size (%d)", *size);
3427 return LIBUSB_ERROR_INVALID_PARAM;
3430 switch (report_type) {
3431 case HID_REPORT_TYPE_INPUT:
3432 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3434 case HID_REPORT_TYPE_FEATURE:
3435 ioctl_code = IOCTL_HID_GET_FEATURE;
3438 usbi_dbg("unknown HID report type %d", report_type);
3439 return LIBUSB_ERROR_INVALID_PARAM;
3442 // Add a trailing byte to detect overflows
3443 buf = (uint8_t*)calloc(expected_size+1, 1);
3445 return LIBUSB_ERROR_NO_MEM;
3447 buf[0] = (uint8_t)id; // Must be set always
3448 usbi_dbg("report ID: 0x%02X", buf[0]);
3450 tp->hid_expected_size = expected_size;
3451 read_size = expected_size;
3453 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3454 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3455 buf, expected_size+1, &read_size, overlapped)) {
3456 if (GetLastError() != ERROR_IO_PENDING) {
3457 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3459 return LIBUSB_ERROR_IO;
3461 // Asynchronous wait
3462 tp->hid_buffer = buf;
3463 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3464 return LIBUSB_SUCCESS;
3467 // Transfer completed synchronously => copy and discard extra buffer
3468 if (read_size == 0) {
3469 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3473 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3475 if ((size_t)read_size > expected_size) {
3476 r = LIBUSB_ERROR_OVERFLOW;
3477 usbi_dbg("OVERFLOW!");
3479 r = LIBUSB_COMPLETED;
3482 *size = MIN((size_t)read_size, *size);
3484 // Discard report ID
3485 memcpy(data, buf+1, *size);
3487 memcpy(data, buf, *size);
3494 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3495 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3498 uint8_t *buf = NULL;
3499 DWORD ioctl_code, write_size= (DWORD)*size;
3501 if (tp->hid_buffer != NULL) {
3502 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3505 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3506 usbi_dbg("invalid size (%d)", *size);
3507 return LIBUSB_ERROR_INVALID_PARAM;
3510 switch (report_type) {
3511 case HID_REPORT_TYPE_OUTPUT:
3512 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3514 case HID_REPORT_TYPE_FEATURE:
3515 ioctl_code = IOCTL_HID_SET_FEATURE;
3518 usbi_dbg("unknown HID report type %d", report_type);
3519 return LIBUSB_ERROR_INVALID_PARAM;
3522 usbi_dbg("report ID: 0x%02X", id);
3523 // When report IDs are not used (i.e. when id == 0), we must add
3524 // a null report ID. Otherwise, we just use original data buffer
3528 buf = (uint8_t*) malloc(write_size);
3530 return LIBUSB_ERROR_NO_MEM;
3534 memcpy(buf + 1, data, *size);
3536 // This seems like a waste, but if we don't duplicate the
3537 // data, we'll get issues when freeing hid_buffer
3538 memcpy(buf, data, *size);
3540 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3544 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3545 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3546 buf, write_size, &write_size, overlapped)) {
3547 if (GetLastError() != ERROR_IO_PENDING) {
3548 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3550 return LIBUSB_ERROR_IO;
3552 tp->hid_buffer = buf;
3553 tp->hid_dest = NULL;
3554 return LIBUSB_SUCCESS;
3557 // Transfer completed synchronously
3559 if (write_size == 0) {
3560 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3563 return LIBUSB_COMPLETED;
3566 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3567 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3568 size_t *size, OVERLAPPED* overlapped)
3570 int report_type = (value >> 8) & 0xFF;
3571 int report_id = value & 0xFF;
3573 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3574 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3575 return LIBUSB_ERROR_INVALID_PARAM;
3577 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3578 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3580 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3581 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3583 return LIBUSB_ERROR_INVALID_PARAM;
3590 static int hid_init(int sub_api, struct libusb_context *ctx)
3592 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3593 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3594 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3595 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3596 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3597 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3598 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3599 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3600 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3601 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3602 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3603 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3604 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3605 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3606 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3607 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3609 api_hid_available = true;
3610 return LIBUSB_SUCCESS;
3613 static int hid_exit(int sub_api)
3615 return LIBUSB_SUCCESS;
3618 // NB: open and close must ensure that they only handle interface of
3619 // the right API type, as these functions can be called wholesale from
3620 // composite_open(), with interfaces belonging to different APIs
3621 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3623 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3624 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3625 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3627 HIDD_ATTRIBUTES hid_attributes;
3628 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3629 HIDP_CAPS capabilities;
3630 HIDP_VALUE_CAPS *value_caps;
3632 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3634 // report IDs handling
3636 char* type[3] = {"input", "output", "feature"};
3637 int nb_ids[2]; // zero and nonzero report IDs
3639 CHECK_HID_AVAILABLE;
3640 if (priv->hid == NULL) {
3641 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3642 return LIBUSB_ERROR_NOT_FOUND;
3645 for (i = 0; i < USB_MAXINTERFACES; i++) {
3646 if ( (priv->usb_interface[i].path != NULL)
3647 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3648 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3649 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3651 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3652 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3653 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3654 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3655 * HidD_GetFeature (if the device supports Feature reports)."
3657 if (hid_handle == INVALID_HANDLE_VALUE) {
3658 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3659 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3660 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3661 if (hid_handle == INVALID_HANDLE_VALUE) {
3662 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3663 switch(GetLastError()) {
3664 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3665 return LIBUSB_ERROR_NO_DEVICE;
3666 case ERROR_ACCESS_DENIED:
3667 return LIBUSB_ERROR_ACCESS;
3669 return LIBUSB_ERROR_IO;
3672 priv->usb_interface[i].restricted_functionality = true;
3674 handle_priv->interface_handle[i].api_handle = hid_handle;
3678 hid_attributes.Size = sizeof(hid_attributes);
3680 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3681 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3685 priv->hid->vid = hid_attributes.VendorID;
3686 priv->hid->pid = hid_attributes.ProductID;
3688 // Set the maximum available input buffer size
3689 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3690 usbi_dbg("set maximum input buffer size to %d", i/2);
3692 // Get the maximum input and output report size
3693 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3694 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3697 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3698 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3702 // Find out if interrupt will need report IDs
3703 size[0] = capabilities.NumberInputValueCaps;
3704 size[1] = capabilities.NumberOutputValueCaps;
3705 size[2] = capabilities.NumberFeatureValueCaps;
3706 for (j=HidP_Input; j<=HidP_Feature; j++) {
3707 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3708 priv->hid->uses_report_ids[j] = false;
3710 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3711 if ( (value_caps != NULL)
3712 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3713 && (size[j] >= 1) ) {
3716 for (i=0; i<(int)size[j]; i++) {
3717 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3718 if (value_caps[i].ReportID != 0) {
3724 if (nb_ids[1] != 0) {
3725 if (nb_ids[0] != 0) {
3726 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3729 priv->hid->uses_report_ids[j] = true;
3732 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3734 safe_free(value_caps);
3738 // Set the report sizes
3739 priv->hid->input_report_size = capabilities.InputReportByteLength;
3740 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3741 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3743 // Fetch string descriptors
3744 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3745 if (priv->hid->string_index[0] != 0) {
3746 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3747 sizeof(priv->hid->string[0]));
3749 priv->hid->string[0][0] = 0;
3751 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3752 if (priv->hid->string_index[1] != 0) {
3753 HidD_GetProductString(hid_handle, priv->hid->string[1],
3754 sizeof(priv->hid->string[1]));
3756 priv->hid->string[1][0] = 0;
3758 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3759 if (priv->hid->string_index[2] != 0) {
3760 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3761 sizeof(priv->hid->string[2]));
3763 priv->hid->string[2][0] = 0;
3767 if (preparsed_data) {
3768 HidD_FreePreparsedData(preparsed_data);
3771 return LIBUSB_SUCCESS;
3774 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3776 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3777 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3781 if (!api_hid_available)
3784 for (i = 0; i < USB_MAXINTERFACES; i++) {
3785 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3786 file_handle = handle_priv->interface_handle[i].api_handle;
3787 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3788 CloseHandle(file_handle);
3794 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3796 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3797 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3799 CHECK_HID_AVAILABLE;
3801 // NB: Disconnection detection is not possible in this function
3802 if (priv->usb_interface[iface].path == NULL) {
3803 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3806 // We use dev_handle as a flag for interface claimed
3807 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3808 return LIBUSB_ERROR_BUSY; // already claimed
3811 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3813 usbi_dbg("claimed interface %d", iface);
3814 handle_priv->active_interface = iface;
3816 return LIBUSB_SUCCESS;
3819 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3821 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3822 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3824 CHECK_HID_AVAILABLE;
3826 if (priv->usb_interface[iface].path == NULL) {
3827 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3830 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3831 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3834 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3836 return LIBUSB_SUCCESS;
3839 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3841 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3843 CHECK_HID_AVAILABLE;
3845 if (altsetting > 255) {
3846 return LIBUSB_ERROR_INVALID_PARAM;
3849 if (altsetting != 0) {
3850 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3851 return LIBUSB_ERROR_NOT_SUPPORTED;
3854 return LIBUSB_SUCCESS;
3857 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3859 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3860 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3861 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3862 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3863 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3864 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3867 int current_interface, config;
3869 int r = LIBUSB_ERROR_INVALID_PARAM;
3871 CHECK_HID_AVAILABLE;
3873 transfer_priv->pollable_fd = INVALID_WINFD;
3874 safe_free(transfer_priv->hid_buffer);
3875 transfer_priv->hid_dest = NULL;
3876 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3878 if (size > MAX_CTRL_BUFFER_LENGTH) {
3879 return LIBUSB_ERROR_INVALID_PARAM;
3882 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3883 if (current_interface < 0) {
3884 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3885 return LIBUSB_ERROR_NOT_FOUND;
3889 usbi_dbg("will use interface %d", current_interface);
3890 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3891 // Always use the handle returned from usbi_create_fd (wfd.handle)
3892 wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
3894 return LIBUSB_ERROR_NOT_FOUND;
3897 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3898 case LIBUSB_REQUEST_TYPE_STANDARD:
3899 switch(setup->request) {
3900 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3901 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3902 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3904 case LIBUSB_REQUEST_GET_CONFIGURATION:
3905 r = windows_get_configuration(transfer->dev_handle, &config);
3906 if (r == LIBUSB_SUCCESS) {
3908 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3909 r = LIBUSB_COMPLETED;
3912 case LIBUSB_REQUEST_SET_CONFIGURATION:
3913 if (setup->value == priv->active_config) {
3914 r = LIBUSB_COMPLETED;
3916 usbi_warn(ctx, "cannot set configuration other than the default one");
3917 r = LIBUSB_ERROR_INVALID_PARAM;
3920 case LIBUSB_REQUEST_GET_INTERFACE:
3922 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3923 r = LIBUSB_COMPLETED;
3925 case LIBUSB_REQUEST_SET_INTERFACE:
3926 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3927 if (r == LIBUSB_SUCCESS) {
3928 r = LIBUSB_COMPLETED;
3932 usbi_warn(ctx, "unsupported HID control request");
3933 r = LIBUSB_ERROR_INVALID_PARAM;
3937 case LIBUSB_REQUEST_TYPE_CLASS:
3938 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3939 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3940 &size, wfd.overlapped);
3943 usbi_warn(ctx, "unsupported HID control request");
3944 r = LIBUSB_ERROR_INVALID_PARAM;
3948 if (r == LIBUSB_COMPLETED) {
3949 // Force request to be completed synchronously. Transferred size has been set by previous call
3950 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3951 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3952 // set InternalHigh to the number of bytes transferred
3953 wfd.overlapped->InternalHigh = (DWORD)size;
3957 if (r == LIBUSB_SUCCESS) {
3958 // Use priv_transfer to store data needed for async polling
3959 transfer_priv->pollable_fd = wfd;
3960 transfer_priv->interface_number = (uint8_t)current_interface;
3962 usbi_free_fd(wfd.fd);
3968 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3969 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3970 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3971 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3972 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3973 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3976 bool direction_in, ret;
3977 int current_interface, length;
3979 int r = LIBUSB_SUCCESS;
3981 CHECK_HID_AVAILABLE;
3983 transfer_priv->pollable_fd = INVALID_WINFD;
3984 transfer_priv->hid_dest = NULL;
3985 safe_free(transfer_priv->hid_buffer);
3987 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3988 if (current_interface < 0) {
3989 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3990 return LIBUSB_ERROR_NOT_FOUND;
3993 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3995 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3996 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
3998 wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
3999 // Always use the handle returned from usbi_create_fd (wfd.handle)
4001 return LIBUSB_ERROR_NO_MEM;
4004 // If report IDs are not in use, an extra prefix byte must be added
4005 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4006 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4007 length = transfer->length+1;
4009 length = transfer->length;
4011 // Add a trailing byte to detect overflows on input
4012 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4013 if (transfer_priv->hid_buffer == NULL) {
4014 return LIBUSB_ERROR_NO_MEM;
4016 transfer_priv->hid_expected_size = length;
4019 transfer_priv->hid_dest = transfer->buffer;
4020 usbi_dbg("reading %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4021 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4023 if (!priv->hid->uses_report_ids[1]) {
4024 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4026 // We could actually do without the calloc and memcpy in this case
4027 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4029 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4030 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4033 if (GetLastError() != ERROR_IO_PENDING) {
4034 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4035 usbi_free_fd(wfd.fd);
4036 safe_free(transfer_priv->hid_buffer);
4037 return LIBUSB_ERROR_IO;
4040 // Only write operations that completed synchronously need to free up
4041 // hid_buffer. For reads, copy_transfer_data() handles that process.
4042 if (!direction_in) {
4043 safe_free(transfer_priv->hid_buffer);
4046 usbi_err(ctx, "program assertion failed - no data was transferred");
4049 if (size > (size_t)length) {
4050 usbi_err(ctx, "OVERFLOW!");
4051 r = LIBUSB_ERROR_OVERFLOW;
4053 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4054 wfd.overlapped->InternalHigh = size;
4057 transfer_priv->pollable_fd = wfd;
4058 transfer_priv->interface_number = (uint8_t)current_interface;
4063 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4065 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4066 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4067 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4069 int current_interface;
4071 CHECK_HID_AVAILABLE;
4073 current_interface = transfer_priv->interface_number;
4074 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4075 CancelIo(hid_handle);
4077 return LIBUSB_SUCCESS;
4080 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4082 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4084 int current_interface;
4086 CHECK_HID_AVAILABLE;
4088 // Flushing the queues on all interfaces is the best we can achieve
4089 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4090 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4091 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4092 HidD_FlushQueue(hid_handle);
4095 return LIBUSB_SUCCESS;
4098 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4100 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4101 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4102 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4104 int current_interface;
4106 CHECK_HID_AVAILABLE;
4108 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4109 if (current_interface < 0) {
4110 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4111 return LIBUSB_ERROR_NOT_FOUND;
4114 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4115 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4117 // No endpoint selection with Microsoft's implementation, so we try to flush the
4118 // whole interface. Should be OK for most case scenarios
4119 if (!HidD_FlushQueue(hid_handle)) {
4120 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4121 // Device was probably disconnected
4122 return LIBUSB_ERROR_NO_DEVICE;
4125 return LIBUSB_SUCCESS;
4128 // This extra function is only needed for HID
4129 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4130 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4131 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4132 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4133 int r = LIBUSB_TRANSFER_COMPLETED;
4134 uint32_t corrected_size = io_size;
4136 if (transfer_priv->hid_buffer != NULL) {
4137 // If we have a valid hid_buffer, it means the transfer was async
4138 if (transfer_priv->hid_dest != NULL) { // Data readout
4139 // First, check for overflow
4140 if (corrected_size > transfer_priv->hid_expected_size) {
4141 usbi_err(ctx, "OVERFLOW!");
4142 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4143 r = LIBUSB_TRANSFER_OVERFLOW;
4146 if (transfer_priv->hid_buffer[0] == 0) {
4147 // Discard the 1 byte report ID prefix
4149 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4151 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4153 transfer_priv->hid_dest = NULL;
4155 // For write, we just need to free the hid buffer
4156 safe_free(transfer_priv->hid_buffer);
4158 itransfer->transferred += corrected_size;
4164 * Composite API functions
4166 static int composite_init(int sub_api, struct libusb_context *ctx)
4168 return LIBUSB_SUCCESS;
4171 static int composite_exit(int sub_api)
4173 return LIBUSB_SUCCESS;
4176 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4178 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4179 int r = LIBUSB_ERROR_NOT_FOUND;
4181 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4182 bool available[SUB_API_MAX+1] = {0};
4184 for (i=0; i<USB_MAXINTERFACES; i++) {
4185 switch (priv->usb_interface[i].apib->id) {
4186 case USB_API_WINUSBX:
4187 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4188 available[priv->usb_interface[i].sub_api] = true;
4191 available[SUB_API_MAX] = true;
4198 for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4200 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4201 if (r != LIBUSB_SUCCESS) {
4206 if (available[SUB_API_MAX]) { // HID driver
4207 r = hid_open(SUB_API_NOTSET, dev_handle);
4212 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4214 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4216 bool available[SUB_API_MAX];
4218 for (i = 0; i<SUB_API_MAX; i++) {
4219 available[i] = false;
4222 for (i=0; i<USB_MAXINTERFACES; i++) {
4223 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4224 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4225 available[priv->usb_interface[i].sub_api] = true;
4229 for (i=0; i<SUB_API_MAX; i++) {
4231 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4236 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4238 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4239 return priv->usb_interface[iface].apib->
4240 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4243 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4245 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4246 return priv->usb_interface[iface].apib->
4247 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4250 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4252 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4253 return priv->usb_interface[iface].apib->
4254 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4257 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4259 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4260 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4261 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4264 // Interface shouldn't matter for control, but it does in practice, with Windows'
4265 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4266 for (pass = 0; pass < 2; pass++) {
4267 for (i=0; i<USB_MAXINTERFACES; i++) {
4268 if (priv->usb_interface[i].path != NULL) {
4269 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4270 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4273 usbi_dbg("using interface %d", i);
4274 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4279 usbi_err(ctx, "no libusbx supported interfaces to complete request");
4280 return LIBUSB_ERROR_NOT_FOUND;
4283 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4284 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4285 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4286 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4287 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4288 int current_interface;
4290 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4291 if (current_interface < 0) {
4292 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4293 return LIBUSB_ERROR_NOT_FOUND;
4296 return priv->usb_interface[current_interface].apib->
4297 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4299 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4300 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4301 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4302 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4303 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4304 int current_interface;
4306 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4307 if (current_interface < 0) {
4308 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4309 return LIBUSB_ERROR_NOT_FOUND;
4312 return priv->usb_interface[current_interface].apib->
4313 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4315 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4317 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4318 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4319 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4320 int current_interface;
4322 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4323 if (current_interface < 0) {
4324 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4325 return LIBUSB_ERROR_NOT_FOUND;
4328 return priv->usb_interface[current_interface].apib->
4329 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4331 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4333 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4334 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4335 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4337 return priv->usb_interface[transfer_priv->interface_number].apib->
4338 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4340 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4342 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4343 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4344 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4346 return priv->usb_interface[transfer_priv->interface_number].apib->
4347 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4349 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4351 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4354 bool available[SUB_API_MAX];
4355 for (i = 0; i<SUB_API_MAX; i++) {
4356 available[i] = false;
4358 for (i=0; i<USB_MAXINTERFACES; i++) {
4359 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4360 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4361 available[priv->usb_interface[i].sub_api] = true;
4364 for (i=0; i<SUB_API_MAX; i++) {
4366 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4367 if (r != LIBUSB_SUCCESS) {
4372 return LIBUSB_SUCCESS;
4375 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4377 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4378 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4379 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4381 return priv->usb_interface[transfer_priv->interface_number].apib->
4382 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);