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 (!WinUSBX[sub_api].initialized)
2600 for (i = 0; i < USB_MAXINTERFACES; i++) {
2601 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2602 file_handle = handle_priv->interface_handle[i].dev_handle;
2603 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2604 CloseHandle(file_handle);
2610 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2612 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2613 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2614 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2617 uint8_t endpoint_address;
2620 CHECK_WINUSBX_AVAILABLE(sub_api);
2622 // With handle and enpoints set (in parent), we can setup the default pipe properties
2623 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2624 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2625 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2626 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2627 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2628 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2630 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2631 continue; // Other policies don't apply to control endpoint or libusb0
2634 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2635 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2636 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2638 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2639 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2640 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2642 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2643 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2644 usbi_dbg("failed to disable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2647 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2648 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2649 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2653 return LIBUSB_SUCCESS;
2656 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2658 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2659 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2660 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2661 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2662 HANDLE file_handle, winusb_handle;
2664 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2666 SP_DEVINFO_DATA dev_info_data;
2667 char* dev_path_no_guid = NULL;
2668 char filter_path[] = "\\\\.\\libusb0-0000";
2669 bool found_filter = false;
2671 CHECK_WINUSBX_AVAILABLE(sub_api);
2673 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2674 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2675 if ((is_using_usbccgp) || (iface == 0)) {
2676 // composite device (independent interfaces) or interface 0
2677 file_handle = handle_priv->interface_handle[iface].dev_handle;
2678 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2679 return LIBUSB_ERROR_NOT_FOUND;
2682 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2683 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2685 switch(GetLastError()) {
2686 case ERROR_BAD_COMMAND:
2687 // The device was disconnected
2688 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2689 return LIBUSB_ERROR_NO_DEVICE;
2691 // it may be that we're using the libusb0 filter driver.
2692 // [TODO] can we move this whole business into the K/0 DLL?
2693 for (i = 0; ; i++) {
2694 safe_free(dev_interface_details);
2695 safe_free(dev_path_no_guid);
2696 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2697 if ((found_filter) || (dev_interface_details == NULL)) {
2701 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2702 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2703 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2704 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2705 if (file_handle == INVALID_HANDLE_VALUE) {
2706 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2708 WinUSBX[sub_api].Free(winusb_handle);
2709 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2712 found_filter = true;
2717 if (!found_filter) {
2718 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2719 return LIBUSB_ERROR_ACCESS;
2723 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2725 // For all other interfaces, use GetAssociatedInterface()
2726 winusb_handle = handle_priv->interface_handle[0].api_handle;
2727 // It is a requirement for multiple interface devices on Windows that, to you
2728 // must first claim the first interface before you claim the others
2729 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2730 file_handle = handle_priv->interface_handle[0].dev_handle;
2731 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2732 handle_priv->interface_handle[0].api_handle = winusb_handle;
2733 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2735 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB)", iface);
2736 return LIBUSB_ERROR_ACCESS;
2739 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2740 &handle_priv->interface_handle[iface].api_handle)) {
2741 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2742 switch(GetLastError()) {
2743 case ERROR_NO_MORE_ITEMS: // invalid iface
2744 return LIBUSB_ERROR_NOT_FOUND;
2745 case ERROR_BAD_COMMAND: // The device was disconnected
2746 return LIBUSB_ERROR_NO_DEVICE;
2747 case ERROR_ALREADY_EXISTS: // already claimed
2748 return LIBUSB_ERROR_BUSY;
2750 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2751 return LIBUSB_ERROR_ACCESS;
2755 usbi_dbg("claimed interface %d", iface);
2756 handle_priv->active_interface = iface;
2758 return LIBUSB_SUCCESS;
2761 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2763 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2764 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2765 HANDLE winusb_handle;
2767 CHECK_WINUSBX_AVAILABLE(sub_api);
2769 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2770 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2771 return LIBUSB_ERROR_NOT_FOUND;
2774 WinUSBX[sub_api].Free(winusb_handle);
2775 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2777 return LIBUSB_SUCCESS;
2781 * Return the first valid interface (of the same API type), for control transfers
2783 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2785 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2786 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2789 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2790 usbi_dbg("unsupported API ID");
2794 for (i=0; i<USB_MAXINTERFACES; i++) {
2795 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2796 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2797 && (handle_priv->interface_handle[i].api_handle != 0)
2798 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2799 && (priv->usb_interface[i].apib->id == api_id) ) {
2807 * Lookup interface by endpoint address. -1 if not found
2809 static int interface_by_endpoint(struct windows_device_priv *priv,
2810 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2813 for (i=0; i<USB_MAXINTERFACES; i++) {
2814 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2816 if (handle_priv->interface_handle[i].api_handle == 0)
2818 if (priv->usb_interface[i].endpoint == NULL)
2820 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2821 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2829 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2831 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2832 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2833 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2834 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2835 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2836 transfer->dev_handle);
2837 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2839 HANDLE winusb_handle;
2840 int current_interface;
2843 CHECK_WINUSBX_AVAILABLE(sub_api);
2845 transfer_priv->pollable_fd = INVALID_WINFD;
2846 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2848 if (size > MAX_CTRL_BUFFER_LENGTH)
2849 return LIBUSB_ERROR_INVALID_PARAM;
2851 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2852 if (current_interface < 0) {
2853 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2854 return LIBUSB_ERROR_NOT_FOUND;
2858 usbi_dbg("will use interface %d", current_interface);
2859 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2861 wfd = usbi_create_fd(winusb_handle, _O_RDONLY);
2862 // Always use the handle returned from usbi_create_fd (wfd.handle)
2864 return LIBUSB_ERROR_NO_MEM;
2867 // Sending of set configuration control requests from WinUSB creates issues
2868 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2869 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2870 if (setup->value != priv->active_config) {
2871 usbi_warn(ctx, "cannot set configuration other than the default one");
2872 usbi_free_fd(wfd.fd);
2873 return LIBUSB_ERROR_INVALID_PARAM;
2875 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2876 wfd.overlapped->InternalHigh = 0;
2878 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2879 if(GetLastError() != ERROR_IO_PENDING) {
2880 usbi_err(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2881 usbi_free_fd(wfd.fd);
2882 return LIBUSB_ERROR_IO;
2885 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2886 wfd.overlapped->InternalHigh = (DWORD)size;
2890 // Use priv_transfer to store data needed for async polling
2891 transfer_priv->pollable_fd = wfd;
2892 transfer_priv->interface_number = (uint8_t)current_interface;
2894 return LIBUSB_SUCCESS;
2897 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2899 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2900 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2901 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2902 HANDLE winusb_handle;
2904 CHECK_WINUSBX_AVAILABLE(sub_api);
2906 if (altsetting > 255) {
2907 return LIBUSB_ERROR_INVALID_PARAM;
2910 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2911 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2912 usbi_err(ctx, "interface must be claimed first");
2913 return LIBUSB_ERROR_NOT_FOUND;
2916 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2917 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2918 return LIBUSB_ERROR_IO;
2921 return LIBUSB_SUCCESS;
2924 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2926 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2927 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2928 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2929 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2930 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2931 HANDLE winusb_handle;
2933 int current_interface;
2936 CHECK_WINUSBX_AVAILABLE(sub_api);
2938 transfer_priv->pollable_fd = INVALID_WINFD;
2940 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2941 if (current_interface < 0) {
2942 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2943 return LIBUSB_ERROR_NOT_FOUND;
2946 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2948 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2950 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? _O_RDONLY : _O_WRONLY);
2951 // Always use the handle returned from usbi_create_fd (wfd.handle)
2953 return LIBUSB_ERROR_NO_MEM;
2956 if (IS_XFERIN(transfer)) {
2957 usbi_dbg("reading %d bytes", transfer->length);
2958 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2960 usbi_dbg("writing %d bytes", transfer->length);
2961 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2964 if(GetLastError() != ERROR_IO_PENDING) {
2965 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2966 usbi_free_fd(wfd.fd);
2967 return LIBUSB_ERROR_IO;
2970 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2971 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
2974 transfer_priv->pollable_fd = wfd;
2975 transfer_priv->interface_number = (uint8_t)current_interface;
2977 return LIBUSB_SUCCESS;
2980 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
2982 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2983 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2984 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2985 HANDLE winusb_handle;
2986 int current_interface;
2988 CHECK_WINUSBX_AVAILABLE(sub_api);
2990 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
2991 if (current_interface < 0) {
2992 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
2993 return LIBUSB_ERROR_NOT_FOUND;
2996 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
2997 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2999 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3000 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3001 return LIBUSB_ERROR_NO_DEVICE;
3004 return LIBUSB_SUCCESS;
3008 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3009 * through testing as well):
3010 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3011 * the control transfer using CancelIo"
3013 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3015 // Cancelling of the I/O is done in the parent
3016 return LIBUSB_SUCCESS;
3019 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3021 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3022 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3023 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3024 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3025 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3026 HANDLE winusb_handle;
3027 int current_interface;
3029 CHECK_WINUSBX_AVAILABLE(sub_api);
3031 current_interface = transfer_priv->interface_number;
3032 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3033 usbi_err(ctx, "program assertion failed: invalid interface_number");
3034 return LIBUSB_ERROR_NOT_FOUND;
3036 usbi_dbg("will use interface %d", current_interface);
3038 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3040 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3041 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3042 return LIBUSB_ERROR_NO_DEVICE;
3045 return LIBUSB_SUCCESS;
3049 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3050 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3051 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3052 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3053 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3054 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3056 // TODO (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3057 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3059 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3060 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3061 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3063 HANDLE winusb_handle;
3066 CHECK_WINUSBX_AVAILABLE(sub_api);
3068 // Reset any available pipe (except control)
3069 for (i=0; i<USB_MAXINTERFACES; i++) {
3070 winusb_handle = handle_priv->interface_handle[i].api_handle;
3071 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3073 // Cancel any pollable I/O
3074 usbi_remove_pollfd(ctx, wfd.fd);
3075 usbi_free_fd(wfd.fd);
3076 wfd = handle_to_winfd(winusb_handle);
3079 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3080 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3081 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3082 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3083 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3084 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3086 // FlushPipe seems to fail on OUT pipes
3087 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3088 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3089 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3090 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3092 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3093 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3094 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3100 // libusbK & libusb0 have the ability to issue an actual device reset
3101 if (WinUSBX[sub_api].ResetDevice != NULL) {
3102 winusb_handle = handle_priv->interface_handle[0].api_handle;
3103 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3104 WinUSBX[sub_api].ResetDevice(winusb_handle);
3107 return LIBUSB_SUCCESS;
3110 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3112 itransfer->transferred += io_size;
3113 return LIBUSB_TRANSFER_COMPLETED;
3117 * Internal HID Support functions (from libusb-win32)
3118 * Note that functions that complete data transfer synchronously must return
3119 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3121 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3122 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3124 static int _hid_wcslen(WCHAR *str)
3127 while (str[i] && (str[i] != 0x409)) {
3133 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3135 struct libusb_device_descriptor d;
3137 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3138 d.bDescriptorType = LIBUSB_DT_DEVICE;
3139 d.bcdUSB = 0x0200; /* 2.00 */
3141 d.bDeviceSubClass = 0;
3142 d.bDeviceProtocol = 0;
3143 d.bMaxPacketSize0 = 64; /* fix this! */
3144 d.idVendor = (uint16_t)dev->vid;
3145 d.idProduct = (uint16_t)dev->pid;
3146 d.bcdDevice = 0x0100;
3147 d.iManufacturer = dev->string_index[0];
3148 d.iProduct = dev->string_index[1];
3149 d.iSerialNumber = dev->string_index[2];
3150 d.bNumConfigurations = 1;
3152 if (*size > LIBUSB_DT_DEVICE_SIZE)
3153 *size = LIBUSB_DT_DEVICE_SIZE;
3154 memcpy(data, &d, *size);
3155 return LIBUSB_COMPLETED;
3158 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3160 char num_endpoints = 0;
3161 size_t config_total_len = 0;
3162 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3163 struct libusb_config_descriptor *cd;
3164 struct libusb_interface_descriptor *id;
3165 struct libusb_hid_descriptor *hd;
3166 struct libusb_endpoint_descriptor *ed;
3169 if (dev->input_report_size)
3171 if (dev->output_report_size)
3174 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3175 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3178 cd = (struct libusb_config_descriptor *)tmp;
3179 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3180 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3181 + LIBUSB_DT_INTERFACE_SIZE);
3182 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3183 + LIBUSB_DT_INTERFACE_SIZE
3184 + LIBUSB_DT_HID_SIZE);
3186 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3187 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3188 cd->wTotalLength = (uint16_t) config_total_len;
3189 cd->bNumInterfaces = 1;
3190 cd->bConfigurationValue = 1;
3191 cd->iConfiguration = 0;
3192 cd->bmAttributes = 1 << 7; /* bus powered */
3195 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3196 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3197 id->bInterfaceNumber = 0;
3198 id->bAlternateSetting = 0;
3199 id->bNumEndpoints = num_endpoints;
3200 id->bInterfaceClass = 3;
3201 id->bInterfaceSubClass = 0;
3202 id->bInterfaceProtocol = 0;
3205 tmp_size = LIBUSB_DT_HID_SIZE;
3206 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3208 if (dev->input_report_size) {
3209 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3210 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3211 ed->bEndpointAddress = HID_IN_EP;
3212 ed->bmAttributes = 3;
3213 ed->wMaxPacketSize = dev->input_report_size - 1;
3219 if (dev->output_report_size) {
3220 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3221 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3222 ed->bEndpointAddress = HID_OUT_EP;
3223 ed->bmAttributes = 3;
3224 ed->wMaxPacketSize = dev->output_report_size - 1;
3228 if (*size > config_total_len)
3229 *size = config_total_len;
3230 memcpy(data, tmp, *size);
3231 return LIBUSB_COMPLETED;
3234 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3235 void *data, size_t *size)
3238 size_t tmp_size = 0;
3241 /* language ID, EN-US */
3242 char string_langid[] = {
3247 if ((*size < 2) || (*size > 255)) {
3248 return LIBUSB_ERROR_OVERFLOW;
3252 tmp = string_langid;
3253 tmp_size = sizeof(string_langid)+2;
3255 for (i=0; i<3; i++) {
3256 if (_index == (dev->string_index[i])) {
3257 tmp = dev->string[i];
3258 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3262 if (i == 3) { // not found
3263 return LIBUSB_ERROR_INVALID_PARAM;
3268 return LIBUSB_ERROR_INVALID_PARAM;
3271 if (tmp_size < *size) {
3275 ((uint8_t*)data)[0] = (uint8_t)*size;
3276 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3277 memcpy((uint8_t*)data+2, tmp, *size-2);
3278 return LIBUSB_COMPLETED;
3281 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3283 struct libusb_hid_descriptor d;
3284 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3285 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3287 _hid_get_report_descriptor(dev, tmp, &report_len);
3289 d.bLength = LIBUSB_DT_HID_SIZE;
3290 d.bDescriptorType = LIBUSB_DT_HID;
3291 d.bcdHID = 0x0110; /* 1.10 */
3293 d.bNumDescriptors = 1;
3294 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3295 d.wClassDescriptorLength = (uint16_t)report_len;
3297 if (*size > LIBUSB_DT_HID_SIZE)
3298 *size = LIBUSB_DT_HID_SIZE;
3299 memcpy(data, &d, *size);
3300 return LIBUSB_COMPLETED;
3303 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3305 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3308 /* usage page (0xFFA0 == vendor defined) */
3309 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3310 /* usage (vendor defined) */
3311 d[i++] = 0x09; d[i++] = 0x01;
3312 /* start collection (application) */
3313 d[i++] = 0xA1; d[i++] = 0x01;
3315 if (dev->input_report_size) {
3316 /* usage (vendor defined) */
3317 d[i++] = 0x09; d[i++] = 0x01;
3318 /* logical minimum (0) */
3319 d[i++] = 0x15; d[i++] = 0x00;
3320 /* logical maximum (255) */
3321 d[i++] = 0x25; d[i++] = 0xFF;
3322 /* report size (8 bits) */
3323 d[i++] = 0x75; d[i++] = 0x08;
3325 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3326 /* input (data, variable, absolute) */
3327 d[i++] = 0x81; d[i++] = 0x00;
3330 if (dev->output_report_size) {
3331 /* usage (vendor defined) */
3332 d[i++] = 0x09; d[i++] = 0x02;
3333 /* logical minimum (0) */
3334 d[i++] = 0x15; d[i++] = 0x00;
3335 /* logical maximum (255) */
3336 d[i++] = 0x25; d[i++] = 0xFF;
3337 /* report size (8 bits) */
3338 d[i++] = 0x75; d[i++] = 0x08;
3340 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3341 /* output (data, variable, absolute) */
3342 d[i++] = 0x91; d[i++] = 0x00;
3344 /* feature report */
3345 if (dev->feature_report_size) {
3346 /* usage (vendor defined) */
3347 d[i++] = 0x09; d[i++] = 0x03;
3348 /* logical minimum (0) */
3349 d[i++] = 0x15; d[i++] = 0x00;
3350 /* logical maximum (255) */
3351 d[i++] = 0x25; d[i++] = 0xFF;
3352 /* report size (8 bits) */
3353 d[i++] = 0x75; d[i++] = 0x08;
3355 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3356 /* feature (data, variable, absolute) */
3357 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3360 /* end collection */
3365 memcpy(data, d, *size);
3366 return LIBUSB_COMPLETED;
3369 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3370 int type, int _index, void *data, size_t *size)
3373 case LIBUSB_DT_DEVICE:
3374 usbi_dbg("LIBUSB_DT_DEVICE");
3375 return _hid_get_device_descriptor(dev, data, size);
3376 case LIBUSB_DT_CONFIG:
3377 usbi_dbg("LIBUSB_DT_CONFIG");
3379 return _hid_get_config_descriptor(dev, data, size);
3380 return LIBUSB_ERROR_INVALID_PARAM;
3381 case LIBUSB_DT_STRING:
3382 usbi_dbg("LIBUSB_DT_STRING");
3383 return _hid_get_string_descriptor(dev, _index, data, size);
3385 usbi_dbg("LIBUSB_DT_HID");
3387 return _hid_get_hid_descriptor(dev, data, size);
3388 return LIBUSB_ERROR_INVALID_PARAM;
3389 case LIBUSB_DT_REPORT:
3390 usbi_dbg("LIBUSB_DT_REPORT");
3392 return _hid_get_report_descriptor(dev, data, size);
3393 return LIBUSB_ERROR_INVALID_PARAM;
3394 case LIBUSB_DT_PHYSICAL:
3395 usbi_dbg("LIBUSB_DT_PHYSICAL");
3396 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3397 return LIBUSB_COMPLETED;
3398 return LIBUSB_ERROR_OTHER;
3400 usbi_dbg("unsupported");
3401 return LIBUSB_ERROR_INVALID_PARAM;
3404 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3405 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3409 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3410 int r = LIBUSB_SUCCESS;
3412 if (tp->hid_buffer != NULL) {
3413 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3416 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3417 usbi_dbg("invalid size (%d)", *size);
3418 return LIBUSB_ERROR_INVALID_PARAM;
3421 switch (report_type) {
3422 case HID_REPORT_TYPE_INPUT:
3423 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3425 case HID_REPORT_TYPE_FEATURE:
3426 ioctl_code = IOCTL_HID_GET_FEATURE;
3429 usbi_dbg("unknown HID report type %d", report_type);
3430 return LIBUSB_ERROR_INVALID_PARAM;
3433 // Add a trailing byte to detect overflows
3434 buf = (uint8_t*)calloc(expected_size+1, 1);
3436 return LIBUSB_ERROR_NO_MEM;
3438 buf[0] = (uint8_t)id; // Must be set always
3439 usbi_dbg("report ID: 0x%02X", buf[0]);
3441 tp->hid_expected_size = expected_size;
3442 read_size = expected_size;
3444 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3445 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3446 buf, expected_size+1, &read_size, overlapped)) {
3447 if (GetLastError() != ERROR_IO_PENDING) {
3448 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3450 return LIBUSB_ERROR_IO;
3452 // Asynchronous wait
3453 tp->hid_buffer = buf;
3454 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3455 return LIBUSB_SUCCESS;
3458 // Transfer completed synchronously => copy and discard extra buffer
3459 if (read_size == 0) {
3460 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3464 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3466 if ((size_t)read_size > expected_size) {
3467 r = LIBUSB_ERROR_OVERFLOW;
3468 usbi_dbg("OVERFLOW!");
3470 r = LIBUSB_COMPLETED;
3473 *size = MIN((size_t)read_size, *size);
3475 // Discard report ID
3476 memcpy(data, buf+1, *size);
3478 memcpy(data, buf, *size);
3485 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3486 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3489 uint8_t *buf = NULL;
3490 DWORD ioctl_code, write_size= (DWORD)*size;
3492 if (tp->hid_buffer != NULL) {
3493 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3496 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3497 usbi_dbg("invalid size (%d)", *size);
3498 return LIBUSB_ERROR_INVALID_PARAM;
3501 switch (report_type) {
3502 case HID_REPORT_TYPE_OUTPUT:
3503 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3505 case HID_REPORT_TYPE_FEATURE:
3506 ioctl_code = IOCTL_HID_SET_FEATURE;
3509 usbi_dbg("unknown HID report type %d", report_type);
3510 return LIBUSB_ERROR_INVALID_PARAM;
3513 usbi_dbg("report ID: 0x%02X", id);
3514 // When report IDs are not used (i.e. when id == 0), we must add
3515 // a null report ID. Otherwise, we just use original data buffer
3519 buf = (uint8_t*) malloc(write_size);
3521 return LIBUSB_ERROR_NO_MEM;
3525 memcpy(buf + 1, data, *size);
3527 // This seems like a waste, but if we don't duplicate the
3528 // data, we'll get issues when freeing hid_buffer
3529 memcpy(buf, data, *size);
3531 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3535 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3536 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3537 buf, write_size, &write_size, overlapped)) {
3538 if (GetLastError() != ERROR_IO_PENDING) {
3539 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3541 return LIBUSB_ERROR_IO;
3543 tp->hid_buffer = buf;
3544 tp->hid_dest = NULL;
3545 return LIBUSB_SUCCESS;
3548 // Transfer completed synchronously
3550 if (write_size == 0) {
3551 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3554 return LIBUSB_COMPLETED;
3557 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3558 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3559 size_t *size, OVERLAPPED* overlapped)
3561 int report_type = (value >> 8) & 0xFF;
3562 int report_id = value & 0xFF;
3564 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3565 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3566 return LIBUSB_ERROR_INVALID_PARAM;
3568 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3569 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3571 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3572 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3574 return LIBUSB_ERROR_INVALID_PARAM;
3581 static int hid_init(int sub_api, struct libusb_context *ctx)
3583 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3584 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3585 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3586 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3587 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3588 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3589 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3590 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3591 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3592 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3593 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3594 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3595 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3596 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3597 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3598 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3600 api_hid_available = true;
3601 return LIBUSB_SUCCESS;
3604 static int hid_exit(int sub_api)
3606 return LIBUSB_SUCCESS;
3609 // NB: open and close must ensure that they only handle interface of
3610 // the right API type, as these functions can be called wholesale from
3611 // composite_open(), with interfaces belonging to different APIs
3612 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3614 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3615 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3616 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3618 HIDD_ATTRIBUTES hid_attributes;
3619 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3620 HIDP_CAPS capabilities;
3621 HIDP_VALUE_CAPS *value_caps;
3623 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3625 // report IDs handling
3627 char* type[3] = {"input", "output", "feature"};
3628 int nb_ids[2]; // zero and nonzero report IDs
3630 CHECK_HID_AVAILABLE;
3631 if (priv->hid == NULL) {
3632 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3633 return LIBUSB_ERROR_NOT_FOUND;
3636 for (i = 0; i < USB_MAXINTERFACES; i++) {
3637 if ( (priv->usb_interface[i].path != NULL)
3638 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3639 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3640 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3642 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3643 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3644 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3645 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3646 * HidD_GetFeature (if the device supports Feature reports)."
3648 if (hid_handle == INVALID_HANDLE_VALUE) {
3649 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3650 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3651 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3652 if (hid_handle == INVALID_HANDLE_VALUE) {
3653 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3654 switch(GetLastError()) {
3655 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3656 return LIBUSB_ERROR_NO_DEVICE;
3657 case ERROR_ACCESS_DENIED:
3658 return LIBUSB_ERROR_ACCESS;
3660 return LIBUSB_ERROR_IO;
3663 priv->usb_interface[i].restricted_functionality = true;
3665 handle_priv->interface_handle[i].api_handle = hid_handle;
3669 hid_attributes.Size = sizeof(hid_attributes);
3671 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3672 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3676 priv->hid->vid = hid_attributes.VendorID;
3677 priv->hid->pid = hid_attributes.ProductID;
3679 // Set the maximum available input buffer size
3680 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3681 usbi_dbg("set maximum input buffer size to %d", i/2);
3683 // Get the maximum input and output report size
3684 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3685 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3688 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3689 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3693 // Find out if interrupt will need report IDs
3694 size[0] = capabilities.NumberInputValueCaps;
3695 size[1] = capabilities.NumberOutputValueCaps;
3696 size[2] = capabilities.NumberFeatureValueCaps;
3697 for (j=HidP_Input; j<=HidP_Feature; j++) {
3698 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3699 priv->hid->uses_report_ids[j] = false;
3701 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3702 if ( (value_caps != NULL)
3703 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3704 && (size[j] >= 1) ) {
3707 for (i=0; i<(int)size[j]; i++) {
3708 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3709 if (value_caps[i].ReportID != 0) {
3715 if (nb_ids[1] != 0) {
3716 if (nb_ids[0] != 0) {
3717 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3720 priv->hid->uses_report_ids[j] = true;
3723 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3725 safe_free(value_caps);
3729 // Set the report sizes
3730 priv->hid->input_report_size = capabilities.InputReportByteLength;
3731 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3732 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3734 // Fetch string descriptors
3735 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3736 if (priv->hid->string_index[0] != 0) {
3737 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3738 sizeof(priv->hid->string[0]));
3740 priv->hid->string[0][0] = 0;
3742 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3743 if (priv->hid->string_index[1] != 0) {
3744 HidD_GetProductString(hid_handle, priv->hid->string[1],
3745 sizeof(priv->hid->string[1]));
3747 priv->hid->string[1][0] = 0;
3749 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3750 if (priv->hid->string_index[2] != 0) {
3751 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3752 sizeof(priv->hid->string[2]));
3754 priv->hid->string[2][0] = 0;
3758 if (preparsed_data) {
3759 HidD_FreePreparsedData(preparsed_data);
3762 return LIBUSB_SUCCESS;
3765 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3767 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3768 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3772 if (!api_hid_available)
3775 for (i = 0; i < USB_MAXINTERFACES; i++) {
3776 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3777 file_handle = handle_priv->interface_handle[i].api_handle;
3778 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3779 CloseHandle(file_handle);
3785 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3787 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3788 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3790 CHECK_HID_AVAILABLE;
3792 // NB: Disconnection detection is not possible in this function
3793 if (priv->usb_interface[iface].path == NULL) {
3794 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3797 // We use dev_handle as a flag for interface claimed
3798 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3799 return LIBUSB_ERROR_BUSY; // already claimed
3802 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3804 usbi_dbg("claimed interface %d", iface);
3805 handle_priv->active_interface = iface;
3807 return LIBUSB_SUCCESS;
3810 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3812 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3813 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3815 CHECK_HID_AVAILABLE;
3817 if (priv->usb_interface[iface].path == NULL) {
3818 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3821 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3822 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3825 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3827 return LIBUSB_SUCCESS;
3830 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3832 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3834 CHECK_HID_AVAILABLE;
3836 if (altsetting > 255) {
3837 return LIBUSB_ERROR_INVALID_PARAM;
3840 if (altsetting != 0) {
3841 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3842 return LIBUSB_ERROR_NOT_SUPPORTED;
3845 return LIBUSB_SUCCESS;
3848 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3850 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3851 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3852 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3853 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3854 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3855 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3858 int current_interface, config;
3860 int r = LIBUSB_ERROR_INVALID_PARAM;
3862 CHECK_HID_AVAILABLE;
3864 transfer_priv->pollable_fd = INVALID_WINFD;
3865 safe_free(transfer_priv->hid_buffer);
3866 transfer_priv->hid_dest = NULL;
3867 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3869 if (size > MAX_CTRL_BUFFER_LENGTH) {
3870 return LIBUSB_ERROR_INVALID_PARAM;
3873 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3874 if (current_interface < 0) {
3875 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3876 return LIBUSB_ERROR_NOT_FOUND;
3880 usbi_dbg("will use interface %d", current_interface);
3881 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3882 // Always use the handle returned from usbi_create_fd (wfd.handle)
3883 wfd = usbi_create_fd(hid_handle, _O_RDONLY);
3885 return LIBUSB_ERROR_NO_MEM;
3888 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3889 case LIBUSB_REQUEST_TYPE_STANDARD:
3890 switch(setup->request) {
3891 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3892 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3893 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3895 case LIBUSB_REQUEST_GET_CONFIGURATION:
3896 r = windows_get_configuration(transfer->dev_handle, &config);
3897 if (r == LIBUSB_SUCCESS) {
3899 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3900 r = LIBUSB_COMPLETED;
3903 case LIBUSB_REQUEST_SET_CONFIGURATION:
3904 if (setup->value == priv->active_config) {
3905 r = LIBUSB_COMPLETED;
3907 usbi_warn(ctx, "cannot set configuration other than the default one");
3908 r = LIBUSB_ERROR_INVALID_PARAM;
3911 case LIBUSB_REQUEST_GET_INTERFACE:
3913 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3914 r = LIBUSB_COMPLETED;
3916 case LIBUSB_REQUEST_SET_INTERFACE:
3917 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3918 if (r == LIBUSB_SUCCESS) {
3919 r = LIBUSB_COMPLETED;
3923 usbi_warn(ctx, "unsupported HID control request");
3924 r = LIBUSB_ERROR_INVALID_PARAM;
3928 case LIBUSB_REQUEST_TYPE_CLASS:
3929 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3930 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3931 &size, wfd.overlapped);
3934 usbi_warn(ctx, "unsupported HID control request");
3935 r = LIBUSB_ERROR_INVALID_PARAM;
3939 if (r == LIBUSB_COMPLETED) {
3940 // Force request to be completed synchronously. Transferred size has been set by previous call
3941 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3942 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3943 // set InternalHigh to the number of bytes transferred
3944 wfd.overlapped->InternalHigh = (DWORD)size;
3948 if (r == LIBUSB_SUCCESS) {
3949 // Use priv_transfer to store data needed for async polling
3950 transfer_priv->pollable_fd = wfd;
3951 transfer_priv->interface_number = (uint8_t)current_interface;
3953 usbi_free_fd(wfd.fd);
3959 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3960 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3961 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3962 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3963 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3964 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3967 bool direction_in, ret;
3968 int current_interface, length;
3970 int r = LIBUSB_SUCCESS;
3972 CHECK_HID_AVAILABLE;
3974 transfer_priv->pollable_fd = INVALID_WINFD;
3975 transfer_priv->hid_dest = NULL;
3976 safe_free(transfer_priv->hid_buffer);
3978 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3979 if (current_interface < 0) {
3980 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3981 return LIBUSB_ERROR_NOT_FOUND;
3984 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3986 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3987 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
3989 wfd = usbi_create_fd(hid_handle, direction_in?_O_RDONLY:_O_WRONLY);
3990 // Always use the handle returned from usbi_create_fd (wfd.handle)
3992 return LIBUSB_ERROR_NO_MEM;
3995 // If report IDs are not in use, an extra prefix byte must be added
3996 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
3997 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
3998 length = transfer->length+1;
4000 length = transfer->length;
4002 // Add a trailing byte to detect overflows on input
4003 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4004 if (transfer_priv->hid_buffer == NULL) {
4005 return LIBUSB_ERROR_NO_MEM;
4007 transfer_priv->hid_expected_size = length;
4010 transfer_priv->hid_dest = transfer->buffer;
4011 usbi_dbg("reading %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4012 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4014 if (!priv->hid->uses_report_ids[1]) {
4015 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4017 // We could actually do without the calloc and memcpy in this case
4018 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4020 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4021 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4024 if (GetLastError() != ERROR_IO_PENDING) {
4025 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4026 usbi_free_fd(wfd.fd);
4027 safe_free(transfer_priv->hid_buffer);
4028 return LIBUSB_ERROR_IO;
4031 // Only write operations that completed synchronously need to free up
4032 // hid_buffer. For reads, copy_transfer_data() handles that process.
4033 if (!direction_in) {
4034 safe_free(transfer_priv->hid_buffer);
4037 usbi_err(ctx, "program assertion failed - no data was transferred");
4040 if (size > (size_t)length) {
4041 usbi_err(ctx, "OVERFLOW!");
4042 r = LIBUSB_ERROR_OVERFLOW;
4044 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4045 wfd.overlapped->InternalHigh = size;
4048 transfer_priv->pollable_fd = wfd;
4049 transfer_priv->interface_number = (uint8_t)current_interface;
4054 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4056 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4057 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4058 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4060 int current_interface;
4062 CHECK_HID_AVAILABLE;
4064 current_interface = transfer_priv->interface_number;
4065 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4066 CancelIo(hid_handle);
4068 return LIBUSB_SUCCESS;
4071 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4073 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4075 int current_interface;
4077 CHECK_HID_AVAILABLE;
4079 // Flushing the queues on all interfaces is the best we can achieve
4080 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4081 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4082 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4083 HidD_FlushQueue(hid_handle);
4086 return LIBUSB_SUCCESS;
4089 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4091 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4092 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4093 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4095 int current_interface;
4097 CHECK_HID_AVAILABLE;
4099 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4100 if (current_interface < 0) {
4101 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4102 return LIBUSB_ERROR_NOT_FOUND;
4105 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4106 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4108 // No endpoint selection with Microsoft's implementation, so we try to flush the
4109 // whole interface. Should be OK for most case scenarios
4110 if (!HidD_FlushQueue(hid_handle)) {
4111 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4112 // Device was probably disconnected
4113 return LIBUSB_ERROR_NO_DEVICE;
4116 return LIBUSB_SUCCESS;
4119 // This extra function is only needed for HID
4120 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4121 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4122 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4123 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4124 int r = LIBUSB_TRANSFER_COMPLETED;
4125 uint32_t corrected_size = io_size;
4127 if (transfer_priv->hid_buffer != NULL) {
4128 // If we have a valid hid_buffer, it means the transfer was async
4129 if (transfer_priv->hid_dest != NULL) { // Data readout
4130 // First, check for overflow
4131 if (corrected_size > transfer_priv->hid_expected_size) {
4132 usbi_err(ctx, "OVERFLOW!");
4133 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4134 r = LIBUSB_TRANSFER_OVERFLOW;
4137 if (transfer_priv->hid_buffer[0] == 0) {
4138 // Discard the 1 byte report ID prefix
4140 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4142 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4144 transfer_priv->hid_dest = NULL;
4146 // For write, we just need to free the hid buffer
4147 safe_free(transfer_priv->hid_buffer);
4149 itransfer->transferred += corrected_size;
4155 * Composite API functions
4157 static int composite_init(int sub_api, struct libusb_context *ctx)
4159 return LIBUSB_SUCCESS;
4162 static int composite_exit(int sub_api)
4164 return LIBUSB_SUCCESS;
4167 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4169 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4172 bool available[SUB_API_MAX];
4174 for (i = 0; i<SUB_API_MAX; i++) {
4175 available[i] = false;
4178 for (i=0; i<USB_MAXINTERFACES; i++) {
4179 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4180 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4181 available[priv->usb_interface[i].sub_api] = true;
4185 for (i=0; i<SUB_API_MAX; i++) {
4187 r = usb_api_backend[USB_API_WINUSBX].open(SUB_API_NOTSET, dev_handle);
4188 if (r != LIBUSB_SUCCESS) {
4193 return LIBUSB_SUCCESS;
4196 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4198 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4200 bool available[SUB_API_MAX];
4202 for (i = 0; i<SUB_API_MAX; i++) {
4203 available[i] = false;
4206 for (i=0; i<USB_MAXINTERFACES; i++) {
4207 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4208 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4209 available[priv->usb_interface[i].sub_api] = true;
4213 for (i=0; i<SUB_API_MAX; i++) {
4215 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4220 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4222 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4223 return priv->usb_interface[iface].apib->
4224 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4227 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4229 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4230 return priv->usb_interface[iface].apib->
4231 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4234 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4236 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4237 return priv->usb_interface[iface].apib->
4238 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4241 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4243 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4244 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4245 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4248 // Interface shouldn't matter for control, but it does in practice, with Windows'
4249 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4250 for (pass = 0; pass < 2; pass++) {
4251 for (i=0; i<USB_MAXINTERFACES; i++) {
4252 if (priv->usb_interface[i].path != NULL) {
4253 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4254 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4257 usbi_dbg("using interface %d", i);
4258 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4263 usbi_err(ctx, "no libusbx supported interfaces to complete request");
4264 return LIBUSB_ERROR_NOT_FOUND;
4267 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4268 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4269 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4270 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4271 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4272 int current_interface;
4274 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4275 if (current_interface < 0) {
4276 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4277 return LIBUSB_ERROR_NOT_FOUND;
4280 return priv->usb_interface[current_interface].apib->
4281 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4283 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4284 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4285 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4286 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4287 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4288 int current_interface;
4290 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4291 if (current_interface < 0) {
4292 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4293 return LIBUSB_ERROR_NOT_FOUND;
4296 return priv->usb_interface[current_interface].apib->
4297 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4299 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4301 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4302 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4303 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4304 int current_interface;
4306 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4307 if (current_interface < 0) {
4308 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4309 return LIBUSB_ERROR_NOT_FOUND;
4312 return priv->usb_interface[current_interface].apib->
4313 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4315 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4317 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4318 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4319 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4321 return priv->usb_interface[transfer_priv->interface_number].apib->
4322 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4324 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4326 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4327 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4328 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4330 return priv->usb_interface[transfer_priv->interface_number].apib->
4331 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4333 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4335 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4338 bool available[SUB_API_MAX];
4339 for (i = 0; i<SUB_API_MAX; i++) {
4340 available[i] = false;
4342 for (i=0; i<USB_MAXINTERFACES; i++) {
4343 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4344 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4345 available[priv->usb_interface[i].sub_api] = true;
4348 for (i=0; i<SUB_API_MAX; i++) {
4350 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4351 if (r != LIBUSB_SUCCESS) {
4356 return LIBUSB_SUCCESS;
4359 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4361 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4362 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4363 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4365 return priv->usb_interface[transfer_priv->interface_number].apib->
4366 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);