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_dbg("assigned libusb0 symbolic link %s", filter_path);
437 // libusb0.sys was connected to this device instance at one time; but not anymore.
440 pRegCloseKey(hkey_device_interface);
443 return dev_interface_details;
445 pSetupDiDestroyDeviceInfoList(*dev_info);
446 *dev_info = INVALID_HANDLE_VALUE;
449 /* Hash table functions - modified From glibc 2.3.2:
450 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
451 [Knuth] The Art of Computer Programming, part 3 (6.4) */
452 typedef struct htab_entry {
456 htab_entry* htab_table = NULL;
457 usbi_mutex_t htab_write_mutex = NULL;
458 unsigned long htab_size, htab_filled;
460 /* For the used double hash method the table size has to be a prime. To
461 correct the user given table size we need a prime test. This trivial
462 algorithm is adequate because the code is called only during init and
463 the number is likely to be small */
464 static int isprime(unsigned long number)
466 // no even number will be passed
467 unsigned int divider = 3;
469 while((divider * divider < number) && (number % divider != 0))
472 return (number % divider != 0);
475 /* Before using the hash table we must allocate memory for it.
476 We allocate one element more as the found prime number says.
477 This is done for more effective indexing as explained in the
478 comment for the hash function. */
479 static int htab_create(struct libusb_context *ctx, unsigned long nel)
481 if (htab_table != NULL) {
482 usbi_err(ctx, "hash table already allocated");
486 usbi_mutex_init(&htab_write_mutex, NULL);
488 // Change nel to the first prime number not smaller as nel.
494 usbi_dbg("using %d entries hash table", nel);
497 // allocate memory and zero out.
498 htab_table = (htab_entry*) calloc(htab_size + 1, sizeof(htab_entry));
499 if (htab_table == NULL) {
500 usbi_err(ctx, "could not allocate space for hash table");
507 /* After using the hash table it has to be destroyed. */
508 static void htab_destroy(void)
511 if (htab_table == NULL) {
515 for (i=0; i<htab_size; i++) {
516 if (htab_table[i].used) {
517 safe_free(htab_table[i].str);
520 usbi_mutex_destroy(&htab_write_mutex);
521 safe_free(htab_table);
524 /* This is the search function. It uses double hashing with open addressing.
525 We use an trick to speed up the lookup. The table is created with one
526 more element available. This enables us to use the index zero special.
527 This index will never be used because we store the first hash index in
528 the field used where zero means not used. Every other value means used.
529 The used field can be used as a first fast comparison for equality of
530 the stored and the parameter value. This helps to prevent unnecessary
531 expensive calls of strcmp. */
532 static unsigned long htab_hash(char* str)
534 unsigned long hval, hval2;
536 unsigned long r = 5381;
540 // Compute main hash value (algorithm suggested by Nokia)
541 while ((c = *sz++) != 0)
542 r = ((r << 5) + r) + c;
546 // compute table hash: simply take the modulus
547 hval = r % htab_size;
551 // Try the first index
554 if (htab_table[idx].used) {
555 if ( (htab_table[idx].used == hval)
556 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
560 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
562 // Second hash function, as suggested in [Knuth]
563 hval2 = 1 + hval % (htab_size - 2);
566 // Because size is prime this guarantees to step through all available indexes
568 idx = htab_size + idx - hval2;
573 // If we visited all entries leave the loop unsuccessfully
578 // If entry is found use it.
579 if ( (htab_table[idx].used == hval)
580 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
584 while (htab_table[idx].used);
587 // Not found => New entry
589 // If the table is full return an error
590 if (htab_filled >= htab_size) {
591 usbi_err(NULL, "hash table is full (%d entries)", htab_size);
595 // Concurrent threads might be storing the same entry at the same time
596 // (eg. "simultaneous" enums from different threads) => use a mutex
597 usbi_mutex_lock(&htab_write_mutex);
598 // Just free any previously allocated string (which should be the same as
599 // new one). The possibility of concurrent threads storing a collision
600 // string (same hash, different string) at the same time is extremely low
601 safe_free(htab_table[idx].str);
602 htab_table[idx].used = hval;
603 htab_table[idx].str = (char*) malloc(safe_strlen(str)+1);
604 if (htab_table[idx].str == NULL) {
605 usbi_err(NULL, "could not duplicate string for hash table");
606 usbi_mutex_unlock(&htab_write_mutex);
609 memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
611 usbi_mutex_unlock(&htab_write_mutex);
617 * Returns the session ID of a device's nth level ancestor
618 * If there's no device at the nth level, return 0
620 static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
622 DWORD parent_devinst;
623 unsigned long session_id = 0;
624 char* sanitized_path = NULL;
625 char path[MAX_PATH_LENGTH];
628 if (level < 1) return 0;
629 for (i = 0; i<level; i++) {
630 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
633 devinst = parent_devinst;
635 if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
638 // TODO (post hotplug): try without sanitizing
639 sanitized_path = sanitize_path(path);
640 if (sanitized_path == NULL) {
643 session_id = htab_hash(sanitized_path);
644 safe_free(sanitized_path);
649 * Populate the endpoints addresses of the device_priv interface helper structs
651 static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
654 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
655 struct libusb_config_descriptor *conf_desc;
656 const struct libusb_interface_descriptor *if_desc;
657 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
659 r = libusb_get_config_descriptor(dev_handle->dev, 0, &conf_desc);
660 if (r != LIBUSB_SUCCESS) {
661 usbi_warn(ctx, "could not read config descriptor: error %d", r);
665 if_desc = &conf_desc->interface[iface].altsetting[altsetting];
666 safe_free(priv->usb_interface[iface].endpoint);
668 if (if_desc->bNumEndpoints == 0) {
669 usbi_dbg("no endpoints found for interface %d", iface);
670 return LIBUSB_SUCCESS;
673 priv->usb_interface[iface].endpoint = (uint8_t*) malloc(if_desc->bNumEndpoints);
674 if (priv->usb_interface[iface].endpoint == NULL) {
675 return LIBUSB_ERROR_NO_MEM;
678 priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
679 for (i=0; i<if_desc->bNumEndpoints; i++) {
680 priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
681 usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface);
683 libusb_free_config_descriptor(conf_desc);
685 // Extra init may be required to configure endpoints
686 return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
689 // Lookup for a match in the list of API driver names
690 // return -1 if not found, driver match number otherwise
691 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->apib->id != USB_API_COMPOSITE) {
1242 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1243 return LIBUSB_ERROR_NO_DEVICE;
1246 // Because MI_## are not necessarily in sequential order (some composite
1247 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1248 // interface number from the path's MI value
1249 interface_number = 0;
1250 for (i=0; device_id[i] != 0; ) {
1251 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1252 && (device_id[i++] == '_') ) {
1253 interface_number = (device_id[i++] - '0')*10;
1254 interface_number += device_id[i] - '0';
1259 if (device_id[i] == 0) {
1260 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1261 device_id, interface_number);
1264 if (priv->usb_interface[interface_number].path != NULL) {
1265 if (api == USB_API_HID) {
1266 // HID devices can have multiple collections (COL##) for each MI_## interface
1267 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1268 interface_number, device_id);
1269 return LIBUSB_ERROR_ACCESS;
1271 // In other cases, just use the latest data
1272 safe_free(priv->usb_interface[interface_number].path);
1275 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1276 priv->usb_interface[interface_number].path = dev_interface_path;
1277 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1278 priv->usb_interface[interface_number].sub_api = sub_api;
1279 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1280 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1281 if (priv->hid == NULL)
1282 return LIBUSB_ERROR_NO_MEM;
1285 return LIBUSB_SUCCESS;
1288 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1289 char* dev_interface_path)
1291 struct windows_device_priv *priv = _device_priv(dev);
1293 if (priv->hid == NULL) {
1294 usbi_err(ctx, "program assertion failed: parent is not HID");
1295 return LIBUSB_ERROR_NO_DEVICE;
1297 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1298 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1299 return LIBUSB_ERROR_NO_DEVICE;
1301 if (priv->usb_interface[priv->hid->nb_interfaces].path != NULL) {
1302 safe_free(priv->usb_interface[priv->hid->nb_interfaces].path);
1305 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1306 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1307 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1308 priv->hid->nb_interfaces++;
1309 return LIBUSB_SUCCESS;
1313 * get_device_list: libusbx backend device enumeration function
1315 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1317 struct discovered_devs *discdevs;
1318 HDEVINFO dev_info = { 0 };
1319 char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1320 SP_DEVINFO_DATA dev_info_data = { 0 };
1321 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1323 #define MAX_ENUM_GUIDS 64
1324 const GUID* guid[MAX_ENUM_GUIDS];
1330 int r = LIBUSB_SUCCESS;
1332 int class_index = 0;
1333 unsigned int nb_guids, pass, i, j, ancestor;
1334 char path[MAX_PATH_LENGTH];
1335 char strbuf[MAX_PATH_LENGTH];
1336 struct libusb_device *dev, *parent_dev;
1337 struct windows_device_priv *priv, *parent_priv;
1338 char* dev_interface_path = NULL;
1339 char* dev_id_path = NULL;
1340 unsigned long session_id;
1341 DWORD size, reg_type, port_nr, install_state;
1343 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1346 // Keep a list of newly allocated devs to unref
1347 libusb_device** unref_list;
1348 unsigned int unref_size = 64;
1349 unsigned int unref_cur = 0;
1351 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1352 // PASS 2 : (re)enumerate HUBS
1353 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1354 // and list additional USB device interface GUIDs to explore
1355 // PASS 4 : (re)enumerate master USB devices that have a device interface
1356 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1357 // set the device interfaces.
1359 // Init the GUID table
1360 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1361 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1362 guid[GEN_PASS] = NULL;
1363 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1364 HidD_GetHidGuid(&hid_guid);
1365 guid[HID_PASS] = &hid_guid;
1366 nb_guids = HID_PASS+1;
1368 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1369 if (unref_list == NULL) {
1370 return LIBUSB_ERROR_NO_MEM;
1373 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1374 //#define ENUM_DEBUG
1376 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1377 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1378 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1380 for (i = 0; ; i++) {
1381 // safe loop: free up any (unprotected) dynamic resource
1382 // NB: this is always executed before breaking the loop
1383 safe_free(dev_interface_details);
1384 safe_free(dev_interface_path);
1385 safe_free(dev_id_path);
1386 priv = parent_priv = NULL;
1387 dev = parent_dev = NULL;
1389 // Safe loop: end of loop conditions
1390 if (r != LIBUSB_SUCCESS) {
1393 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1394 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1397 if (pass != GEN_PASS) {
1398 // Except for GEN, all passes deal with device interfaces
1399 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1400 if (dev_interface_details == NULL) {
1403 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1404 if (dev_interface_path == NULL) {
1405 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1410 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1411 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1412 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1413 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1414 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1418 if (class_index >= ARRAYSIZE(usb_class))
1422 // Read the Device ID path. This is what we'll use as UID
1423 // Note that if the device is plugged in a different port or hub, the Device ID changes
1424 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1425 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1426 dev_info_data.DevInst);
1429 dev_id_path = sanitize_path(path);
1430 if (dev_id_path == NULL) {
1431 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1432 dev_info_data.DevInst);
1436 usbi_dbg("PRO: %s", dev_id_path);
1439 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1441 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1442 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1443 ®_type, (BYTE*)&port_nr, 4, &size))
1445 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1446 dev_id_path, windows_error_str(0));
1451 // Set API to use or get additional data from generic pass
1452 api = USB_API_UNSUPPORTED;
1453 sub_api = SUB_API_NOTSET;
1458 // We use the GEN pass to detect driverless devices...
1459 size = sizeof(strbuf);
1460 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1461 ®_type, (BYTE*)strbuf, size, &size)) {
1462 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1463 usbi_info(ctx, "libusbx will not be able to access it.");
1465 // ...and to add the additional device interface GUIDs
1466 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1467 if (key != INVALID_HANDLE_VALUE) {
1468 size = sizeof(guid_string_w);
1469 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1470 (BYTE*)guid_string_w, &size);
1472 if (s == ERROR_SUCCESS) {
1473 if (nb_guids >= MAX_ENUM_GUIDS) {
1474 // If this assert is ever reported, grow a GUID table dynamically
1475 usbi_err(ctx, "program assertion failed: too many GUIDs");
1476 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1478 if_guid = (GUID*) calloc(1, sizeof(GUID));
1479 pCLSIDFromString(guid_string_w, if_guid);
1480 guid[nb_guids++] = if_guid;
1481 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1489 // Get the API type (after checking that the driver installation is OK)
1490 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1491 ®_type, (BYTE*)&install_state, 4, &size))
1493 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1494 dev_id_path, windows_error_str(0));
1495 } else if (install_state != 0) {
1496 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1497 dev_id_path, install_state);
1500 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1504 // Find parent device (for the passes that need it)
1511 // Go through the ancestors until we see a face we recognize
1513 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1514 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1515 if (session_id == 0) {
1518 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1520 if (parent_dev == NULL) {
1521 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1524 parent_priv = _device_priv(parent_dev);
1525 // virtual USB devices are also listed during GEN - don't process these yet
1526 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1532 // Create new or match existing device, using the (hashed) device_id as session id
1533 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1534 // These are the passes that create "new" devices
1535 session_id = htab_hash(dev_id_path);
1536 dev = usbi_get_device_by_session_id(ctx, session_id);
1538 if (pass == DEV_PASS) {
1539 // This can occur if the OS only reports a newly plugged device after we started enum
1540 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1541 " - ignoring", dev_id_path);
1544 usbi_dbg("allocating new device for session [%X]", session_id);
1545 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1546 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1548 windows_device_priv_init(dev);
1549 // Keep track of devices that need unref
1550 unref_list[unref_cur++] = dev;
1551 if (unref_cur >= unref_size) {
1553 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1554 if (unref_list == NULL) {
1555 usbi_err(ctx, "could not realloc list for unref - aborting.");
1556 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1560 usbi_dbg("found existing device for session [%X] (%d.%d)",
1561 session_id, dev->bus_number, dev->device_address);
1563 priv = _device_priv(dev);
1569 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1570 dev->device_address = 0;
1571 dev->num_configurations = 0;
1572 priv->apib = &usb_api_backend[USB_API_HUB];
1573 priv->sub_api = SUB_API_NOTSET;
1574 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1575 priv->path = dev_interface_path; dev_interface_path = NULL;
1579 // If the device has already been setup, don't do it again
1580 if (priv->path != NULL)
1582 // Take care of API initialization
1583 priv->path = dev_interface_path; dev_interface_path = NULL;
1584 priv->apib = &usb_api_backend[api];
1585 priv->sub_api = sub_api;
1587 case USB_API_COMPOSITE:
1591 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1592 if (priv->hid == NULL) {
1593 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1595 priv->hid->nb_interfaces = 0;
1598 // For other devices, the first interface is the same as the device
1599 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1600 if (priv->usb_interface[0].path != NULL) {
1601 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1603 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1605 // The following is needed if we want API calls to work for both simple
1606 // and composite devices.
1607 for(j=0; j<USB_MAXINTERFACES; j++) {
1608 priv->usb_interface[j].apib = &usb_api_backend[api];
1614 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1615 if (r == LIBUSB_SUCCESS) {
1616 // Append device to the list of discovered devices
1617 discdevs = discovered_devs_append(*_discdevs, dev);
1619 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1621 *_discdevs = discdevs;
1622 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1623 // This can occur if the device was disconnected but Windows hasn't
1624 // refreshed its enumeration yet - in that case, we ignore the device
1628 default: // HID_PASS and later
1629 if (parent_priv->apib->id == USB_API_HID) {
1630 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1631 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1632 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1633 dev_interface_path = NULL;
1634 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1635 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1636 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1637 case LIBUSB_SUCCESS:
1638 dev_interface_path = NULL;
1640 case LIBUSB_ERROR_ACCESS:
1641 // interface has already been set => make sure dev_interface_path is freed then
1653 // Free any additional GUIDs
1654 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1655 safe_free(guid[pass]);
1658 // Unref newly allocated devs
1659 for (i=0; i<unref_cur; i++) {
1660 safe_unref_device(unref_list[i]);
1662 safe_free(unref_list);
1668 * exit: libusbx backend deinitialization function
1670 static void windows_exit(void)
1674 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1676 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1677 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1678 if (semaphore == NULL) {
1682 // A successful wait brings our semaphore count to 0 (unsignaled)
1683 // => any concurent wait stalls until the semaphore release
1684 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1685 CloseHandle(semaphore);
1689 // Only works if exits and inits are balanced exactly
1690 if (--concurrent_usage < 0) { // Last exit
1691 for (i=0; i<USB_API_MAX; i++) {
1692 usb_api_backend[i].exit(SUB_API_NOTSET);
1697 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1698 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1699 usbi_dbg("could not wait for timer thread to quit");
1700 TerminateThread(timer_thread, 1);
1702 CloseHandle(timer_thread);
1703 timer_thread = NULL;
1705 for (i = 0; i < 2; i++) {
1706 if (timer_request[i]) {
1707 CloseHandle(timer_request[i]);
1708 timer_request[i] = NULL;
1711 if (timer_response) {
1712 CloseHandle(timer_response);
1713 timer_response = NULL;
1716 CloseHandle(timer_mutex);
1722 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1723 CloseHandle(semaphore);
1726 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1728 struct windows_device_priv *priv = _device_priv(dev);
1730 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1733 return LIBUSB_SUCCESS;
1736 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1738 struct windows_device_priv *priv = _device_priv(dev);
1739 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1742 // config index is zero based
1743 if (config_index >= dev->num_configurations)
1744 return LIBUSB_ERROR_INVALID_PARAM;
1746 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1747 return LIBUSB_ERROR_NOT_FOUND;
1749 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1751 size = min(config_header->wTotalLength, len);
1752 memcpy(buffer, priv->config_descriptor[config_index], size);
1754 return LIBUSB_SUCCESS;
1758 * return the cached copy of the active config descriptor
1760 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1762 struct windows_device_priv *priv = _device_priv(dev);
1764 if (priv->active_config == 0)
1765 return LIBUSB_ERROR_NOT_FOUND;
1767 // config index is zero based
1768 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1771 static int windows_open(struct libusb_device_handle *dev_handle)
1773 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1774 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1776 if (priv->apib == NULL) {
1777 usbi_err(ctx, "program assertion failed - device is not initialized");
1778 return LIBUSB_ERROR_NO_DEVICE;
1781 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1784 static void windows_close(struct libusb_device_handle *dev_handle)
1786 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1788 priv->apib->close(SUB_API_NOTSET, dev_handle);
1791 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1793 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1795 if (priv->active_config == 0) {
1797 return LIBUSB_ERROR_NOT_FOUND;
1800 *config = priv->active_config;
1801 return LIBUSB_SUCCESS;
1805 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1806 * does not currently expose a service that allows higher-level drivers to set
1807 * the configuration."
1809 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1811 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1812 int r = LIBUSB_SUCCESS;
1814 if (config >= USB_MAXCONFIG)
1815 return LIBUSB_ERROR_INVALID_PARAM;
1817 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1818 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1819 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1822 if (r == LIBUSB_SUCCESS) {
1823 priv->active_config = (uint8_t)config;
1828 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1830 int r = LIBUSB_SUCCESS;
1831 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1833 if (iface >= USB_MAXINTERFACES)
1834 return LIBUSB_ERROR_INVALID_PARAM;
1836 safe_free(priv->usb_interface[iface].endpoint);
1837 priv->usb_interface[iface].nb_endpoints= 0;
1839 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1841 if (r == LIBUSB_SUCCESS) {
1842 r = windows_assign_endpoints(dev_handle, iface, 0);
1848 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1850 int r = LIBUSB_SUCCESS;
1851 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1853 safe_free(priv->usb_interface[iface].endpoint);
1854 priv->usb_interface[iface].nb_endpoints= 0;
1856 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1858 if (r == LIBUSB_SUCCESS) {
1859 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1865 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1867 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1869 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1872 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1874 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1875 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1878 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1880 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1881 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1884 // The 3 functions below are unlikely to ever get supported on Windows
1885 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1887 return LIBUSB_ERROR_NOT_SUPPORTED;
1890 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1892 return LIBUSB_ERROR_NOT_SUPPORTED;
1895 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1897 return LIBUSB_ERROR_NOT_SUPPORTED;
1900 static void windows_destroy_device(struct libusb_device *dev)
1902 windows_device_priv_release(dev);
1905 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1907 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1909 usbi_free_fd(transfer_priv->pollable_fd.fd);
1910 safe_free(transfer_priv->hid_buffer);
1911 // When auto claim is in use, attempt to release the auto-claimed interface
1912 auto_release(itransfer);
1915 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1917 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1918 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1919 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1920 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1923 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1924 if (r != LIBUSB_SUCCESS) {
1928 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1929 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1931 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1932 return LIBUSB_SUCCESS;
1935 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1937 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1938 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1939 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1940 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1943 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1944 if (r != LIBUSB_SUCCESS) {
1948 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1949 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1951 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1952 return LIBUSB_SUCCESS;
1955 static int submit_control_transfer(struct usbi_transfer *itransfer)
1957 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1958 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1959 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1960 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1963 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1964 if (r != LIBUSB_SUCCESS) {
1968 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
1970 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1971 return LIBUSB_SUCCESS;
1975 static int windows_submit_transfer(struct usbi_transfer *itransfer)
1977 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1979 switch (transfer->type) {
1980 case LIBUSB_TRANSFER_TYPE_CONTROL:
1981 return submit_control_transfer(itransfer);
1982 case LIBUSB_TRANSFER_TYPE_BULK:
1983 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1984 if (IS_XFEROUT(transfer) &&
1985 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
1986 return LIBUSB_ERROR_NOT_SUPPORTED;
1987 return submit_bulk_transfer(itransfer);
1988 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1989 return submit_iso_transfer(itransfer);
1991 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1992 return LIBUSB_ERROR_INVALID_PARAM;
1996 static int windows_abort_control(struct usbi_transfer *itransfer)
1998 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1999 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2001 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2004 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2006 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2007 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2009 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2012 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2014 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2016 switch (transfer->type) {
2017 case LIBUSB_TRANSFER_TYPE_CONTROL:
2018 return windows_abort_control(itransfer);
2019 case LIBUSB_TRANSFER_TYPE_BULK:
2020 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2021 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2022 return windows_abort_transfers(itransfer);
2024 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2025 return LIBUSB_ERROR_INVALID_PARAM;
2029 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2031 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2032 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2035 usbi_dbg("handling I/O completion with errcode %d", io_result);
2039 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2041 case ERROR_GEN_FAILURE:
2042 usbi_dbg("detected endpoint stall");
2043 status = LIBUSB_TRANSFER_STALL;
2045 case ERROR_SEM_TIMEOUT:
2046 usbi_dbg("detected semaphore timeout");
2047 status = LIBUSB_TRANSFER_TIMED_OUT;
2049 case ERROR_OPERATION_ABORTED:
2050 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2051 usbi_dbg("detected timeout");
2052 status = LIBUSB_TRANSFER_TIMED_OUT;
2054 usbi_dbg("detected operation aborted");
2055 status = LIBUSB_TRANSFER_CANCELLED;
2059 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(0));
2060 status = LIBUSB_TRANSFER_ERROR;
2063 windows_clear_transfer_priv(itransfer); // Cancel polling
2064 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2067 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2069 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2071 switch (transfer->type) {
2072 case LIBUSB_TRANSFER_TYPE_CONTROL:
2073 case LIBUSB_TRANSFER_TYPE_BULK:
2074 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2075 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2076 windows_transfer_callback (itransfer, io_result, io_size);
2079 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2083 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2085 struct windows_transfer_priv* transfer_priv = NULL;
2086 POLL_NFDS_TYPE i = 0;
2088 struct usbi_transfer *transfer;
2089 DWORD io_size, io_result;
2091 usbi_mutex_lock(&ctx->open_devs_lock);
2092 for (i = 0; i < nfds && num_ready > 0; i++) {
2094 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2096 if (!fds[i].revents) {
2102 // Because a Windows OVERLAPPED is used for poll emulation,
2103 // a pollable fd is created and stored with each transfer
2104 usbi_mutex_lock(&ctx->flying_transfers_lock);
2105 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2106 transfer_priv = usbi_transfer_get_os_priv(transfer);
2107 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2112 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2115 // Handle async requests that completed synchronously first
2116 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2117 io_result = NO_ERROR;
2118 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2119 // Regular async overlapped
2120 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2121 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2122 io_result = NO_ERROR;
2124 io_result = GetLastError();
2126 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2127 // let handle_callback free the event using the transfer wfd
2128 // If you don't use the transfer wfd, you run a risk of trying to free a
2129 // newly allocated wfd that took the place of the one from the transfer.
2130 windows_handle_callback(transfer, io_result, io_size);
2132 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2133 return LIBUSB_ERROR_NOT_FOUND;
2137 usbi_mutex_unlock(&ctx->open_devs_lock);
2138 return LIBUSB_SUCCESS;
2142 * Monotonic and real time functions
2144 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2146 LARGE_INTEGER hires_counter, li_frequency;
2150 // Init - find out if we have access to a monotonic (hires) timer
2151 if (!QueryPerformanceFrequency(&li_frequency)) {
2152 usbi_dbg("no hires timer available on this platform");
2153 hires_frequency = 0;
2154 hires_ticks_to_ps = UINT64_C(0);
2156 hires_frequency = li_frequency.QuadPart;
2157 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2158 // to picoseconds to compute the tv_nsecs part in clock_gettime
2159 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2160 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2163 // Main loop - wait for requests
2165 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2166 if ( (timer_index != 0) && (timer_index != 1) ) {
2167 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2170 if (request_count[timer_index] == 0) {
2171 // Request already handled
2172 ResetEvent(timer_request[timer_index]);
2173 // There's still a possiblity that a thread sends a request between the
2174 // time we test request_count[] == 0 and we reset the event, in which case
2175 // the request would be ignored. The simple solution to that is to test
2176 // request_count again and process requests if non zero.
2177 if (request_count[timer_index] == 0)
2180 switch (timer_index) {
2182 WaitForSingleObject(timer_mutex, INFINITE);
2183 // Requests to this thread are for hires always
2184 if (QueryPerformanceCounter(&hires_counter) != 0) {
2185 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2186 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2188 // Fallback to real-time if we can't get monotonic value
2189 // Note that real-time clock does not wait on the mutex or this thread.
2190 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2192 ReleaseMutex(timer_mutex);
2194 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2196 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2197 usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0));
2200 case 1: // time to quit
2201 usbi_dbg("timer thread quitting");
2207 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2210 ULARGE_INTEGER rtime;
2213 case USBI_CLOCK_MONOTONIC:
2214 if (hires_frequency != 0) {
2216 InterlockedIncrement((LONG*)&request_count[0]);
2217 SetEvent(timer_request[0]);
2218 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2221 WaitForSingleObject(timer_mutex, INFINITE);
2223 ReleaseMutex(timer_mutex);
2224 return LIBUSB_SUCCESS;
2226 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2227 break; // Retry until successful
2229 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2230 return LIBUSB_ERROR_OTHER;
2234 // Fall through and return real-time if monotonic was not detected @ timer init
2235 case USBI_CLOCK_REALTIME:
2236 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2237 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2238 // Note however that our resolution is bounded by the Windows system time
2239 // functions and is at best of the order of 1 ms (or, usually, worse)
2240 GetSystemTimeAsFileTime(&filetime);
2241 rtime.LowPart = filetime.dwLowDateTime;
2242 rtime.HighPart = filetime.dwHighDateTime;
2243 rtime.QuadPart -= epoch_time;
2244 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2245 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2246 return LIBUSB_SUCCESS;
2248 return LIBUSB_ERROR_INVALID_PARAM;
2253 // NB: MSVC6 does not support named initializers.
2254 const struct usbi_os_backend windows_backend = {
2259 windows_get_device_list,
2263 windows_get_device_descriptor,
2264 windows_get_active_config_descriptor,
2265 windows_get_config_descriptor,
2267 windows_get_configuration,
2268 windows_set_configuration,
2269 windows_claim_interface,
2270 windows_release_interface,
2272 windows_set_interface_altsetting,
2274 windows_reset_device,
2276 windows_kernel_driver_active,
2277 windows_detach_kernel_driver,
2278 windows_attach_kernel_driver,
2280 windows_destroy_device,
2282 windows_submit_transfer,
2283 windows_cancel_transfer,
2284 windows_clear_transfer_priv,
2286 windows_handle_events,
2288 windows_clock_gettime,
2289 #if defined(USBI_TIMERFD_AVAILABLE)
2292 sizeof(struct windows_device_priv),
2293 sizeof(struct windows_device_handle_priv),
2294 sizeof(struct windows_transfer_priv),
2302 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2303 return LIBUSB_SUCCESS;
2305 static int unsupported_exit(int sub_api) {
2306 return LIBUSB_SUCCESS;
2308 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2309 PRINT_UNSUPPORTED_API(open);
2311 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2312 usbi_dbg("unsupported API call for 'close'");
2314 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2315 PRINT_UNSUPPORTED_API(configure_endpoints);
2317 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2318 PRINT_UNSUPPORTED_API(claim_interface);
2320 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2321 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2323 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2324 PRINT_UNSUPPORTED_API(release_interface);
2326 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2327 PRINT_UNSUPPORTED_API(clear_halt);
2329 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2330 PRINT_UNSUPPORTED_API(reset_device);
2332 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2333 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2335 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2336 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2338 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2339 PRINT_UNSUPPORTED_API(submit_control_transfer);
2341 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2342 PRINT_UNSUPPORTED_API(abort_control);
2344 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2345 PRINT_UNSUPPORTED_API(abort_transfers);
2347 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2348 PRINT_UNSUPPORTED_API(copy_transfer_data);
2350 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2351 return LIBUSB_SUCCESS;
2353 // These names must be uppercase
2354 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2355 const char* composite_driver_names[] = {"USBCCGP"};
2356 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2357 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2358 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2360 USB_API_UNSUPPORTED,
2368 unsupported_configure_endpoints,
2369 unsupported_claim_interface,
2370 unsupported_set_interface_altsetting,
2371 unsupported_release_interface,
2372 unsupported_clear_halt,
2373 unsupported_reset_device,
2374 unsupported_submit_bulk_transfer,
2375 unsupported_submit_iso_transfer,
2376 unsupported_submit_control_transfer,
2377 unsupported_abort_control,
2378 unsupported_abort_transfers,
2379 unsupported_copy_transfer_data,
2384 ARRAYSIZE(hub_driver_names),
2389 unsupported_configure_endpoints,
2390 unsupported_claim_interface,
2391 unsupported_set_interface_altsetting,
2392 unsupported_release_interface,
2393 unsupported_clear_halt,
2394 unsupported_reset_device,
2395 unsupported_submit_bulk_transfer,
2396 unsupported_submit_iso_transfer,
2397 unsupported_submit_control_transfer,
2398 unsupported_abort_control,
2399 unsupported_abort_transfers,
2400 unsupported_copy_transfer_data,
2404 composite_driver_names,
2405 ARRAYSIZE(composite_driver_names),
2410 common_configure_endpoints,
2411 composite_claim_interface,
2412 composite_set_interface_altsetting,
2413 composite_release_interface,
2414 composite_clear_halt,
2415 composite_reset_device,
2416 composite_submit_bulk_transfer,
2417 composite_submit_iso_transfer,
2418 composite_submit_control_transfer,
2419 composite_abort_control,
2420 composite_abort_transfers,
2421 composite_copy_transfer_data,
2425 winusbx_driver_names,
2426 ARRAYSIZE(winusbx_driver_names),
2431 winusbx_configure_endpoints,
2432 winusbx_claim_interface,
2433 winusbx_set_interface_altsetting,
2434 winusbx_release_interface,
2436 winusbx_reset_device,
2437 winusbx_submit_bulk_transfer,
2438 unsupported_submit_iso_transfer,
2439 winusbx_submit_control_transfer,
2440 winusbx_abort_control,
2441 winusbx_abort_transfers,
2442 winusbx_copy_transfer_data,
2447 ARRAYSIZE(hid_driver_names),
2452 common_configure_endpoints,
2453 hid_claim_interface,
2454 hid_set_interface_altsetting,
2455 hid_release_interface,
2458 hid_submit_bulk_transfer,
2459 unsupported_submit_iso_transfer,
2460 hid_submit_control_transfer,
2461 hid_abort_transfers,
2462 hid_abort_transfers,
2463 hid_copy_transfer_data,
2469 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2471 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2472 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2474 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2477 bool native_winusb = false;
2479 KLIB_VERSION LibK_Version;
2480 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2481 LibK_GetVersion_t pLibK_GetVersion = NULL;
2483 h = GetModuleHandleA("libusbK");
2485 h = LoadLibraryA("libusbK");
2488 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2489 h = GetModuleHandleA("WinUSB");
2491 h = LoadLibraryA("WinUSB");
2493 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2494 "you will not be able to access devices outside of enumeration");
2495 return LIBUSB_ERROR_NOT_FOUND;
2498 usbi_dbg("using libusbK DLL for universal access");
2499 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2500 if (pLibK_GetVersion != NULL) {
2501 pLibK_GetVersion(&LibK_Version);
2502 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2503 LibK_Version.Micro, LibK_Version.Nano);
2505 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2506 if (pLibK_GetProcAddress == NULL) {
2507 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2508 return LIBUSB_ERROR_NOT_FOUND;
2511 native_winusb = (pLibK_GetProcAddress == NULL);
2512 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2513 WinUSBX_Set(AbortPipe);
2514 WinUSBX_Set(ControlTransfer);
2515 WinUSBX_Set(FlushPipe);
2517 WinUSBX_Set(GetAssociatedInterface);
2518 WinUSBX_Set(GetCurrentAlternateSetting);
2519 WinUSBX_Set(GetDescriptor);
2520 WinUSBX_Set(GetOverlappedResult);
2521 WinUSBX_Set(GetPipePolicy);
2522 WinUSBX_Set(GetPowerPolicy);
2523 WinUSBX_Set(Initialize);
2524 WinUSBX_Set(QueryDeviceInformation);
2525 WinUSBX_Set(QueryInterfaceSettings);
2526 WinUSBX_Set(QueryPipe);
2527 WinUSBX_Set(ReadPipe);
2528 WinUSBX_Set(ResetPipe);
2529 WinUSBX_Set(SetCurrentAlternateSetting);
2530 WinUSBX_Set(SetPipePolicy);
2531 WinUSBX_Set(SetPowerPolicy);
2532 WinUSBX_Set(WritePipe);
2533 if (!native_winusb) {
2534 WinUSBX_Set(ResetDevice);
2536 if (WinUSBX[i].Initialize != NULL) {
2537 WinUSBX[i].initialized = true;
2538 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2540 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2541 WinUSBX[i].initialized = false;
2544 return LIBUSB_SUCCESS;
2547 static int winusbx_exit(int sub_api)
2549 return LIBUSB_SUCCESS;
2552 // NB: open and close must ensure that they only handle interface of
2553 // the right API type, as these functions can be called wholesale from
2554 // composite_open(), with interfaces belonging to different APIs
2555 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2557 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2558 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2559 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2564 CHECK_WINUSBX_AVAILABLE(sub_api);
2566 // WinUSB requires a seperate handle for each interface
2567 for (i = 0; i < USB_MAXINTERFACES; i++) {
2568 if ( (priv->usb_interface[i].path != NULL)
2569 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2570 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2571 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2572 if (file_handle == INVALID_HANDLE_VALUE) {
2573 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2574 switch(GetLastError()) {
2575 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2576 return LIBUSB_ERROR_NO_DEVICE;
2577 case ERROR_ACCESS_DENIED:
2578 return LIBUSB_ERROR_ACCESS;
2580 return LIBUSB_ERROR_IO;
2583 handle_priv->interface_handle[i].dev_handle = file_handle;
2587 return LIBUSB_SUCCESS;
2590 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2592 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2593 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2597 if (sub_api == SUB_API_NOTSET)
2598 sub_api = priv->sub_api;
2599 if (!WinUSBX[sub_api].initialized)
2602 for (i = 0; i < USB_MAXINTERFACES; i++) {
2603 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2604 file_handle = handle_priv->interface_handle[i].dev_handle;
2605 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2606 CloseHandle(file_handle);
2612 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2614 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2615 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2616 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2619 uint8_t endpoint_address;
2622 CHECK_WINUSBX_AVAILABLE(sub_api);
2624 // With handle and enpoints set (in parent), we can setup the default pipe properties
2625 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2626 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2627 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2628 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2629 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2630 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2632 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2633 continue; // Other policies don't apply to control endpoint or libusb0
2636 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2637 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2638 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2640 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2641 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2642 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2645 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2646 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2647 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2648 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2649 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2651 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2652 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2653 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2657 return LIBUSB_SUCCESS;
2660 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2662 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2663 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2664 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2665 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2666 HANDLE file_handle, winusb_handle;
2668 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2670 SP_DEVINFO_DATA dev_info_data;
2671 char* dev_path_no_guid = NULL;
2672 char filter_path[] = "\\\\.\\libusb0-0000";
2673 bool found_filter = false;
2675 CHECK_WINUSBX_AVAILABLE(sub_api);
2677 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2678 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2679 if ((is_using_usbccgp) || (iface == 0)) {
2680 // composite device (independent interfaces) or interface 0
2681 file_handle = handle_priv->interface_handle[iface].dev_handle;
2682 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2683 return LIBUSB_ERROR_NOT_FOUND;
2686 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2687 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2689 switch(GetLastError()) {
2690 case ERROR_BAD_COMMAND:
2691 // The device was disconnected
2692 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2693 return LIBUSB_ERROR_NO_DEVICE;
2695 // it may be that we're using the libusb0 filter driver.
2696 // [TODO] can we move this whole business into the K/0 DLL?
2697 for (i = 0; ; i++) {
2698 safe_free(dev_interface_details);
2699 safe_free(dev_path_no_guid);
2700 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2701 if ((found_filter) || (dev_interface_details == NULL)) {
2705 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2706 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2707 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2708 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2709 if (file_handle == INVALID_HANDLE_VALUE) {
2710 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2712 WinUSBX[sub_api].Free(winusb_handle);
2713 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2716 found_filter = true;
2721 if (!found_filter) {
2722 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2723 return LIBUSB_ERROR_ACCESS;
2727 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2729 // For all other interfaces, use GetAssociatedInterface()
2730 winusb_handle = handle_priv->interface_handle[0].api_handle;
2731 // It is a requirement for multiple interface devices on Windows that, to you
2732 // must first claim the first interface before you claim the others
2733 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2734 file_handle = handle_priv->interface_handle[0].dev_handle;
2735 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2736 handle_priv->interface_handle[0].api_handle = winusb_handle;
2737 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2739 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB)", iface);
2740 return LIBUSB_ERROR_ACCESS;
2743 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2744 &handle_priv->interface_handle[iface].api_handle)) {
2745 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2746 switch(GetLastError()) {
2747 case ERROR_NO_MORE_ITEMS: // invalid iface
2748 return LIBUSB_ERROR_NOT_FOUND;
2749 case ERROR_BAD_COMMAND: // The device was disconnected
2750 return LIBUSB_ERROR_NO_DEVICE;
2751 case ERROR_ALREADY_EXISTS: // already claimed
2752 return LIBUSB_ERROR_BUSY;
2754 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2755 return LIBUSB_ERROR_ACCESS;
2759 usbi_dbg("claimed interface %d", iface);
2760 handle_priv->active_interface = iface;
2762 return LIBUSB_SUCCESS;
2765 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2767 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2768 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2769 HANDLE winusb_handle;
2771 CHECK_WINUSBX_AVAILABLE(sub_api);
2773 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2774 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2775 return LIBUSB_ERROR_NOT_FOUND;
2778 WinUSBX[sub_api].Free(winusb_handle);
2779 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2781 return LIBUSB_SUCCESS;
2785 * Return the first valid interface (of the same API type), for control transfers
2787 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2789 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2790 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2793 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2794 usbi_dbg("unsupported API ID");
2798 for (i=0; i<USB_MAXINTERFACES; i++) {
2799 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2800 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2801 && (handle_priv->interface_handle[i].api_handle != 0)
2802 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2803 && (priv->usb_interface[i].apib->id == api_id) ) {
2811 * Lookup interface by endpoint address. -1 if not found
2813 static int interface_by_endpoint(struct windows_device_priv *priv,
2814 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2817 for (i=0; i<USB_MAXINTERFACES; i++) {
2818 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2820 if (handle_priv->interface_handle[i].api_handle == 0)
2822 if (priv->usb_interface[i].endpoint == NULL)
2824 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2825 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2833 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2835 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2836 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2837 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2838 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2839 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2840 transfer->dev_handle);
2841 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2843 HANDLE winusb_handle;
2844 int current_interface;
2847 CHECK_WINUSBX_AVAILABLE(sub_api);
2849 transfer_priv->pollable_fd = INVALID_WINFD;
2850 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2852 if (size > MAX_CTRL_BUFFER_LENGTH)
2853 return LIBUSB_ERROR_INVALID_PARAM;
2855 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2856 if (current_interface < 0) {
2857 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2858 return LIBUSB_ERROR_NOT_FOUND;
2862 usbi_dbg("will use interface %d", current_interface);
2863 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2865 wfd = usbi_create_fd(winusb_handle, _O_RDONLY);
2866 // Always use the handle returned from usbi_create_fd (wfd.handle)
2868 return LIBUSB_ERROR_NO_MEM;
2871 // Sending of set configuration control requests from WinUSB creates issues
2872 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2873 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2874 if (setup->value != priv->active_config) {
2875 usbi_warn(ctx, "cannot set configuration other than the default one");
2876 usbi_free_fd(wfd.fd);
2877 return LIBUSB_ERROR_INVALID_PARAM;
2879 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2880 wfd.overlapped->InternalHigh = 0;
2882 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2883 if(GetLastError() != ERROR_IO_PENDING) {
2884 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2885 usbi_free_fd(wfd.fd);
2886 return LIBUSB_ERROR_IO;
2889 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2890 wfd.overlapped->InternalHigh = (DWORD)size;
2894 // Use priv_transfer to store data needed for async polling
2895 transfer_priv->pollable_fd = wfd;
2896 transfer_priv->interface_number = (uint8_t)current_interface;
2898 return LIBUSB_SUCCESS;
2901 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2903 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2904 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2905 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2906 HANDLE winusb_handle;
2908 CHECK_WINUSBX_AVAILABLE(sub_api);
2910 if (altsetting > 255) {
2911 return LIBUSB_ERROR_INVALID_PARAM;
2914 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2915 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2916 usbi_err(ctx, "interface must be claimed first");
2917 return LIBUSB_ERROR_NOT_FOUND;
2920 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2921 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2922 return LIBUSB_ERROR_IO;
2925 return LIBUSB_SUCCESS;
2928 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2930 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2931 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2932 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2933 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2934 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2935 HANDLE winusb_handle;
2937 int current_interface;
2940 CHECK_WINUSBX_AVAILABLE(sub_api);
2942 transfer_priv->pollable_fd = INVALID_WINFD;
2944 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2945 if (current_interface < 0) {
2946 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2947 return LIBUSB_ERROR_NOT_FOUND;
2950 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2952 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2954 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? _O_RDONLY : _O_WRONLY);
2955 // Always use the handle returned from usbi_create_fd (wfd.handle)
2957 return LIBUSB_ERROR_NO_MEM;
2960 if (IS_XFERIN(transfer)) {
2961 usbi_dbg("reading %d bytes", transfer->length);
2962 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2964 usbi_dbg("writing %d bytes", transfer->length);
2965 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2968 if(GetLastError() != ERROR_IO_PENDING) {
2969 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2970 usbi_free_fd(wfd.fd);
2971 return LIBUSB_ERROR_IO;
2974 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2975 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
2978 transfer_priv->pollable_fd = wfd;
2979 transfer_priv->interface_number = (uint8_t)current_interface;
2981 return LIBUSB_SUCCESS;
2984 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
2986 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2987 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2988 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2989 HANDLE winusb_handle;
2990 int current_interface;
2992 CHECK_WINUSBX_AVAILABLE(sub_api);
2994 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
2995 if (current_interface < 0) {
2996 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
2997 return LIBUSB_ERROR_NOT_FOUND;
3000 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3001 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3003 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3004 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3005 return LIBUSB_ERROR_NO_DEVICE;
3008 return LIBUSB_SUCCESS;
3012 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3013 * through testing as well):
3014 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3015 * the control transfer using CancelIo"
3017 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3019 // Cancelling of the I/O is done in the parent
3020 return LIBUSB_SUCCESS;
3023 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3025 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3026 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3027 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3028 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3029 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3030 HANDLE winusb_handle;
3031 int current_interface;
3033 CHECK_WINUSBX_AVAILABLE(sub_api);
3035 current_interface = transfer_priv->interface_number;
3036 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3037 usbi_err(ctx, "program assertion failed: invalid interface_number");
3038 return LIBUSB_ERROR_NOT_FOUND;
3040 usbi_dbg("will use interface %d", current_interface);
3042 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3044 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3045 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3046 return LIBUSB_ERROR_NO_DEVICE;
3049 return LIBUSB_SUCCESS;
3053 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3054 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3055 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3056 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3057 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3058 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3060 // TODO (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3061 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3063 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3064 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3065 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3067 HANDLE winusb_handle;
3070 CHECK_WINUSBX_AVAILABLE(sub_api);
3072 // Reset any available pipe (except control)
3073 for (i=0; i<USB_MAXINTERFACES; i++) {
3074 winusb_handle = handle_priv->interface_handle[i].api_handle;
3075 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3077 // Cancel any pollable I/O
3078 usbi_remove_pollfd(ctx, wfd.fd);
3079 usbi_free_fd(wfd.fd);
3080 wfd = handle_to_winfd(winusb_handle);
3083 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3084 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3085 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3086 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3087 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3088 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3090 // FlushPipe seems to fail on OUT pipes
3091 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3092 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3093 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3094 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3096 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3097 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3098 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3104 // libusbK & libusb0 have the ability to issue an actual device reset
3105 if (WinUSBX[sub_api].ResetDevice != NULL) {
3106 winusb_handle = handle_priv->interface_handle[0].api_handle;
3107 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3108 WinUSBX[sub_api].ResetDevice(winusb_handle);
3111 return LIBUSB_SUCCESS;
3114 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3116 itransfer->transferred += io_size;
3117 return LIBUSB_TRANSFER_COMPLETED;
3121 * Internal HID Support functions (from libusb-win32)
3122 * Note that functions that complete data transfer synchronously must return
3123 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3125 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3126 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3128 static int _hid_wcslen(WCHAR *str)
3131 while (str[i] && (str[i] != 0x409)) {
3137 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3139 struct libusb_device_descriptor d;
3141 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3142 d.bDescriptorType = LIBUSB_DT_DEVICE;
3143 d.bcdUSB = 0x0200; /* 2.00 */
3145 d.bDeviceSubClass = 0;
3146 d.bDeviceProtocol = 0;
3147 d.bMaxPacketSize0 = 64; /* fix this! */
3148 d.idVendor = (uint16_t)dev->vid;
3149 d.idProduct = (uint16_t)dev->pid;
3150 d.bcdDevice = 0x0100;
3151 d.iManufacturer = dev->string_index[0];
3152 d.iProduct = dev->string_index[1];
3153 d.iSerialNumber = dev->string_index[2];
3154 d.bNumConfigurations = 1;
3156 if (*size > LIBUSB_DT_DEVICE_SIZE)
3157 *size = LIBUSB_DT_DEVICE_SIZE;
3158 memcpy(data, &d, *size);
3159 return LIBUSB_COMPLETED;
3162 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3164 char num_endpoints = 0;
3165 size_t config_total_len = 0;
3166 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3167 struct libusb_config_descriptor *cd;
3168 struct libusb_interface_descriptor *id;
3169 struct libusb_hid_descriptor *hd;
3170 struct libusb_endpoint_descriptor *ed;
3173 if (dev->input_report_size)
3175 if (dev->output_report_size)
3178 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3179 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3182 cd = (struct libusb_config_descriptor *)tmp;
3183 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3184 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3185 + LIBUSB_DT_INTERFACE_SIZE);
3186 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3187 + LIBUSB_DT_INTERFACE_SIZE
3188 + LIBUSB_DT_HID_SIZE);
3190 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3191 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3192 cd->wTotalLength = (uint16_t) config_total_len;
3193 cd->bNumInterfaces = 1;
3194 cd->bConfigurationValue = 1;
3195 cd->iConfiguration = 0;
3196 cd->bmAttributes = 1 << 7; /* bus powered */
3199 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3200 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3201 id->bInterfaceNumber = 0;
3202 id->bAlternateSetting = 0;
3203 id->bNumEndpoints = num_endpoints;
3204 id->bInterfaceClass = 3;
3205 id->bInterfaceSubClass = 0;
3206 id->bInterfaceProtocol = 0;
3209 tmp_size = LIBUSB_DT_HID_SIZE;
3210 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3212 if (dev->input_report_size) {
3213 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3214 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3215 ed->bEndpointAddress = HID_IN_EP;
3216 ed->bmAttributes = 3;
3217 ed->wMaxPacketSize = dev->input_report_size - 1;
3223 if (dev->output_report_size) {
3224 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3225 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3226 ed->bEndpointAddress = HID_OUT_EP;
3227 ed->bmAttributes = 3;
3228 ed->wMaxPacketSize = dev->output_report_size - 1;
3232 if (*size > config_total_len)
3233 *size = config_total_len;
3234 memcpy(data, tmp, *size);
3235 return LIBUSB_COMPLETED;
3238 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3239 void *data, size_t *size)
3242 size_t tmp_size = 0;
3245 /* language ID, EN-US */
3246 char string_langid[] = {
3251 if ((*size < 2) || (*size > 255)) {
3252 return LIBUSB_ERROR_OVERFLOW;
3256 tmp = string_langid;
3257 tmp_size = sizeof(string_langid)+2;
3259 for (i=0; i<3; i++) {
3260 if (_index == (dev->string_index[i])) {
3261 tmp = dev->string[i];
3262 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3266 if (i == 3) { // not found
3267 return LIBUSB_ERROR_INVALID_PARAM;
3272 return LIBUSB_ERROR_INVALID_PARAM;
3275 if (tmp_size < *size) {
3279 ((uint8_t*)data)[0] = (uint8_t)*size;
3280 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3281 memcpy((uint8_t*)data+2, tmp, *size-2);
3282 return LIBUSB_COMPLETED;
3285 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3287 struct libusb_hid_descriptor d;
3288 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3289 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3291 _hid_get_report_descriptor(dev, tmp, &report_len);
3293 d.bLength = LIBUSB_DT_HID_SIZE;
3294 d.bDescriptorType = LIBUSB_DT_HID;
3295 d.bcdHID = 0x0110; /* 1.10 */
3297 d.bNumDescriptors = 1;
3298 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3299 d.wClassDescriptorLength = (uint16_t)report_len;
3301 if (*size > LIBUSB_DT_HID_SIZE)
3302 *size = LIBUSB_DT_HID_SIZE;
3303 memcpy(data, &d, *size);
3304 return LIBUSB_COMPLETED;
3307 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3309 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3312 /* usage page (0xFFA0 == vendor defined) */
3313 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3314 /* usage (vendor defined) */
3315 d[i++] = 0x09; d[i++] = 0x01;
3316 /* start collection (application) */
3317 d[i++] = 0xA1; d[i++] = 0x01;
3319 if (dev->input_report_size) {
3320 /* usage (vendor defined) */
3321 d[i++] = 0x09; d[i++] = 0x01;
3322 /* logical minimum (0) */
3323 d[i++] = 0x15; d[i++] = 0x00;
3324 /* logical maximum (255) */
3325 d[i++] = 0x25; d[i++] = 0xFF;
3326 /* report size (8 bits) */
3327 d[i++] = 0x75; d[i++] = 0x08;
3329 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3330 /* input (data, variable, absolute) */
3331 d[i++] = 0x81; d[i++] = 0x00;
3334 if (dev->output_report_size) {
3335 /* usage (vendor defined) */
3336 d[i++] = 0x09; d[i++] = 0x02;
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->output_report_size - 1;
3345 /* output (data, variable, absolute) */
3346 d[i++] = 0x91; d[i++] = 0x00;
3348 /* feature report */
3349 if (dev->feature_report_size) {
3350 /* usage (vendor defined) */
3351 d[i++] = 0x09; d[i++] = 0x03;
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->feature_report_size - 1;
3360 /* feature (data, variable, absolute) */
3361 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3364 /* end collection */
3369 memcpy(data, d, *size);
3370 return LIBUSB_COMPLETED;
3373 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3374 int type, int _index, void *data, size_t *size)
3377 case LIBUSB_DT_DEVICE:
3378 usbi_dbg("LIBUSB_DT_DEVICE");
3379 return _hid_get_device_descriptor(dev, data, size);
3380 case LIBUSB_DT_CONFIG:
3381 usbi_dbg("LIBUSB_DT_CONFIG");
3383 return _hid_get_config_descriptor(dev, data, size);
3384 return LIBUSB_ERROR_INVALID_PARAM;
3385 case LIBUSB_DT_STRING:
3386 usbi_dbg("LIBUSB_DT_STRING");
3387 return _hid_get_string_descriptor(dev, _index, data, size);
3389 usbi_dbg("LIBUSB_DT_HID");
3391 return _hid_get_hid_descriptor(dev, data, size);
3392 return LIBUSB_ERROR_INVALID_PARAM;
3393 case LIBUSB_DT_REPORT:
3394 usbi_dbg("LIBUSB_DT_REPORT");
3396 return _hid_get_report_descriptor(dev, data, size);
3397 return LIBUSB_ERROR_INVALID_PARAM;
3398 case LIBUSB_DT_PHYSICAL:
3399 usbi_dbg("LIBUSB_DT_PHYSICAL");
3400 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3401 return LIBUSB_COMPLETED;
3402 return LIBUSB_ERROR_OTHER;
3404 usbi_dbg("unsupported");
3405 return LIBUSB_ERROR_INVALID_PARAM;
3408 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3409 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3413 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3414 int r = LIBUSB_SUCCESS;
3416 if (tp->hid_buffer != NULL) {
3417 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3420 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3421 usbi_dbg("invalid size (%d)", *size);
3422 return LIBUSB_ERROR_INVALID_PARAM;
3425 switch (report_type) {
3426 case HID_REPORT_TYPE_INPUT:
3427 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3429 case HID_REPORT_TYPE_FEATURE:
3430 ioctl_code = IOCTL_HID_GET_FEATURE;
3433 usbi_dbg("unknown HID report type %d", report_type);
3434 return LIBUSB_ERROR_INVALID_PARAM;
3437 // Add a trailing byte to detect overflows
3438 buf = (uint8_t*)calloc(expected_size+1, 1);
3440 return LIBUSB_ERROR_NO_MEM;
3442 buf[0] = (uint8_t)id; // Must be set always
3443 usbi_dbg("report ID: 0x%02X", buf[0]);
3445 tp->hid_expected_size = expected_size;
3446 read_size = expected_size;
3448 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3449 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3450 buf, expected_size+1, &read_size, overlapped)) {
3451 if (GetLastError() != ERROR_IO_PENDING) {
3452 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3454 return LIBUSB_ERROR_IO;
3456 // Asynchronous wait
3457 tp->hid_buffer = buf;
3458 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3459 return LIBUSB_SUCCESS;
3462 // Transfer completed synchronously => copy and discard extra buffer
3463 if (read_size == 0) {
3464 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3468 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3470 if ((size_t)read_size > expected_size) {
3471 r = LIBUSB_ERROR_OVERFLOW;
3472 usbi_dbg("OVERFLOW!");
3474 r = LIBUSB_COMPLETED;
3477 *size = MIN((size_t)read_size, *size);
3479 // Discard report ID
3480 memcpy(data, buf+1, *size);
3482 memcpy(data, buf, *size);
3489 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3490 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3493 uint8_t *buf = NULL;
3494 DWORD ioctl_code, write_size= (DWORD)*size;
3496 if (tp->hid_buffer != NULL) {
3497 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3500 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3501 usbi_dbg("invalid size (%d)", *size);
3502 return LIBUSB_ERROR_INVALID_PARAM;
3505 switch (report_type) {
3506 case HID_REPORT_TYPE_OUTPUT:
3507 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3509 case HID_REPORT_TYPE_FEATURE:
3510 ioctl_code = IOCTL_HID_SET_FEATURE;
3513 usbi_dbg("unknown HID report type %d", report_type);
3514 return LIBUSB_ERROR_INVALID_PARAM;
3517 usbi_dbg("report ID: 0x%02X", id);
3518 // When report IDs are not used (i.e. when id == 0), we must add
3519 // a null report ID. Otherwise, we just use original data buffer
3523 buf = (uint8_t*) malloc(write_size);
3525 return LIBUSB_ERROR_NO_MEM;
3529 memcpy(buf + 1, data, *size);
3531 // This seems like a waste, but if we don't duplicate the
3532 // data, we'll get issues when freeing hid_buffer
3533 memcpy(buf, data, *size);
3535 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3539 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3540 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3541 buf, write_size, &write_size, overlapped)) {
3542 if (GetLastError() != ERROR_IO_PENDING) {
3543 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3545 return LIBUSB_ERROR_IO;
3547 tp->hid_buffer = buf;
3548 tp->hid_dest = NULL;
3549 return LIBUSB_SUCCESS;
3552 // Transfer completed synchronously
3554 if (write_size == 0) {
3555 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3558 return LIBUSB_COMPLETED;
3561 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3562 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3563 size_t *size, OVERLAPPED* overlapped)
3565 int report_type = (value >> 8) & 0xFF;
3566 int report_id = value & 0xFF;
3568 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3569 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3570 return LIBUSB_ERROR_INVALID_PARAM;
3572 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3573 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3575 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3576 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3578 return LIBUSB_ERROR_INVALID_PARAM;
3585 static int hid_init(int sub_api, struct libusb_context *ctx)
3587 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3588 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3589 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3590 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3591 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3592 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3593 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3594 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3595 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3596 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3597 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3598 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3599 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3600 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3601 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3602 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3604 api_hid_available = true;
3605 return LIBUSB_SUCCESS;
3608 static int hid_exit(int sub_api)
3610 return LIBUSB_SUCCESS;
3613 // NB: open and close must ensure that they only handle interface of
3614 // the right API type, as these functions can be called wholesale from
3615 // composite_open(), with interfaces belonging to different APIs
3616 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3618 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3619 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3620 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3622 HIDD_ATTRIBUTES hid_attributes;
3623 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3624 HIDP_CAPS capabilities;
3625 HIDP_VALUE_CAPS *value_caps;
3627 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3629 // report IDs handling
3631 char* type[3] = {"input", "output", "feature"};
3632 int nb_ids[2]; // zero and nonzero report IDs
3634 CHECK_HID_AVAILABLE;
3635 if (priv->hid == NULL) {
3636 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3637 return LIBUSB_ERROR_NOT_FOUND;
3640 for (i = 0; i < USB_MAXINTERFACES; i++) {
3641 if ( (priv->usb_interface[i].path != NULL)
3642 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3643 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3644 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3646 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3647 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3648 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3649 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3650 * HidD_GetFeature (if the device supports Feature reports)."
3652 if (hid_handle == INVALID_HANDLE_VALUE) {
3653 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3654 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3655 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3656 if (hid_handle == INVALID_HANDLE_VALUE) {
3657 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3658 switch(GetLastError()) {
3659 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3660 return LIBUSB_ERROR_NO_DEVICE;
3661 case ERROR_ACCESS_DENIED:
3662 return LIBUSB_ERROR_ACCESS;
3664 return LIBUSB_ERROR_IO;
3667 priv->usb_interface[i].restricted_functionality = true;
3669 handle_priv->interface_handle[i].api_handle = hid_handle;
3673 hid_attributes.Size = sizeof(hid_attributes);
3675 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3676 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3680 priv->hid->vid = hid_attributes.VendorID;
3681 priv->hid->pid = hid_attributes.ProductID;
3683 // Set the maximum available input buffer size
3684 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3685 usbi_dbg("set maximum input buffer size to %d", i/2);
3687 // Get the maximum input and output report size
3688 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3689 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3692 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3693 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3697 // Find out if interrupt will need report IDs
3698 size[0] = capabilities.NumberInputValueCaps;
3699 size[1] = capabilities.NumberOutputValueCaps;
3700 size[2] = capabilities.NumberFeatureValueCaps;
3701 for (j=HidP_Input; j<=HidP_Feature; j++) {
3702 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3703 priv->hid->uses_report_ids[j] = false;
3705 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3706 if ( (value_caps != NULL)
3707 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3708 && (size[j] >= 1) ) {
3711 for (i=0; i<(int)size[j]; i++) {
3712 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3713 if (value_caps[i].ReportID != 0) {
3719 if (nb_ids[1] != 0) {
3720 if (nb_ids[0] != 0) {
3721 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3724 priv->hid->uses_report_ids[j] = true;
3727 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3729 safe_free(value_caps);
3733 // Set the report sizes
3734 priv->hid->input_report_size = capabilities.InputReportByteLength;
3735 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3736 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3738 // Fetch string descriptors
3739 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3740 if (priv->hid->string_index[0] != 0) {
3741 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3742 sizeof(priv->hid->string[0]));
3744 priv->hid->string[0][0] = 0;
3746 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3747 if (priv->hid->string_index[1] != 0) {
3748 HidD_GetProductString(hid_handle, priv->hid->string[1],
3749 sizeof(priv->hid->string[1]));
3751 priv->hid->string[1][0] = 0;
3753 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3754 if (priv->hid->string_index[2] != 0) {
3755 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3756 sizeof(priv->hid->string[2]));
3758 priv->hid->string[2][0] = 0;
3762 if (preparsed_data) {
3763 HidD_FreePreparsedData(preparsed_data);
3766 return LIBUSB_SUCCESS;
3769 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3771 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3772 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3776 if (!api_hid_available)
3779 for (i = 0; i < USB_MAXINTERFACES; i++) {
3780 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3781 file_handle = handle_priv->interface_handle[i].api_handle;
3782 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3783 CloseHandle(file_handle);
3789 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3791 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3792 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3794 CHECK_HID_AVAILABLE;
3796 // NB: Disconnection detection is not possible in this function
3797 if (priv->usb_interface[iface].path == NULL) {
3798 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3801 // We use dev_handle as a flag for interface claimed
3802 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3803 return LIBUSB_ERROR_BUSY; // already claimed
3806 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3808 usbi_dbg("claimed interface %d", iface);
3809 handle_priv->active_interface = iface;
3811 return LIBUSB_SUCCESS;
3814 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3816 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3817 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3819 CHECK_HID_AVAILABLE;
3821 if (priv->usb_interface[iface].path == NULL) {
3822 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3825 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3826 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3829 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3831 return LIBUSB_SUCCESS;
3834 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3836 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3838 CHECK_HID_AVAILABLE;
3840 if (altsetting > 255) {
3841 return LIBUSB_ERROR_INVALID_PARAM;
3844 if (altsetting != 0) {
3845 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3846 return LIBUSB_ERROR_NOT_SUPPORTED;
3849 return LIBUSB_SUCCESS;
3852 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3854 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3855 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3856 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3857 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3858 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3859 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3862 int current_interface, config;
3864 int r = LIBUSB_ERROR_INVALID_PARAM;
3866 CHECK_HID_AVAILABLE;
3868 transfer_priv->pollable_fd = INVALID_WINFD;
3869 safe_free(transfer_priv->hid_buffer);
3870 transfer_priv->hid_dest = NULL;
3871 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3873 if (size > MAX_CTRL_BUFFER_LENGTH) {
3874 return LIBUSB_ERROR_INVALID_PARAM;
3877 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3878 if (current_interface < 0) {
3879 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3880 return LIBUSB_ERROR_NOT_FOUND;
3884 usbi_dbg("will use interface %d", current_interface);
3885 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3886 // Always use the handle returned from usbi_create_fd (wfd.handle)
3887 wfd = usbi_create_fd(hid_handle, _O_RDONLY);
3889 return LIBUSB_ERROR_NO_MEM;
3892 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3893 case LIBUSB_REQUEST_TYPE_STANDARD:
3894 switch(setup->request) {
3895 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3896 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3897 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3899 case LIBUSB_REQUEST_GET_CONFIGURATION:
3900 r = windows_get_configuration(transfer->dev_handle, &config);
3901 if (r == LIBUSB_SUCCESS) {
3903 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3904 r = LIBUSB_COMPLETED;
3907 case LIBUSB_REQUEST_SET_CONFIGURATION:
3908 if (setup->value == priv->active_config) {
3909 r = LIBUSB_COMPLETED;
3911 usbi_warn(ctx, "cannot set configuration other than the default one");
3912 r = LIBUSB_ERROR_INVALID_PARAM;
3915 case LIBUSB_REQUEST_GET_INTERFACE:
3917 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3918 r = LIBUSB_COMPLETED;
3920 case LIBUSB_REQUEST_SET_INTERFACE:
3921 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3922 if (r == LIBUSB_SUCCESS) {
3923 r = LIBUSB_COMPLETED;
3927 usbi_warn(ctx, "unsupported HID control request");
3928 r = LIBUSB_ERROR_INVALID_PARAM;
3932 case LIBUSB_REQUEST_TYPE_CLASS:
3933 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3934 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3935 &size, wfd.overlapped);
3938 usbi_warn(ctx, "unsupported HID control request");
3939 r = LIBUSB_ERROR_INVALID_PARAM;
3943 if (r == LIBUSB_COMPLETED) {
3944 // Force request to be completed synchronously. Transferred size has been set by previous call
3945 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3946 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3947 // set InternalHigh to the number of bytes transferred
3948 wfd.overlapped->InternalHigh = (DWORD)size;
3952 if (r == LIBUSB_SUCCESS) {
3953 // Use priv_transfer to store data needed for async polling
3954 transfer_priv->pollable_fd = wfd;
3955 transfer_priv->interface_number = (uint8_t)current_interface;
3957 usbi_free_fd(wfd.fd);
3963 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3964 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3965 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3966 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3967 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3968 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3971 bool direction_in, ret;
3972 int current_interface, length;
3974 int r = LIBUSB_SUCCESS;
3976 CHECK_HID_AVAILABLE;
3978 transfer_priv->pollable_fd = INVALID_WINFD;
3979 transfer_priv->hid_dest = NULL;
3980 safe_free(transfer_priv->hid_buffer);
3982 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3983 if (current_interface < 0) {
3984 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3985 return LIBUSB_ERROR_NOT_FOUND;
3988 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3990 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3991 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
3993 wfd = usbi_create_fd(hid_handle, direction_in?_O_RDONLY:_O_WRONLY);
3994 // Always use the handle returned from usbi_create_fd (wfd.handle)
3996 return LIBUSB_ERROR_NO_MEM;
3999 // If report IDs are not in use, an extra prefix byte must be added
4000 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4001 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4002 length = transfer->length+1;
4004 length = transfer->length;
4006 // Add a trailing byte to detect overflows on input
4007 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4008 if (transfer_priv->hid_buffer == NULL) {
4009 return LIBUSB_ERROR_NO_MEM;
4011 transfer_priv->hid_expected_size = length;
4014 transfer_priv->hid_dest = transfer->buffer;
4015 usbi_dbg("reading %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4016 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4018 if (!priv->hid->uses_report_ids[1]) {
4019 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4021 // We could actually do without the calloc and memcpy in this case
4022 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4024 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4025 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4028 if (GetLastError() != ERROR_IO_PENDING) {
4029 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4030 usbi_free_fd(wfd.fd);
4031 safe_free(transfer_priv->hid_buffer);
4032 return LIBUSB_ERROR_IO;
4035 // Only write operations that completed synchronously need to free up
4036 // hid_buffer. For reads, copy_transfer_data() handles that process.
4037 if (!direction_in) {
4038 safe_free(transfer_priv->hid_buffer);
4041 usbi_err(ctx, "program assertion failed - no data was transferred");
4044 if (size > (size_t)length) {
4045 usbi_err(ctx, "OVERFLOW!");
4046 r = LIBUSB_ERROR_OVERFLOW;
4048 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4049 wfd.overlapped->InternalHigh = size;
4052 transfer_priv->pollable_fd = wfd;
4053 transfer_priv->interface_number = (uint8_t)current_interface;
4058 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4060 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4061 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4062 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4064 int current_interface;
4066 CHECK_HID_AVAILABLE;
4068 current_interface = transfer_priv->interface_number;
4069 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4070 CancelIo(hid_handle);
4072 return LIBUSB_SUCCESS;
4075 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4077 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4079 int current_interface;
4081 CHECK_HID_AVAILABLE;
4083 // Flushing the queues on all interfaces is the best we can achieve
4084 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4085 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4086 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4087 HidD_FlushQueue(hid_handle);
4090 return LIBUSB_SUCCESS;
4093 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4095 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4096 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4097 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4099 int current_interface;
4101 CHECK_HID_AVAILABLE;
4103 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4104 if (current_interface < 0) {
4105 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4106 return LIBUSB_ERROR_NOT_FOUND;
4109 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4110 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4112 // No endpoint selection with Microsoft's implementation, so we try to flush the
4113 // whole interface. Should be OK for most case scenarios
4114 if (!HidD_FlushQueue(hid_handle)) {
4115 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4116 // Device was probably disconnected
4117 return LIBUSB_ERROR_NO_DEVICE;
4120 return LIBUSB_SUCCESS;
4123 // This extra function is only needed for HID
4124 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4125 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4126 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4127 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4128 int r = LIBUSB_TRANSFER_COMPLETED;
4129 uint32_t corrected_size = io_size;
4131 if (transfer_priv->hid_buffer != NULL) {
4132 // If we have a valid hid_buffer, it means the transfer was async
4133 if (transfer_priv->hid_dest != NULL) { // Data readout
4134 // First, check for overflow
4135 if (corrected_size > transfer_priv->hid_expected_size) {
4136 usbi_err(ctx, "OVERFLOW!");
4137 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4138 r = LIBUSB_TRANSFER_OVERFLOW;
4141 if (transfer_priv->hid_buffer[0] == 0) {
4142 // Discard the 1 byte report ID prefix
4144 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4146 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4148 transfer_priv->hid_dest = NULL;
4150 // For write, we just need to free the hid buffer
4151 safe_free(transfer_priv->hid_buffer);
4153 itransfer->transferred += corrected_size;
4159 * Composite API functions
4161 static int composite_init(int sub_api, struct libusb_context *ctx)
4163 return LIBUSB_SUCCESS;
4166 static int composite_exit(int sub_api)
4168 return LIBUSB_SUCCESS;
4171 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4173 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4176 bool available[SUB_API_MAX];
4178 for (i = 0; i<SUB_API_MAX; i++) {
4179 available[i] = false;
4182 for (i=0; i<USB_MAXINTERFACES; i++) {
4183 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4184 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4185 available[priv->usb_interface[i].sub_api] = true;
4189 for (i=0; i<SUB_API_MAX; i++) {
4191 r = usb_api_backend[USB_API_WINUSBX].open(SUB_API_NOTSET, dev_handle);
4192 if (r != LIBUSB_SUCCESS) {
4197 return LIBUSB_SUCCESS;
4200 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4202 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4204 bool available[SUB_API_MAX];
4206 for (i = 0; i<SUB_API_MAX; i++) {
4207 available[i] = false;
4210 for (i=0; i<USB_MAXINTERFACES; i++) {
4211 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4212 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4213 available[priv->usb_interface[i].sub_api] = true;
4217 for (i=0; i<SUB_API_MAX; i++) {
4219 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4224 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4226 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4227 return priv->usb_interface[iface].apib->
4228 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4231 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4233 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4234 return priv->usb_interface[iface].apib->
4235 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4238 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4240 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4241 return priv->usb_interface[iface].apib->
4242 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4245 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4247 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4248 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4249 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4252 // Interface shouldn't matter for control, but it does in practice, with Windows'
4253 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4254 for (pass = 0; pass < 2; pass++) {
4255 for (i=0; i<USB_MAXINTERFACES; i++) {
4256 if (priv->usb_interface[i].path != NULL) {
4257 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4258 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4261 usbi_dbg("using interface %d", i);
4262 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4267 usbi_err(ctx, "no libusbx supported interfaces to complete request");
4268 return LIBUSB_ERROR_NOT_FOUND;
4271 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4272 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4273 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4274 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4275 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4276 int current_interface;
4278 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4279 if (current_interface < 0) {
4280 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4281 return LIBUSB_ERROR_NOT_FOUND;
4284 return priv->usb_interface[current_interface].apib->
4285 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4287 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4288 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4289 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4290 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4291 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4292 int current_interface;
4294 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4295 if (current_interface < 0) {
4296 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4297 return LIBUSB_ERROR_NOT_FOUND;
4300 return priv->usb_interface[current_interface].apib->
4301 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4303 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4305 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4306 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4307 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4308 int current_interface;
4310 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4311 if (current_interface < 0) {
4312 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4313 return LIBUSB_ERROR_NOT_FOUND;
4316 return priv->usb_interface[current_interface].apib->
4317 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4319 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4321 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4322 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4323 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4325 return priv->usb_interface[transfer_priv->interface_number].apib->
4326 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4328 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4330 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4331 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4332 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4334 return priv->usb_interface[transfer_priv->interface_number].apib->
4335 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4337 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4339 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4342 bool available[SUB_API_MAX];
4343 for (i = 0; i<SUB_API_MAX; i++) {
4344 available[i] = false;
4346 for (i=0; i<USB_MAXINTERFACES; i++) {
4347 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4348 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4349 available[priv->usb_interface[i].sub_api] = true;
4352 for (i=0; i<SUB_API_MAX; i++) {
4354 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4355 if (r != LIBUSB_SUCCESS) {
4360 return LIBUSB_SUCCESS;
4363 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4365 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4366 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4367 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4369 return priv->usb_interface[transfer_priv->interface_number].apib->
4370 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);