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 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_info(ctx,"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 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 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->api_flags & USB_API_SET)
1242 return LIBUSB_SUCCESS;
1243 if (priv->apib->id != USB_API_COMPOSITE) {
1244 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1245 return LIBUSB_ERROR_NO_DEVICE;
1248 // Because MI_## are not necessarily in sequential order (some composite
1249 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1250 // interface number from the path's MI value
1251 interface_number = 0;
1252 for (i=0; device_id[i] != 0; ) {
1253 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1254 && (device_id[i++] == '_') ) {
1255 interface_number = (device_id[i++] - '0')*10;
1256 interface_number += device_id[i] - '0';
1261 if (device_id[i] == 0) {
1262 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1263 device_id, interface_number);
1266 // HID devices can have multiple collections (COL##) for each MI_## interface
1267 if (priv->usb_interface[interface_number].path != NULL) {
1268 if (api != USB_API_HID) {
1269 usbi_warn(ctx, "program assertion failed %s is not an USB HID collection", device_id);
1270 return LIBUSB_ERROR_OTHER;
1272 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1273 interface_number, device_id);
1274 return LIBUSB_ERROR_ACCESS;
1277 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1278 priv->usb_interface[interface_number].path = dev_interface_path;
1279 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1280 priv->usb_interface[interface_number].sub_api = sub_api;
1281 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1282 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1283 if (priv->hid == NULL)
1284 return LIBUSB_ERROR_NO_MEM;
1286 priv->api_flags |= USB_API_SET | (1<<api);
1288 return LIBUSB_SUCCESS;
1291 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1292 char* dev_interface_path)
1294 struct windows_device_priv *priv = _device_priv(dev);
1296 if (priv->api_flags & USB_API_SET)
1297 return LIBUSB_SUCCESS;
1298 if (priv->hid == NULL) {
1299 usbi_err(ctx, "program assertion failed: parent is not HID");
1300 return LIBUSB_ERROR_NO_DEVICE;
1302 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1303 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1304 return LIBUSB_ERROR_NO_DEVICE;
1306 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1307 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1308 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1309 priv->hid->nb_interfaces++;
1310 priv->api_flags |= USB_API_SET;
1311 return LIBUSB_SUCCESS;
1315 * get_device_list: libusbx backend device enumeration function
1317 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1319 struct discovered_devs *discdevs;
1320 HDEVINFO dev_info = { 0 };
1321 char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1322 SP_DEVINFO_DATA dev_info_data = { 0 };
1323 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1325 #define MAX_ENUM_GUIDS 64
1326 const GUID* guid[MAX_ENUM_GUIDS];
1332 int r = LIBUSB_SUCCESS;
1334 int class_index = 0;
1335 unsigned int nb_guids, pass, i, j, ancestor;
1336 char path[MAX_PATH_LENGTH];
1337 char strbuf[MAX_PATH_LENGTH];
1338 struct libusb_device *dev, *parent_dev;
1339 struct windows_device_priv *priv, *parent_priv;
1340 char* dev_interface_path = NULL;
1341 char* dev_id_path = NULL;
1342 unsigned long session_id;
1343 DWORD size, reg_type, port_nr, install_state;
1345 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1348 // Keep a list of newly allocated devs to unref
1349 libusb_device** unref_list;
1350 unsigned int unref_size = 64;
1351 unsigned int unref_cur = 0;
1353 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1354 // PASS 2 : (re)enumerate HUBS
1355 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1356 // and list additional USB device interface GUIDs to explore
1357 // PASS 4 : (re)enumerate master USB devices that have a device interface
1358 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1359 // set the device interfaces.
1361 // Init the GUID table
1362 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1363 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1364 guid[GEN_PASS] = NULL;
1365 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1366 HidD_GetHidGuid(&hid_guid);
1367 guid[HID_PASS] = &hid_guid;
1368 nb_guids = HID_PASS+1;
1370 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1371 if (unref_list == NULL) {
1372 return LIBUSB_ERROR_NO_MEM;
1375 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1376 //#define ENUM_DEBUG
1380 usbi_dbg("PROCESSING HCDs %s", guid_to_string(guid[pass]));
1383 usbi_dbg("PROCESSING HUBs %s", guid_to_string(guid[pass]));
1386 usbi_dbg("PROCESSING DEVs %s", guid_to_string(guid[pass]));
1389 usbi_dbg("PROCESSING GENs");
1392 usbi_dbg("PROCESSING HIDs %s", guid_to_string(guid[pass]));
1395 usbi_dbg("PROCESSING EXTs %s", guid_to_string(guid[pass]));
1399 for (i = 0; ; i++) {
1400 // safe loop: free up any (unprotected) dynamic resource
1401 // NB: this is always executed before breaking the loop
1402 safe_free(dev_interface_details);
1403 safe_free(dev_interface_path);
1404 safe_free(dev_id_path);
1405 priv = parent_priv = NULL;
1406 dev = parent_dev = NULL;
1408 // Safe loop: end of loop conditions
1409 if (r != LIBUSB_SUCCESS) {
1412 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1413 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1416 if (pass != GEN_PASS) {
1417 // Except for GEN, all passes deal with device interfaces
1418 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1419 if (dev_interface_details == NULL) {
1422 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1423 if (dev_interface_path == NULL) {
1424 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1429 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1430 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1431 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1432 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1433 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1437 if (class_index >= ARRAYSIZE(usb_class))
1441 // Read the Device ID path. This is what we'll use as UID
1442 // Note that if the device is plugged in a different port or hub, the Device ID changes
1443 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1444 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1445 dev_info_data.DevInst);
1448 dev_id_path = sanitize_path(path);
1449 if (dev_id_path == NULL) {
1450 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1451 dev_info_data.DevInst);
1455 usbi_dbg("PRO: %s", dev_id_path);
1458 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1460 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1461 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1462 ®_type, (BYTE*)&port_nr, 4, &size))
1464 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1465 dev_id_path, windows_error_str(0));
1470 // Set API to use or get additional data from generic pass
1471 api = USB_API_UNSUPPORTED;
1472 sub_api = SUB_API_NOTSET;
1477 // We use the GEN pass to detect driverless devices...
1478 size = sizeof(strbuf);
1479 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1480 ®_type, (BYTE*)strbuf, size, &size)) {
1481 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1482 usbi_info(ctx, "libusbx will not be able to access it.");
1484 // ...and to add the additional device interface GUIDs
1485 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1486 if (key != INVALID_HANDLE_VALUE) {
1487 size = sizeof(guid_string_w);
1488 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1489 (BYTE*)guid_string_w, &size);
1491 if (s == ERROR_SUCCESS) {
1492 if (nb_guids >= MAX_ENUM_GUIDS) {
1493 // If this assert is ever reported, grow a GUID table dynamically
1494 usbi_err(ctx, "program assertion failed: too many GUIDs");
1495 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1497 if_guid = (GUID*) calloc(1, sizeof(GUID));
1498 pCLSIDFromString(guid_string_w, if_guid);
1499 guid[nb_guids++] = if_guid;
1500 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1508 // Get the API type (after checking that the driver installation is OK)
1509 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1510 ®_type, (BYTE*)&install_state, 4, &size))
1512 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1513 dev_id_path, windows_error_str(0));
1514 } else if (install_state != 0) {
1515 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1516 dev_id_path, install_state);
1519 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1523 // Find parent device (for the passes that need it)
1530 // Go through the ancestors until we see a face we recognize
1532 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1533 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1534 if (session_id == 0) {
1537 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1539 if (parent_dev == NULL) {
1540 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1543 parent_priv = _device_priv(parent_dev);
1544 // virtual USB devices are also listed during GEN - don't process these yet
1545 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1551 // Create new or match existing device, using the (hashed) device_id as session id
1552 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1553 // These are the passes that create "new" devices
1554 session_id = htab_hash(dev_id_path);
1555 dev = usbi_get_device_by_session_id(ctx, session_id);
1557 if (pass == DEV_PASS) {
1558 // This can occur if the OS only reports a newly plugged device after we started enum
1559 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1560 " - ignoring", dev_id_path);
1563 usbi_dbg("allocating new device for session [%X]", session_id);
1564 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1565 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1567 windows_device_priv_init(dev);
1568 // Keep track of devices that need unref
1569 unref_list[unref_cur++] = dev;
1570 if (unref_cur >= unref_size) {
1572 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1573 if (unref_list == NULL) {
1574 usbi_err(ctx, "could not realloc list for unref - aborting.");
1575 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1579 usbi_dbg("found existing device for session [%X] (%d.%d)",
1580 session_id, dev->bus_number, dev->device_address);
1582 priv = _device_priv(dev);
1588 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1589 dev->device_address = 0;
1590 dev->num_configurations = 0;
1591 priv->apib = &usb_api_backend[USB_API_HUB];
1592 priv->sub_api = SUB_API_NOTSET;
1593 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1594 priv->path = dev_interface_path; dev_interface_path = NULL;
1598 // If the device has already been setup, don't do it again
1599 if (priv->path != NULL)
1601 // Take care of API initialization
1602 priv->path = dev_interface_path; dev_interface_path = NULL;
1603 priv->apib = &usb_api_backend[api];
1604 priv->sub_api = sub_api;
1606 case USB_API_COMPOSITE:
1610 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1611 if (priv->hid == NULL) {
1612 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1614 priv->hid->nb_interfaces = 0;
1617 // For other devices, the first interface is the same as the device
1618 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1619 if (priv->usb_interface[0].path != NULL) {
1620 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1622 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1624 // The following is needed if we want API calls to work for both simple
1625 // and composite devices.
1626 for(j=0; j<USB_MAXINTERFACES; j++) {
1627 priv->usb_interface[j].apib = &usb_api_backend[api];
1633 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1634 if (r == LIBUSB_SUCCESS) {
1635 // Append device to the list of discovered devices
1636 discdevs = discovered_devs_append(*_discdevs, dev);
1638 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1640 *_discdevs = discdevs;
1641 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1642 // This can occur if the device was disconnected but Windows hasn't
1643 // refreshed its enumeration yet - in that case, we ignore the device
1647 default: // HID_PASS and later
1648 if (parent_priv->apib->id == USB_API_HID) {
1649 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1650 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1651 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1652 dev_interface_path = NULL;
1653 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1654 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1655 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, SUB_API_NOTSET)) {
1656 case LIBUSB_SUCCESS:
1657 dev_interface_path = NULL;
1659 case LIBUSB_ERROR_ACCESS:
1660 // interface has already been set => make sure dev_interface_path is freed then
1672 // Free any additional GUIDs
1673 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1674 safe_free(guid[pass]);
1677 // Unref newly allocated devs
1678 for (i=0; i<unref_cur; i++) {
1679 safe_unref_device(unref_list[i]);
1681 safe_free(unref_list);
1687 * exit: libusbx backend deinitialization function
1689 static void windows_exit(void)
1693 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1695 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1696 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1697 if (semaphore == NULL) {
1701 // A successful wait brings our semaphore count to 0 (unsignaled)
1702 // => any concurent wait stalls until the semaphore release
1703 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1704 CloseHandle(semaphore);
1708 // Only works if exits and inits are balanced exactly
1709 if (--concurrent_usage < 0) { // Last exit
1710 for (i=0; i<USB_API_MAX; i++) {
1711 usb_api_backend[i].exit(SUB_API_NOTSET);
1716 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1717 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1718 usbi_dbg("could not wait for timer thread to quit");
1719 TerminateThread(timer_thread, 1);
1721 CloseHandle(timer_thread);
1722 timer_thread = NULL;
1724 for (i = 0; i < 2; i++) {
1725 if (timer_request[i]) {
1726 CloseHandle(timer_request[i]);
1727 timer_request[i] = NULL;
1730 if (timer_response) {
1731 CloseHandle(timer_response);
1732 timer_response = NULL;
1735 CloseHandle(timer_mutex);
1741 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1742 CloseHandle(semaphore);
1745 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1747 struct windows_device_priv *priv = _device_priv(dev);
1749 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1752 return LIBUSB_SUCCESS;
1755 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1757 struct windows_device_priv *priv = _device_priv(dev);
1758 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1761 // config index is zero based
1762 if (config_index >= dev->num_configurations)
1763 return LIBUSB_ERROR_INVALID_PARAM;
1765 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1766 return LIBUSB_ERROR_NOT_FOUND;
1768 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1770 size = min(config_header->wTotalLength, len);
1771 memcpy(buffer, priv->config_descriptor[config_index], size);
1773 return LIBUSB_SUCCESS;
1777 * return the cached copy of the active config descriptor
1779 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1781 struct windows_device_priv *priv = _device_priv(dev);
1783 if (priv->active_config == 0)
1784 return LIBUSB_ERROR_NOT_FOUND;
1786 // config index is zero based
1787 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1790 static int windows_open(struct libusb_device_handle *dev_handle)
1792 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1793 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1795 if (priv->apib == NULL) {
1796 usbi_err(ctx, "program assertion failed - device is not initialized");
1797 return LIBUSB_ERROR_NO_DEVICE;
1800 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1803 static void windows_close(struct libusb_device_handle *dev_handle)
1805 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1807 priv->apib->close(SUB_API_NOTSET, dev_handle);
1810 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1812 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1814 if (priv->active_config == 0) {
1816 return LIBUSB_ERROR_NOT_FOUND;
1819 *config = priv->active_config;
1820 return LIBUSB_SUCCESS;
1824 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1825 * does not currently expose a service that allows higher-level drivers to set
1826 * the configuration."
1828 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1830 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1831 int r = LIBUSB_SUCCESS;
1833 if (config >= USB_MAXCONFIG)
1834 return LIBUSB_ERROR_INVALID_PARAM;
1836 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1837 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1838 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1841 if (r == LIBUSB_SUCCESS) {
1842 priv->active_config = (uint8_t)config;
1847 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1849 int r = LIBUSB_SUCCESS;
1850 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1852 if (iface >= USB_MAXINTERFACES)
1853 return LIBUSB_ERROR_INVALID_PARAM;
1855 safe_free(priv->usb_interface[iface].endpoint);
1856 priv->usb_interface[iface].nb_endpoints= 0;
1858 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1860 if (r == LIBUSB_SUCCESS) {
1861 r = windows_assign_endpoints(dev_handle, iface, 0);
1867 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1869 int r = LIBUSB_SUCCESS;
1870 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1872 safe_free(priv->usb_interface[iface].endpoint);
1873 priv->usb_interface[iface].nb_endpoints= 0;
1875 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1877 if (r == LIBUSB_SUCCESS) {
1878 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1884 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1886 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1888 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1891 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1893 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1894 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1897 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1899 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1900 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1903 // The 3 functions below are unlikely to ever get supported on Windows
1904 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1906 return LIBUSB_ERROR_NOT_SUPPORTED;
1909 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1911 return LIBUSB_ERROR_NOT_SUPPORTED;
1914 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1916 return LIBUSB_ERROR_NOT_SUPPORTED;
1919 static void windows_destroy_device(struct libusb_device *dev)
1921 windows_device_priv_release(dev);
1924 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1926 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1928 usbi_free_fd(transfer_priv->pollable_fd.fd);
1929 safe_free(transfer_priv->hid_buffer);
1930 // When auto claim is in use, attempt to release the auto-claimed interface
1931 auto_release(itransfer);
1934 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1936 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1937 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1938 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1939 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1942 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1943 if (r != LIBUSB_SUCCESS) {
1947 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1948 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1950 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1951 return LIBUSB_SUCCESS;
1954 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1956 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1957 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1958 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1959 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1962 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1963 if (r != LIBUSB_SUCCESS) {
1967 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1968 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1970 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1971 return LIBUSB_SUCCESS;
1974 static int submit_control_transfer(struct usbi_transfer *itransfer)
1976 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1977 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1978 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1979 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1982 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1983 if (r != LIBUSB_SUCCESS) {
1987 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
1989 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1990 return LIBUSB_SUCCESS;
1994 static int windows_submit_transfer(struct usbi_transfer *itransfer)
1996 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1998 switch (transfer->type) {
1999 case LIBUSB_TRANSFER_TYPE_CONTROL:
2000 return submit_control_transfer(itransfer);
2001 case LIBUSB_TRANSFER_TYPE_BULK:
2002 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2003 if (IS_XFEROUT(transfer) &&
2004 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
2005 return LIBUSB_ERROR_NOT_SUPPORTED;
2006 return submit_bulk_transfer(itransfer);
2007 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2008 return submit_iso_transfer(itransfer);
2010 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2011 return LIBUSB_ERROR_INVALID_PARAM;
2015 static int windows_abort_control(struct usbi_transfer *itransfer)
2017 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2018 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2020 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2023 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2025 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2026 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2028 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2031 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2033 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2035 switch (transfer->type) {
2036 case LIBUSB_TRANSFER_TYPE_CONTROL:
2037 return windows_abort_control(itransfer);
2038 case LIBUSB_TRANSFER_TYPE_BULK:
2039 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2040 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2041 return windows_abort_transfers(itransfer);
2043 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2044 return LIBUSB_ERROR_INVALID_PARAM;
2048 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2050 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2051 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2054 usbi_dbg("handling I/O completion with errcode %d", io_result);
2058 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2060 case ERROR_GEN_FAILURE:
2061 usbi_dbg("detected endpoint stall");
2062 status = LIBUSB_TRANSFER_STALL;
2064 case ERROR_SEM_TIMEOUT:
2065 usbi_dbg("detected semaphore timeout");
2066 status = LIBUSB_TRANSFER_TIMED_OUT;
2068 case ERROR_OPERATION_ABORTED:
2069 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2070 usbi_dbg("detected timeout");
2071 status = LIBUSB_TRANSFER_TIMED_OUT;
2073 usbi_dbg("detected operation aborted");
2074 status = LIBUSB_TRANSFER_CANCELLED;
2078 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(0));
2079 status = LIBUSB_TRANSFER_ERROR;
2082 windows_clear_transfer_priv(itransfer); // Cancel polling
2083 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2086 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2088 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2090 switch (transfer->type) {
2091 case LIBUSB_TRANSFER_TYPE_CONTROL:
2092 case LIBUSB_TRANSFER_TYPE_BULK:
2093 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2094 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2095 windows_transfer_callback (itransfer, io_result, io_size);
2098 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2102 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2104 struct windows_transfer_priv* transfer_priv = NULL;
2105 POLL_NFDS_TYPE i = 0;
2107 struct usbi_transfer *transfer;
2108 DWORD io_size, io_result;
2110 usbi_mutex_lock(&ctx->open_devs_lock);
2111 for (i = 0; i < nfds && num_ready > 0; i++) {
2113 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2115 if (!fds[i].revents) {
2121 // Because a Windows OVERLAPPED is used for poll emulation,
2122 // a pollable fd is created and stored with each transfer
2123 usbi_mutex_lock(&ctx->flying_transfers_lock);
2124 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2125 transfer_priv = usbi_transfer_get_os_priv(transfer);
2126 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2131 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2134 // Handle async requests that completed synchronously first
2135 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2136 io_result = NO_ERROR;
2137 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2138 // Regular async overlapped
2139 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2140 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2141 io_result = NO_ERROR;
2143 io_result = GetLastError();
2145 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2146 // let handle_callback free the event using the transfer wfd
2147 // If you don't use the transfer wfd, you run a risk of trying to free a
2148 // newly allocated wfd that took the place of the one from the transfer.
2149 windows_handle_callback(transfer, io_result, io_size);
2151 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2152 return LIBUSB_ERROR_NOT_FOUND;
2156 usbi_mutex_unlock(&ctx->open_devs_lock);
2157 return LIBUSB_SUCCESS;
2161 * Monotonic and real time functions
2163 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2165 LARGE_INTEGER hires_counter, li_frequency;
2169 // Init - find out if we have access to a monotonic (hires) timer
2170 if (!QueryPerformanceFrequency(&li_frequency)) {
2171 usbi_dbg("no hires timer available on this platform");
2172 hires_frequency = 0;
2173 hires_ticks_to_ps = UINT64_C(0);
2175 hires_frequency = li_frequency.QuadPart;
2176 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2177 // to picoseconds to compute the tv_nsecs part in clock_gettime
2178 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2179 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2182 // Main loop - wait for requests
2184 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2185 if ( (timer_index != 0) && (timer_index != 1) ) {
2186 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2189 if (request_count[timer_index] == 0) {
2190 // Request already handled
2191 ResetEvent(timer_request[timer_index]);
2192 // There's still a possiblity that a thread sends a request between the
2193 // time we test request_count[] == 0 and we reset the event, in which case
2194 // the request would be ignored. The simple solution to that is to test
2195 // request_count again and process requests if non zero.
2196 if (request_count[timer_index] == 0)
2199 switch (timer_index) {
2201 WaitForSingleObject(timer_mutex, INFINITE);
2202 // Requests to this thread are for hires always
2203 if (QueryPerformanceCounter(&hires_counter) != 0) {
2204 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2205 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2207 // Fallback to real-time if we can't get monotonic value
2208 // Note that real-time clock does not wait on the mutex or this thread.
2209 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2211 ReleaseMutex(timer_mutex);
2213 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2215 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2216 usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0));
2219 case 1: // time to quit
2220 usbi_dbg("timer thread quitting");
2226 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2229 ULARGE_INTEGER rtime;
2232 case USBI_CLOCK_MONOTONIC:
2233 if (hires_frequency != 0) {
2235 InterlockedIncrement((LONG*)&request_count[0]);
2236 SetEvent(timer_request[0]);
2237 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2240 WaitForSingleObject(timer_mutex, INFINITE);
2242 ReleaseMutex(timer_mutex);
2243 return LIBUSB_SUCCESS;
2245 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2246 break; // Retry until successful
2248 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2249 return LIBUSB_ERROR_OTHER;
2253 // Fall through and return real-time if monotonic was not detected @ timer init
2254 case USBI_CLOCK_REALTIME:
2255 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2256 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2257 // Note however that our resolution is bounded by the Windows system time
2258 // functions and is at best of the order of 1 ms (or, usually, worse)
2259 GetSystemTimeAsFileTime(&filetime);
2260 rtime.LowPart = filetime.dwLowDateTime;
2261 rtime.HighPart = filetime.dwHighDateTime;
2262 rtime.QuadPart -= epoch_time;
2263 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2264 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2265 return LIBUSB_SUCCESS;
2267 return LIBUSB_ERROR_INVALID_PARAM;
2272 // NB: MSVC6 does not support named initializers.
2273 const struct usbi_os_backend windows_backend = {
2278 windows_get_device_list,
2282 windows_get_device_descriptor,
2283 windows_get_active_config_descriptor,
2284 windows_get_config_descriptor,
2286 windows_get_configuration,
2287 windows_set_configuration,
2288 windows_claim_interface,
2289 windows_release_interface,
2291 windows_set_interface_altsetting,
2293 windows_reset_device,
2295 windows_kernel_driver_active,
2296 windows_detach_kernel_driver,
2297 windows_attach_kernel_driver,
2299 windows_destroy_device,
2301 windows_submit_transfer,
2302 windows_cancel_transfer,
2303 windows_clear_transfer_priv,
2305 windows_handle_events,
2307 windows_clock_gettime,
2308 #if defined(USBI_TIMERFD_AVAILABLE)
2311 sizeof(struct windows_device_priv),
2312 sizeof(struct windows_device_handle_priv),
2313 sizeof(struct windows_transfer_priv),
2321 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2322 return LIBUSB_SUCCESS;
2324 static int unsupported_exit(int sub_api) {
2325 return LIBUSB_SUCCESS;
2327 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2328 PRINT_UNSUPPORTED_API(open);
2330 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2331 usbi_dbg("unsupported API call for 'close'");
2333 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2334 PRINT_UNSUPPORTED_API(configure_endpoints);
2336 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2337 PRINT_UNSUPPORTED_API(claim_interface);
2339 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2340 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2342 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2343 PRINT_UNSUPPORTED_API(release_interface);
2345 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2346 PRINT_UNSUPPORTED_API(clear_halt);
2348 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2349 PRINT_UNSUPPORTED_API(reset_device);
2351 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2352 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2354 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2355 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2357 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2358 PRINT_UNSUPPORTED_API(submit_control_transfer);
2360 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2361 PRINT_UNSUPPORTED_API(abort_control);
2363 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2364 PRINT_UNSUPPORTED_API(abort_transfers);
2366 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2367 PRINT_UNSUPPORTED_API(copy_transfer_data);
2369 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2370 return LIBUSB_SUCCESS;
2372 // These names must be uppercase
2373 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2374 const char* composite_driver_names[] = {"USBCCGP"};
2375 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2376 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2377 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2379 USB_API_UNSUPPORTED,
2387 unsupported_configure_endpoints,
2388 unsupported_claim_interface,
2389 unsupported_set_interface_altsetting,
2390 unsupported_release_interface,
2391 unsupported_clear_halt,
2392 unsupported_reset_device,
2393 unsupported_submit_bulk_transfer,
2394 unsupported_submit_iso_transfer,
2395 unsupported_submit_control_transfer,
2396 unsupported_abort_control,
2397 unsupported_abort_transfers,
2398 unsupported_copy_transfer_data,
2403 ARRAYSIZE(hub_driver_names),
2408 unsupported_configure_endpoints,
2409 unsupported_claim_interface,
2410 unsupported_set_interface_altsetting,
2411 unsupported_release_interface,
2412 unsupported_clear_halt,
2413 unsupported_reset_device,
2414 unsupported_submit_bulk_transfer,
2415 unsupported_submit_iso_transfer,
2416 unsupported_submit_control_transfer,
2417 unsupported_abort_control,
2418 unsupported_abort_transfers,
2419 unsupported_copy_transfer_data,
2423 composite_driver_names,
2424 ARRAYSIZE(composite_driver_names),
2429 common_configure_endpoints,
2430 composite_claim_interface,
2431 composite_set_interface_altsetting,
2432 composite_release_interface,
2433 composite_clear_halt,
2434 composite_reset_device,
2435 composite_submit_bulk_transfer,
2436 composite_submit_iso_transfer,
2437 composite_submit_control_transfer,
2438 composite_abort_control,
2439 composite_abort_transfers,
2440 composite_copy_transfer_data,
2444 winusbx_driver_names,
2445 ARRAYSIZE(winusbx_driver_names),
2450 winusbx_configure_endpoints,
2451 winusbx_claim_interface,
2452 winusbx_set_interface_altsetting,
2453 winusbx_release_interface,
2455 winusbx_reset_device,
2456 winusbx_submit_bulk_transfer,
2457 unsupported_submit_iso_transfer,
2458 winusbx_submit_control_transfer,
2459 winusbx_abort_control,
2460 winusbx_abort_transfers,
2461 winusbx_copy_transfer_data,
2466 ARRAYSIZE(hid_driver_names),
2471 common_configure_endpoints,
2472 hid_claim_interface,
2473 hid_set_interface_altsetting,
2474 hid_release_interface,
2477 hid_submit_bulk_transfer,
2478 unsupported_submit_iso_transfer,
2479 hid_submit_control_transfer,
2480 hid_abort_transfers,
2481 hid_abort_transfers,
2482 hid_copy_transfer_data,
2488 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2490 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2491 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2493 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2496 bool native_winusb = false;
2498 KLIB_VERSION LibK_Version;
2499 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2500 LibK_GetVersion_t pLibK_GetVersion = NULL;
2502 h = GetModuleHandleA("libusbK");
2504 h = LoadLibraryA("libusbK");
2507 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2508 h = GetModuleHandleA("WinUSB");
2510 h = LoadLibraryA("WinUSB");
2512 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2513 "you will not be able to access devices outside of enumeration");
2514 return LIBUSB_ERROR_NOT_FOUND;
2517 usbi_dbg("using libusbK DLL for universal access");
2518 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2519 if (pLibK_GetVersion != NULL) {
2520 pLibK_GetVersion(&LibK_Version);
2521 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2522 LibK_Version.Micro, LibK_Version.Nano);
2524 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2525 if (pLibK_GetProcAddress == NULL) {
2526 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2527 return LIBUSB_ERROR_NOT_FOUND;
2530 native_winusb = (pLibK_GetProcAddress == NULL);
2531 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2532 WinUSBX_Set(AbortPipe);
2533 WinUSBX_Set(ControlTransfer);
2534 WinUSBX_Set(FlushPipe);
2536 WinUSBX_Set(GetAssociatedInterface);
2537 WinUSBX_Set(GetCurrentAlternateSetting);
2538 WinUSBX_Set(GetDescriptor);
2539 WinUSBX_Set(GetOverlappedResult);
2540 WinUSBX_Set(GetPipePolicy);
2541 WinUSBX_Set(GetPowerPolicy);
2542 WinUSBX_Set(Initialize);
2543 WinUSBX_Set(QueryDeviceInformation);
2544 WinUSBX_Set(QueryInterfaceSettings);
2545 WinUSBX_Set(QueryPipe);
2546 WinUSBX_Set(ReadPipe);
2547 WinUSBX_Set(ResetPipe);
2548 WinUSBX_Set(SetCurrentAlternateSetting);
2549 WinUSBX_Set(SetPipePolicy);
2550 WinUSBX_Set(SetPowerPolicy);
2551 WinUSBX_Set(WritePipe);
2552 if (!native_winusb) {
2553 WinUSBX_Set(ResetDevice);
2555 if (WinUSBX[i].Initialize != NULL) {
2556 WinUSBX[i].initialized = true;
2557 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2559 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2560 WinUSBX[i].initialized = false;
2563 return LIBUSB_SUCCESS;
2566 static int winusbx_exit(int sub_api)
2568 return LIBUSB_SUCCESS;
2571 // NB: open and close must ensure that they only handle interface of
2572 // the right API type, as these functions can be called wholesale from
2573 // composite_open(), with interfaces belonging to different APIs
2574 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2576 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2577 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2578 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2583 CHECK_WINUSBX_AVAILABLE(sub_api);
2585 // WinUSB requires a seperate handle for each interface
2586 for (i = 0; i < USB_MAXINTERFACES; i++) {
2587 if ( (priv->usb_interface[i].path != NULL)
2588 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2589 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2590 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2591 if (file_handle == INVALID_HANDLE_VALUE) {
2592 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2593 switch(GetLastError()) {
2594 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2595 return LIBUSB_ERROR_NO_DEVICE;
2596 case ERROR_ACCESS_DENIED:
2597 return LIBUSB_ERROR_ACCESS;
2599 return LIBUSB_ERROR_IO;
2602 handle_priv->interface_handle[i].dev_handle = file_handle;
2606 return LIBUSB_SUCCESS;
2609 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2611 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2612 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2616 if (!WinUSBX[sub_api].initialized)
2619 for (i = 0; i < USB_MAXINTERFACES; i++) {
2620 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2621 file_handle = handle_priv->interface_handle[i].dev_handle;
2622 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2623 CloseHandle(file_handle);
2629 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2631 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2632 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2633 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2636 uint8_t endpoint_address;
2639 CHECK_WINUSBX_AVAILABLE(sub_api);
2641 // With handle and enpoints set (in parent), we can setup the default pipe properties
2642 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2643 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2644 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2645 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2646 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2647 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2649 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2650 continue; // Other policies don't apply to control endpoint or libusb0
2653 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2654 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2655 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2657 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2658 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2659 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2661 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2662 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2663 usbi_dbg("failed to disable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2666 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2667 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2668 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2672 return LIBUSB_SUCCESS;
2675 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2677 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2678 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2679 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2680 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2681 HANDLE file_handle, winusb_handle;
2683 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2685 SP_DEVINFO_DATA dev_info_data;
2686 char* dev_path_no_guid = NULL;
2687 char filter_path[] = "\\\\.\\libusb0-0000";
2688 bool found_filter = false;
2690 CHECK_WINUSBX_AVAILABLE(sub_api);
2692 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2693 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2694 if ((is_using_usbccgp) || (iface == 0)) {
2695 // composite device (independent interfaces) or interface 0
2696 file_handle = handle_priv->interface_handle[iface].dev_handle;
2697 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2698 return LIBUSB_ERROR_NOT_FOUND;
2701 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2702 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2704 switch(GetLastError()) {
2705 case ERROR_BAD_COMMAND:
2706 // The device was disconnected
2707 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2708 return LIBUSB_ERROR_NO_DEVICE;
2710 // it may be that we're using the libusb0 filter driver.
2711 // [TODO] can we move this whole business into the K/0 DLL?
2712 for (i = 0; ; i++) {
2713 safe_free(dev_interface_details);
2714 safe_free(dev_path_no_guid);
2715 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2716 if ((found_filter) || (dev_interface_details == NULL)) {
2720 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2721 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2722 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2723 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2724 if (file_handle == INVALID_HANDLE_VALUE) {
2725 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2727 WinUSBX[sub_api].Free(winusb_handle);
2728 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2731 found_filter = true;
2736 if (!found_filter) {
2737 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2738 return LIBUSB_ERROR_ACCESS;
2742 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2744 // For all other interfaces, use GetAssociatedInterface()
2745 winusb_handle = handle_priv->interface_handle[0].api_handle;
2746 // It is a requirement for multiple interface devices on Windows that, to you
2747 // must first claim the first interface before you claim the others
2748 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2749 file_handle = handle_priv->interface_handle[0].dev_handle;
2750 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2751 handle_priv->interface_handle[0].api_handle = winusb_handle;
2752 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2754 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB)", iface);
2755 return LIBUSB_ERROR_ACCESS;
2758 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2759 &handle_priv->interface_handle[iface].api_handle)) {
2760 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2761 switch(GetLastError()) {
2762 case ERROR_NO_MORE_ITEMS: // invalid iface
2763 return LIBUSB_ERROR_NOT_FOUND;
2764 case ERROR_BAD_COMMAND: // The device was disconnected
2765 return LIBUSB_ERROR_NO_DEVICE;
2766 case ERROR_ALREADY_EXISTS: // already claimed
2767 return LIBUSB_ERROR_BUSY;
2769 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2770 return LIBUSB_ERROR_ACCESS;
2774 usbi_dbg("claimed interface %d", iface);
2775 handle_priv->active_interface = iface;
2777 return LIBUSB_SUCCESS;
2780 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2782 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2783 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2784 HANDLE winusb_handle;
2786 CHECK_WINUSBX_AVAILABLE(sub_api);
2788 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2789 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2790 return LIBUSB_ERROR_NOT_FOUND;
2793 WinUSBX[sub_api].Free(winusb_handle);
2794 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2796 return LIBUSB_SUCCESS;
2800 * Return the first valid interface (of the same API type), for control transfers
2802 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2804 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2805 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2808 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2809 usbi_dbg("unsupported API ID");
2813 for (i=0; i<USB_MAXINTERFACES; i++) {
2814 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2815 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2816 && (handle_priv->interface_handle[i].api_handle != 0)
2817 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2818 && (priv->usb_interface[i].apib->id == api_id) ) {
2826 * Lookup interface by endpoint address. -1 if not found
2828 static int interface_by_endpoint(struct windows_device_priv *priv,
2829 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2832 for (i=0; i<USB_MAXINTERFACES; i++) {
2833 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2835 if (handle_priv->interface_handle[i].api_handle == 0)
2837 if (priv->usb_interface[i].endpoint == NULL)
2839 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2840 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2848 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2850 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2851 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2852 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2853 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2854 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2855 transfer->dev_handle);
2856 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2858 HANDLE winusb_handle;
2859 int current_interface;
2862 CHECK_WINUSBX_AVAILABLE(sub_api);
2864 transfer_priv->pollable_fd = INVALID_WINFD;
2865 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2867 if (size > MAX_CTRL_BUFFER_LENGTH)
2868 return LIBUSB_ERROR_INVALID_PARAM;
2870 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2871 if (current_interface < 0) {
2872 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2873 return LIBUSB_ERROR_NOT_FOUND;
2877 usbi_dbg("will use interface %d", current_interface);
2878 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2880 wfd = usbi_create_fd(winusb_handle, _O_RDONLY);
2881 // Always use the handle returned from usbi_create_fd (wfd.handle)
2883 return LIBUSB_ERROR_NO_MEM;
2886 // Sending of set configuration control requests from WinUSB creates issues
2887 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2888 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2889 if (setup->value != priv->active_config) {
2890 usbi_warn(ctx, "cannot set configuration other than the default one");
2891 usbi_free_fd(wfd.fd);
2892 return LIBUSB_ERROR_INVALID_PARAM;
2894 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2895 wfd.overlapped->InternalHigh = 0;
2897 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2898 if(GetLastError() != ERROR_IO_PENDING) {
2899 usbi_err(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2900 usbi_free_fd(wfd.fd);
2901 return LIBUSB_ERROR_IO;
2904 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2905 wfd.overlapped->InternalHigh = (DWORD)size;
2909 // Use priv_transfer to store data needed for async polling
2910 transfer_priv->pollable_fd = wfd;
2911 transfer_priv->interface_number = (uint8_t)current_interface;
2913 return LIBUSB_SUCCESS;
2916 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2918 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2919 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2920 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2921 HANDLE winusb_handle;
2923 CHECK_WINUSBX_AVAILABLE(sub_api);
2925 if (altsetting > 255) {
2926 return LIBUSB_ERROR_INVALID_PARAM;
2929 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2930 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2931 usbi_err(ctx, "interface must be claimed first");
2932 return LIBUSB_ERROR_NOT_FOUND;
2935 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2936 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2937 return LIBUSB_ERROR_IO;
2940 return LIBUSB_SUCCESS;
2943 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2945 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2946 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2947 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2948 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2949 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2950 HANDLE winusb_handle;
2952 int current_interface;
2955 CHECK_WINUSBX_AVAILABLE(sub_api);
2957 transfer_priv->pollable_fd = INVALID_WINFD;
2959 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2960 if (current_interface < 0) {
2961 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2962 return LIBUSB_ERROR_NOT_FOUND;
2965 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2967 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2969 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? _O_RDONLY : _O_WRONLY);
2970 // Always use the handle returned from usbi_create_fd (wfd.handle)
2972 return LIBUSB_ERROR_NO_MEM;
2975 if (IS_XFERIN(transfer)) {
2976 usbi_dbg("reading %d bytes", transfer->length);
2977 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2979 usbi_dbg("writing %d bytes", transfer->length);
2980 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2983 if(GetLastError() != ERROR_IO_PENDING) {
2984 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2985 usbi_free_fd(wfd.fd);
2986 return LIBUSB_ERROR_IO;
2989 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2990 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
2993 transfer_priv->pollable_fd = wfd;
2994 transfer_priv->interface_number = (uint8_t)current_interface;
2996 return LIBUSB_SUCCESS;
2999 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3001 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3002 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3003 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3004 HANDLE winusb_handle;
3005 int current_interface;
3007 CHECK_WINUSBX_AVAILABLE(sub_api);
3009 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3010 if (current_interface < 0) {
3011 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3012 return LIBUSB_ERROR_NOT_FOUND;
3015 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3016 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3018 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3019 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3020 return LIBUSB_ERROR_NO_DEVICE;
3023 return LIBUSB_SUCCESS;
3027 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3028 * through testing as well):
3029 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3030 * the control transfer using CancelIo"
3032 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3034 // Cancelling of the I/O is done in the parent
3035 return LIBUSB_SUCCESS;
3038 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3040 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3041 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3042 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3043 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3044 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3045 HANDLE winusb_handle;
3046 int current_interface;
3048 CHECK_WINUSBX_AVAILABLE(sub_api);
3050 current_interface = transfer_priv->interface_number;
3051 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3052 usbi_err(ctx, "program assertion failed: invalid interface_number");
3053 return LIBUSB_ERROR_NOT_FOUND;
3055 usbi_dbg("will use interface %d", current_interface);
3057 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3059 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3060 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3061 return LIBUSB_ERROR_NO_DEVICE;
3064 return LIBUSB_SUCCESS;
3068 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3069 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3070 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3071 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3072 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3073 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3075 // TODO (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3076 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3078 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3079 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3080 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3082 HANDLE winusb_handle;
3085 CHECK_WINUSBX_AVAILABLE(sub_api);
3087 // Reset any available pipe (except control)
3088 for (i=0; i<USB_MAXINTERFACES; i++) {
3089 winusb_handle = handle_priv->interface_handle[i].api_handle;
3090 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3092 // Cancel any pollable I/O
3093 usbi_remove_pollfd(ctx, wfd.fd);
3094 usbi_free_fd(wfd.fd);
3095 wfd = handle_to_winfd(winusb_handle);
3098 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3099 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3100 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3101 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3102 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3103 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3105 // FlushPipe seems to fail on OUT pipes
3106 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3107 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3108 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3109 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3111 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3112 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3113 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3119 // libusbK & libusb0 have the ability to issue an actual device reset
3120 if (WinUSBX[sub_api].ResetDevice != NULL) {
3121 winusb_handle = handle_priv->interface_handle[0].api_handle;
3122 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3123 WinUSBX[sub_api].ResetDevice(winusb_handle);
3126 return LIBUSB_SUCCESS;
3129 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3131 itransfer->transferred += io_size;
3132 return LIBUSB_TRANSFER_COMPLETED;
3136 * Internal HID Support functions (from libusb-win32)
3137 * Note that functions that complete data transfer synchronously must return
3138 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3140 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3141 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3143 static int _hid_wcslen(WCHAR *str)
3146 while (str[i] && (str[i] != 0x409)) {
3152 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3154 struct libusb_device_descriptor d;
3156 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3157 d.bDescriptorType = LIBUSB_DT_DEVICE;
3158 d.bcdUSB = 0x0200; /* 2.00 */
3160 d.bDeviceSubClass = 0;
3161 d.bDeviceProtocol = 0;
3162 d.bMaxPacketSize0 = 64; /* fix this! */
3163 d.idVendor = (uint16_t)dev->vid;
3164 d.idProduct = (uint16_t)dev->pid;
3165 d.bcdDevice = 0x0100;
3166 d.iManufacturer = dev->string_index[0];
3167 d.iProduct = dev->string_index[1];
3168 d.iSerialNumber = dev->string_index[2];
3169 d.bNumConfigurations = 1;
3171 if (*size > LIBUSB_DT_DEVICE_SIZE)
3172 *size = LIBUSB_DT_DEVICE_SIZE;
3173 memcpy(data, &d, *size);
3174 return LIBUSB_COMPLETED;
3177 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3179 char num_endpoints = 0;
3180 size_t config_total_len = 0;
3181 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3182 struct libusb_config_descriptor *cd;
3183 struct libusb_interface_descriptor *id;
3184 struct libusb_hid_descriptor *hd;
3185 struct libusb_endpoint_descriptor *ed;
3188 if (dev->input_report_size)
3190 if (dev->output_report_size)
3193 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3194 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3197 cd = (struct libusb_config_descriptor *)tmp;
3198 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3199 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3200 + LIBUSB_DT_INTERFACE_SIZE);
3201 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3202 + LIBUSB_DT_INTERFACE_SIZE
3203 + LIBUSB_DT_HID_SIZE);
3205 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3206 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3207 cd->wTotalLength = (uint16_t) config_total_len;
3208 cd->bNumInterfaces = 1;
3209 cd->bConfigurationValue = 1;
3210 cd->iConfiguration = 0;
3211 cd->bmAttributes = 1 << 7; /* bus powered */
3214 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3215 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3216 id->bInterfaceNumber = 0;
3217 id->bAlternateSetting = 0;
3218 id->bNumEndpoints = num_endpoints;
3219 id->bInterfaceClass = 3;
3220 id->bInterfaceSubClass = 0;
3221 id->bInterfaceProtocol = 0;
3224 tmp_size = LIBUSB_DT_HID_SIZE;
3225 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3227 if (dev->input_report_size) {
3228 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3229 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3230 ed->bEndpointAddress = HID_IN_EP;
3231 ed->bmAttributes = 3;
3232 ed->wMaxPacketSize = dev->input_report_size - 1;
3238 if (dev->output_report_size) {
3239 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3240 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3241 ed->bEndpointAddress = HID_OUT_EP;
3242 ed->bmAttributes = 3;
3243 ed->wMaxPacketSize = dev->output_report_size - 1;
3247 if (*size > config_total_len)
3248 *size = config_total_len;
3249 memcpy(data, tmp, *size);
3250 return LIBUSB_COMPLETED;
3253 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3254 void *data, size_t *size)
3257 size_t tmp_size = 0;
3260 /* language ID, EN-US */
3261 char string_langid[] = {
3266 if ((*size < 2) || (*size > 255)) {
3267 return LIBUSB_ERROR_OVERFLOW;
3271 tmp = string_langid;
3272 tmp_size = sizeof(string_langid)+2;
3274 for (i=0; i<3; i++) {
3275 if (_index == (dev->string_index[i])) {
3276 tmp = dev->string[i];
3277 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3281 if (i == 3) { // not found
3282 return LIBUSB_ERROR_INVALID_PARAM;
3287 return LIBUSB_ERROR_INVALID_PARAM;
3290 if (tmp_size < *size) {
3294 ((uint8_t*)data)[0] = (uint8_t)*size;
3295 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3296 memcpy((uint8_t*)data+2, tmp, *size-2);
3297 return LIBUSB_COMPLETED;
3300 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3302 struct libusb_hid_descriptor d;
3303 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3304 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3306 _hid_get_report_descriptor(dev, tmp, &report_len);
3308 d.bLength = LIBUSB_DT_HID_SIZE;
3309 d.bDescriptorType = LIBUSB_DT_HID;
3310 d.bcdHID = 0x0110; /* 1.10 */
3312 d.bNumDescriptors = 1;
3313 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3314 d.wClassDescriptorLength = (uint16_t)report_len;
3316 if (*size > LIBUSB_DT_HID_SIZE)
3317 *size = LIBUSB_DT_HID_SIZE;
3318 memcpy(data, &d, *size);
3319 return LIBUSB_COMPLETED;
3322 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3324 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3327 /* usage page (0xFFA0 == vendor defined) */
3328 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3329 /* usage (vendor defined) */
3330 d[i++] = 0x09; d[i++] = 0x01;
3331 /* start collection (application) */
3332 d[i++] = 0xA1; d[i++] = 0x01;
3334 if (dev->input_report_size) {
3335 /* usage (vendor defined) */
3336 d[i++] = 0x09; d[i++] = 0x01;
3337 /* logical minimum (0) */
3338 d[i++] = 0x15; d[i++] = 0x00;
3339 /* logical maximum (255) */
3340 d[i++] = 0x25; d[i++] = 0xFF;
3341 /* report size (8 bits) */
3342 d[i++] = 0x75; d[i++] = 0x08;
3344 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3345 /* input (data, variable, absolute) */
3346 d[i++] = 0x81; d[i++] = 0x00;
3349 if (dev->output_report_size) {
3350 /* usage (vendor defined) */
3351 d[i++] = 0x09; d[i++] = 0x02;
3352 /* logical minimum (0) */
3353 d[i++] = 0x15; d[i++] = 0x00;
3354 /* logical maximum (255) */
3355 d[i++] = 0x25; d[i++] = 0xFF;
3356 /* report size (8 bits) */
3357 d[i++] = 0x75; d[i++] = 0x08;
3359 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3360 /* output (data, variable, absolute) */
3361 d[i++] = 0x91; d[i++] = 0x00;
3363 /* feature report */
3364 if (dev->feature_report_size) {
3365 /* usage (vendor defined) */
3366 d[i++] = 0x09; d[i++] = 0x03;
3367 /* logical minimum (0) */
3368 d[i++] = 0x15; d[i++] = 0x00;
3369 /* logical maximum (255) */
3370 d[i++] = 0x25; d[i++] = 0xFF;
3371 /* report size (8 bits) */
3372 d[i++] = 0x75; d[i++] = 0x08;
3374 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3375 /* feature (data, variable, absolute) */
3376 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3379 /* end collection */
3384 memcpy(data, d, *size);
3385 return LIBUSB_COMPLETED;
3388 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3389 int type, int _index, void *data, size_t *size)
3392 case LIBUSB_DT_DEVICE:
3393 usbi_dbg("LIBUSB_DT_DEVICE");
3394 return _hid_get_device_descriptor(dev, data, size);
3395 case LIBUSB_DT_CONFIG:
3396 usbi_dbg("LIBUSB_DT_CONFIG");
3398 return _hid_get_config_descriptor(dev, data, size);
3399 return LIBUSB_ERROR_INVALID_PARAM;
3400 case LIBUSB_DT_STRING:
3401 usbi_dbg("LIBUSB_DT_STRING");
3402 return _hid_get_string_descriptor(dev, _index, data, size);
3404 usbi_dbg("LIBUSB_DT_HID");
3406 return _hid_get_hid_descriptor(dev, data, size);
3407 return LIBUSB_ERROR_INVALID_PARAM;
3408 case LIBUSB_DT_REPORT:
3409 usbi_dbg("LIBUSB_DT_REPORT");
3411 return _hid_get_report_descriptor(dev, data, size);
3412 return LIBUSB_ERROR_INVALID_PARAM;
3413 case LIBUSB_DT_PHYSICAL:
3414 usbi_dbg("LIBUSB_DT_PHYSICAL");
3415 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3416 return LIBUSB_COMPLETED;
3417 return LIBUSB_ERROR_OTHER;
3419 usbi_dbg("unsupported");
3420 return LIBUSB_ERROR_INVALID_PARAM;
3423 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3424 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3428 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3429 int r = LIBUSB_SUCCESS;
3431 if (tp->hid_buffer != NULL) {
3432 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3435 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3436 usbi_dbg("invalid size (%d)", *size);
3437 return LIBUSB_ERROR_INVALID_PARAM;
3440 switch (report_type) {
3441 case HID_REPORT_TYPE_INPUT:
3442 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3444 case HID_REPORT_TYPE_FEATURE:
3445 ioctl_code = IOCTL_HID_GET_FEATURE;
3448 usbi_dbg("unknown HID report type %d", report_type);
3449 return LIBUSB_ERROR_INVALID_PARAM;
3452 // Add a trailing byte to detect overflows
3453 buf = (uint8_t*)calloc(expected_size+1, 1);
3455 return LIBUSB_ERROR_NO_MEM;
3457 buf[0] = (uint8_t)id; // Must be set always
3458 usbi_dbg("report ID: 0x%02X", buf[0]);
3460 tp->hid_expected_size = expected_size;
3461 read_size = expected_size;
3463 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3464 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3465 buf, expected_size+1, &read_size, overlapped)) {
3466 if (GetLastError() != ERROR_IO_PENDING) {
3467 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3469 return LIBUSB_ERROR_IO;
3471 // Asynchronous wait
3472 tp->hid_buffer = buf;
3473 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3474 return LIBUSB_SUCCESS;
3477 // Transfer completed synchronously => copy and discard extra buffer
3478 if (read_size == 0) {
3479 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3483 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3485 if ((size_t)read_size > expected_size) {
3486 r = LIBUSB_ERROR_OVERFLOW;
3487 usbi_dbg("OVERFLOW!");
3489 r = LIBUSB_COMPLETED;
3492 *size = MIN((size_t)read_size, *size);
3494 // Discard report ID
3495 memcpy(data, buf+1, *size);
3497 memcpy(data, buf, *size);
3504 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3505 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3508 uint8_t *buf = NULL;
3509 DWORD ioctl_code, write_size= (DWORD)*size;
3511 if (tp->hid_buffer != NULL) {
3512 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3515 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3516 usbi_dbg("invalid size (%d)", *size);
3517 return LIBUSB_ERROR_INVALID_PARAM;
3520 switch (report_type) {
3521 case HID_REPORT_TYPE_OUTPUT:
3522 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3524 case HID_REPORT_TYPE_FEATURE:
3525 ioctl_code = IOCTL_HID_SET_FEATURE;
3528 usbi_dbg("unknown HID report type %d", report_type);
3529 return LIBUSB_ERROR_INVALID_PARAM;
3532 usbi_dbg("report ID: 0x%02X", id);
3533 // When report IDs are not used (i.e. when id == 0), we must add
3534 // a null report ID. Otherwise, we just use original data buffer
3538 buf = (uint8_t*) malloc(write_size);
3540 return LIBUSB_ERROR_NO_MEM;
3544 memcpy(buf + 1, data, *size);
3546 // This seems like a waste, but if we don't duplicate the
3547 // data, we'll get issues when freeing hid_buffer
3548 memcpy(buf, data, *size);
3550 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3554 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3555 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3556 buf, write_size, &write_size, overlapped)) {
3557 if (GetLastError() != ERROR_IO_PENDING) {
3558 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3560 return LIBUSB_ERROR_IO;
3562 tp->hid_buffer = buf;
3563 tp->hid_dest = NULL;
3564 return LIBUSB_SUCCESS;
3567 // Transfer completed synchronously
3569 if (write_size == 0) {
3570 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3573 return LIBUSB_COMPLETED;
3576 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3577 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3578 size_t *size, OVERLAPPED* overlapped)
3580 int report_type = (value >> 8) & 0xFF;
3581 int report_id = value & 0xFF;
3583 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3584 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3585 return LIBUSB_ERROR_INVALID_PARAM;
3587 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3588 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3590 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3591 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3593 return LIBUSB_ERROR_INVALID_PARAM;
3600 static int hid_init(int sub_api, struct libusb_context *ctx)
3602 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3603 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3604 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3605 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3606 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3607 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3608 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3609 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3610 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3611 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3612 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3613 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3614 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3615 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3616 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3617 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3619 api_hid_available = true;
3620 return LIBUSB_SUCCESS;
3623 static int hid_exit(int sub_api)
3625 return LIBUSB_SUCCESS;
3628 // NB: open and close must ensure that they only handle interface of
3629 // the right API type, as these functions can be called wholesale from
3630 // composite_open(), with interfaces belonging to different APIs
3631 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3633 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3634 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3635 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3637 HIDD_ATTRIBUTES hid_attributes;
3638 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3639 HIDP_CAPS capabilities;
3640 HIDP_VALUE_CAPS *value_caps;
3642 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3644 // report IDs handling
3646 char* type[3] = {"input", "output", "feature"};
3647 int nb_ids[2]; // zero and nonzero report IDs
3649 CHECK_HID_AVAILABLE;
3650 if (priv->hid == NULL) {
3651 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3652 return LIBUSB_ERROR_NOT_FOUND;
3655 for (i = 0; i < USB_MAXINTERFACES; i++) {
3656 if ( (priv->usb_interface[i].path != NULL)
3657 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3658 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3659 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3661 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3662 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3663 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3664 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3665 * HidD_GetFeature (if the device supports Feature reports)."
3667 if (hid_handle == INVALID_HANDLE_VALUE) {
3668 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3669 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3670 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3671 if (hid_handle == INVALID_HANDLE_VALUE) {
3672 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3673 switch(GetLastError()) {
3674 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3675 return LIBUSB_ERROR_NO_DEVICE;
3676 case ERROR_ACCESS_DENIED:
3677 return LIBUSB_ERROR_ACCESS;
3679 return LIBUSB_ERROR_IO;
3682 priv->usb_interface[i].restricted_functionality = true;
3684 handle_priv->interface_handle[i].api_handle = hid_handle;
3688 hid_attributes.Size = sizeof(hid_attributes);
3690 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3691 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3695 priv->hid->vid = hid_attributes.VendorID;
3696 priv->hid->pid = hid_attributes.ProductID;
3698 // Set the maximum available input buffer size
3699 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3700 usbi_dbg("set maximum input buffer size to %d", i/2);
3702 // Get the maximum input and output report size
3703 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3704 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3707 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3708 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3712 // Find out if interrupt will need report IDs
3713 size[0] = capabilities.NumberInputValueCaps;
3714 size[1] = capabilities.NumberOutputValueCaps;
3715 size[2] = capabilities.NumberFeatureValueCaps;
3716 for (j=HidP_Input; j<=HidP_Feature; j++) {
3717 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3718 priv->hid->uses_report_ids[j] = false;
3720 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3721 if ( (value_caps != NULL)
3722 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3723 && (size[j] >= 1) ) {
3726 for (i=0; i<(int)size[j]; i++) {
3727 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3728 if (value_caps[i].ReportID != 0) {
3734 if (nb_ids[1] != 0) {
3735 if (nb_ids[0] != 0) {
3736 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3739 priv->hid->uses_report_ids[j] = true;
3742 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3744 safe_free(value_caps);
3748 // Set the report sizes
3749 priv->hid->input_report_size = capabilities.InputReportByteLength;
3750 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3751 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3753 // Fetch string descriptors
3754 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3755 if (priv->hid->string_index[0] != 0) {
3756 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3757 sizeof(priv->hid->string[0]));
3759 priv->hid->string[0][0] = 0;
3761 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3762 if (priv->hid->string_index[1] != 0) {
3763 HidD_GetProductString(hid_handle, priv->hid->string[1],
3764 sizeof(priv->hid->string[1]));
3766 priv->hid->string[1][0] = 0;
3768 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3769 if (priv->hid->string_index[2] != 0) {
3770 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3771 sizeof(priv->hid->string[2]));
3773 priv->hid->string[2][0] = 0;
3777 if (preparsed_data) {
3778 HidD_FreePreparsedData(preparsed_data);
3781 return LIBUSB_SUCCESS;
3784 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3786 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3787 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3791 if (!api_hid_available)
3794 for (i = 0; i < USB_MAXINTERFACES; i++) {
3795 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3796 file_handle = handle_priv->interface_handle[i].api_handle;
3797 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3798 CloseHandle(file_handle);
3804 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3806 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3807 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3809 CHECK_HID_AVAILABLE;
3811 // NB: Disconnection detection is not possible in this function
3812 if (priv->usb_interface[iface].path == NULL) {
3813 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3816 // We use dev_handle as a flag for interface claimed
3817 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3818 return LIBUSB_ERROR_BUSY; // already claimed
3821 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3823 usbi_dbg("claimed interface %d", iface);
3824 handle_priv->active_interface = iface;
3826 return LIBUSB_SUCCESS;
3829 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3831 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3832 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3834 CHECK_HID_AVAILABLE;
3836 if (priv->usb_interface[iface].path == NULL) {
3837 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3840 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3841 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3844 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3846 return LIBUSB_SUCCESS;
3849 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3851 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3853 CHECK_HID_AVAILABLE;
3855 if (altsetting > 255) {
3856 return LIBUSB_ERROR_INVALID_PARAM;
3859 if (altsetting != 0) {
3860 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3861 return LIBUSB_ERROR_NOT_SUPPORTED;
3864 return LIBUSB_SUCCESS;
3867 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3869 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3870 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3871 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3872 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3873 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3874 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3877 int current_interface, config;
3879 int r = LIBUSB_ERROR_INVALID_PARAM;
3881 CHECK_HID_AVAILABLE;
3883 transfer_priv->pollable_fd = INVALID_WINFD;
3884 safe_free(transfer_priv->hid_buffer);
3885 transfer_priv->hid_dest = NULL;
3886 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3888 if (size > MAX_CTRL_BUFFER_LENGTH) {
3889 return LIBUSB_ERROR_INVALID_PARAM;
3892 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3893 if (current_interface < 0) {
3894 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3895 return LIBUSB_ERROR_NOT_FOUND;
3899 usbi_dbg("will use interface %d", current_interface);
3900 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3901 // Always use the handle returned from usbi_create_fd (wfd.handle)
3902 wfd = usbi_create_fd(hid_handle, _O_RDONLY);
3904 return LIBUSB_ERROR_NO_MEM;
3907 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3908 case LIBUSB_REQUEST_TYPE_STANDARD:
3909 switch(setup->request) {
3910 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3911 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3912 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3914 case LIBUSB_REQUEST_GET_CONFIGURATION:
3915 r = windows_get_configuration(transfer->dev_handle, &config);
3916 if (r == LIBUSB_SUCCESS) {
3918 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3919 r = LIBUSB_COMPLETED;
3922 case LIBUSB_REQUEST_SET_CONFIGURATION:
3923 if (setup->value == priv->active_config) {
3924 r = LIBUSB_COMPLETED;
3926 usbi_warn(ctx, "cannot set configuration other than the default one");
3927 r = LIBUSB_ERROR_INVALID_PARAM;
3930 case LIBUSB_REQUEST_GET_INTERFACE:
3932 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3933 r = LIBUSB_COMPLETED;
3935 case LIBUSB_REQUEST_SET_INTERFACE:
3936 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3937 if (r == LIBUSB_SUCCESS) {
3938 r = LIBUSB_COMPLETED;
3942 usbi_warn(ctx, "unsupported HID control request");
3943 r = LIBUSB_ERROR_INVALID_PARAM;
3947 case LIBUSB_REQUEST_TYPE_CLASS:
3948 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3949 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3950 &size, wfd.overlapped);
3953 usbi_warn(ctx, "unsupported HID control request");
3954 r = LIBUSB_ERROR_INVALID_PARAM;
3958 if (r == LIBUSB_COMPLETED) {
3959 // Force request to be completed synchronously. Transferred size has been set by previous call
3960 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3961 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3962 // set InternalHigh to the number of bytes transferred
3963 wfd.overlapped->InternalHigh = (DWORD)size;
3967 if (r == LIBUSB_SUCCESS) {
3968 // Use priv_transfer to store data needed for async polling
3969 transfer_priv->pollable_fd = wfd;
3970 transfer_priv->interface_number = (uint8_t)current_interface;
3972 usbi_free_fd(wfd.fd);
3978 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3979 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3980 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3981 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3982 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3983 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3986 bool direction_in, ret;
3987 int current_interface, length;
3989 int r = LIBUSB_SUCCESS;
3991 CHECK_HID_AVAILABLE;
3993 transfer_priv->pollable_fd = INVALID_WINFD;
3994 transfer_priv->hid_dest = NULL;
3995 safe_free(transfer_priv->hid_buffer);
3997 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3998 if (current_interface < 0) {
3999 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4000 return LIBUSB_ERROR_NOT_FOUND;
4003 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
4005 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4006 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
4008 wfd = usbi_create_fd(hid_handle, direction_in?_O_RDONLY:_O_WRONLY);
4009 // Always use the handle returned from usbi_create_fd (wfd.handle)
4011 return LIBUSB_ERROR_NO_MEM;
4014 // If report IDs are not in use, an extra prefix byte must be added
4015 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4016 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4017 length = transfer->length+1;
4019 length = transfer->length;
4021 // Add a trailing byte to detect overflows on input
4022 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4023 if (transfer_priv->hid_buffer == NULL) {
4024 return LIBUSB_ERROR_NO_MEM;
4026 transfer_priv->hid_expected_size = length;
4029 transfer_priv->hid_dest = transfer->buffer;
4030 usbi_dbg("reading %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4031 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4033 if (!priv->hid->uses_report_ids[1]) {
4034 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4036 // We could actually do without the calloc and memcpy in this case
4037 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4039 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4040 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4043 if (GetLastError() != ERROR_IO_PENDING) {
4044 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4045 usbi_free_fd(wfd.fd);
4046 safe_free(transfer_priv->hid_buffer);
4047 return LIBUSB_ERROR_IO;
4050 // Only write operations that completed synchronously need to free up
4051 // hid_buffer. For reads, copy_transfer_data() handles that process.
4052 if (!direction_in) {
4053 safe_free(transfer_priv->hid_buffer);
4056 usbi_err(ctx, "program assertion failed - no data was transferred");
4059 if (size > (size_t)length) {
4060 usbi_err(ctx, "OVERFLOW!");
4061 r = LIBUSB_ERROR_OVERFLOW;
4063 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4064 wfd.overlapped->InternalHigh = size;
4067 transfer_priv->pollable_fd = wfd;
4068 transfer_priv->interface_number = (uint8_t)current_interface;
4073 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4075 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4076 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4077 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4079 int current_interface;
4081 CHECK_HID_AVAILABLE;
4083 current_interface = transfer_priv->interface_number;
4084 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4085 CancelIo(hid_handle);
4087 return LIBUSB_SUCCESS;
4090 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4092 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4094 int current_interface;
4096 CHECK_HID_AVAILABLE;
4098 // Flushing the queues on all interfaces is the best we can achieve
4099 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4100 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4101 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4102 HidD_FlushQueue(hid_handle);
4105 return LIBUSB_SUCCESS;
4108 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4110 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4111 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4112 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4114 int current_interface;
4116 CHECK_HID_AVAILABLE;
4118 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4119 if (current_interface < 0) {
4120 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4121 return LIBUSB_ERROR_NOT_FOUND;
4124 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4125 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4127 // No endpoint selection with Microsoft's implementation, so we try to flush the
4128 // whole interface. Should be OK for most case scenarios
4129 if (!HidD_FlushQueue(hid_handle)) {
4130 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4131 // Device was probably disconnected
4132 return LIBUSB_ERROR_NO_DEVICE;
4135 return LIBUSB_SUCCESS;
4138 // This extra function is only needed for HID
4139 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4140 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4141 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4142 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4143 int r = LIBUSB_TRANSFER_COMPLETED;
4144 uint32_t corrected_size = io_size;
4146 if (transfer_priv->hid_buffer != NULL) {
4147 // If we have a valid hid_buffer, it means the transfer was async
4148 if (transfer_priv->hid_dest != NULL) { // Data readout
4149 // First, check for overflow
4150 if (corrected_size > transfer_priv->hid_expected_size) {
4151 usbi_err(ctx, "OVERFLOW!");
4152 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4153 r = LIBUSB_TRANSFER_OVERFLOW;
4156 if (transfer_priv->hid_buffer[0] == 0) {
4157 // Discard the 1 byte report ID prefix
4159 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4161 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4163 transfer_priv->hid_dest = NULL;
4165 // For write, we just need to free the hid buffer
4166 safe_free(transfer_priv->hid_buffer);
4168 itransfer->transferred += corrected_size;
4174 * Composite API functions
4176 static int composite_init(int sub_api, struct libusb_context *ctx)
4178 return LIBUSB_SUCCESS;
4181 static int composite_exit(int sub_api)
4183 return LIBUSB_SUCCESS;
4186 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4188 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4191 bool available[SUB_API_MAX];
4193 for (i = 0; i<SUB_API_MAX; i++) {
4194 available[i] = false;
4197 for (i=0; i<USB_MAXINTERFACES; i++) {
4198 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4199 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4200 available[priv->usb_interface[i].sub_api] = true;
4204 for (i=0; i<SUB_API_MAX; i++) {
4206 r = usb_api_backend[USB_API_WINUSBX].open(SUB_API_NOTSET, dev_handle);
4207 if (r != LIBUSB_SUCCESS) {
4212 return LIBUSB_SUCCESS;
4215 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4217 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4219 bool available[SUB_API_MAX];
4221 for (i = 0; i<SUB_API_MAX; i++) {
4222 available[i] = false;
4225 for (i=0; i<USB_MAXINTERFACES; i++) {
4226 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4227 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4228 available[priv->usb_interface[i].sub_api] = true;
4232 for (i=0; i<SUB_API_MAX; i++) {
4234 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4239 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4241 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4242 return priv->usb_interface[iface].apib->
4243 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4246 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4248 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4249 return priv->usb_interface[iface].apib->
4250 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4253 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4255 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4256 return priv->usb_interface[iface].apib->
4257 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4260 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4262 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4263 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4264 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4267 // Interface shouldn't matter for control, but it does in practice, with Windows'
4268 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4269 for (pass = 0; pass < 2; pass++) {
4270 for (i=0; i<USB_MAXINTERFACES; i++) {
4271 if (priv->usb_interface[i].path != NULL) {
4272 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4273 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4276 usbi_dbg("using interface %d", i);
4277 return priv->usb_interface[i].apib->submit_control_transfer(sub_api, itransfer);
4282 usbi_err(ctx, "no libusbx supported interfaces to complete request");
4283 return LIBUSB_ERROR_NOT_FOUND;
4286 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4287 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4288 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4289 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4290 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4291 int current_interface;
4293 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4294 if (current_interface < 0) {
4295 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4296 return LIBUSB_ERROR_NOT_FOUND;
4299 return priv->usb_interface[current_interface].apib->
4300 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4302 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4303 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4304 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4305 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4306 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4307 int current_interface;
4309 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4310 if (current_interface < 0) {
4311 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4312 return LIBUSB_ERROR_NOT_FOUND;
4315 return priv->usb_interface[current_interface].apib->
4316 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4318 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4320 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4321 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4322 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4323 int current_interface;
4325 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4326 if (current_interface < 0) {
4327 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4328 return LIBUSB_ERROR_NOT_FOUND;
4331 return priv->usb_interface[current_interface].apib->
4332 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4334 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4336 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4337 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4338 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4340 return priv->usb_interface[transfer_priv->interface_number].apib->
4341 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4343 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4345 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4346 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4347 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4349 return priv->usb_interface[transfer_priv->interface_number].apib->
4350 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4352 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4354 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4357 bool available[SUB_API_MAX];
4358 for (i = 0; i<SUB_API_MAX; i++) {
4359 available[i] = false;
4361 for (i=0; i<USB_MAXINTERFACES; i++) {
4362 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4363 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4364 available[priv->usb_interface[i].sub_api] = true;
4367 for (i=0; i<SUB_API_MAX; i++) {
4369 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4370 if (r != LIBUSB_SUCCESS) {
4375 return LIBUSB_SUCCESS;
4378 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4380 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4381 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4382 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4384 return priv->usb_interface[transfer_priv->interface_number].apib->
4385 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);