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; }
46 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian);
47 static int windows_clock_gettime(int clk_id, struct timespec *tp);
48 unsigned __stdcall windows_clock_gettime_threaded(void* param);
50 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
52 // WinUSB-like API prototypes
53 static int winusbx_init(int sub_api, struct libusb_context *ctx);
54 static int winusbx_exit(int sub_api);
55 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle);
56 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle);
57 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
58 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
59 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
60 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
61 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
62 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
63 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
64 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
65 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer);
66 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
67 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
69 static int hid_init(int sub_api, struct libusb_context *ctx);
70 static int hid_exit(int sub_api);
71 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle);
72 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle);
73 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
74 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
75 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
76 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
77 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
78 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
79 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
80 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
81 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
82 // Composite API prototypes
83 static int composite_init(int sub_api, struct libusb_context *ctx);
84 static int composite_exit(int sub_api);
85 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle);
86 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle);
87 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
88 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
89 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
90 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
91 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
92 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
93 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
94 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
95 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer);
96 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
97 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
101 uint64_t hires_frequency, hires_ticks_to_ps;
102 const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
103 enum windows_version windows_version = WINDOWS_UNSUPPORTED;
105 static int concurrent_usage = -1;
106 usbi_mutex_t autoclaim_lock;
108 // NB: index 0 is for monotonic and 1 is for the thread exit event
109 HANDLE timer_thread = NULL;
110 HANDLE timer_mutex = NULL;
111 struct timespec timer_tp;
112 volatile LONG request_count[2] = {0, 1}; // last one must be > 0
113 HANDLE timer_request[2] = { NULL, NULL };
114 HANDLE timer_response = NULL;
116 #define CHECK_WINUSBX_AVAILABLE(sub_api) do { if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; \
117 if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0)
118 static struct winusb_interface WinUSBX[SUB_API_MAX];
119 const char* sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES;
120 bool api_hid_available = false;
121 #define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0)
123 static inline BOOLEAN guid_eq(const GUID *guid1, const GUID *guid2) {
124 if ((guid1 != NULL) && (guid2 != NULL)) {
125 return (memcmp(guid1, guid2, sizeof(GUID)) == 0);
130 #if defined(ENABLE_LOGGING)
131 static char* guid_to_string(const GUID* guid)
133 static char guid_string[MAX_GUID_STRING_LENGTH];
135 if (guid == NULL) return NULL;
136 sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
137 (unsigned int)guid->Data1, guid->Data2, guid->Data3,
138 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
139 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
145 * Converts a windows error to human readable string
146 * uses retval as errorcode, or, if 0, use GetLastError()
148 #if defined(ENABLE_LOGGING)
149 static char *windows_error_str(uint32_t retval)
151 static char err_string[ERR_BUFFER_SIZE];
155 uint32_t error_code, format_error;
157 error_code = retval?retval:GetLastError();
159 safe_sprintf(err_string, ERR_BUFFER_SIZE, "[%u] ", error_code);
161 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
162 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
163 ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
165 format_error = GetLastError();
167 safe_sprintf(err_string, ERR_BUFFER_SIZE,
168 "Windows error code %u (FormatMessage error code %u)", error_code, format_error);
170 safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
172 // Remove CR/LF terminators
173 for (i=safe_strlen(err_string)-1; ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
182 * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
183 * Return an allocated sanitized string or NULL on error.
185 static char* sanitize_path(const char* path)
187 const char root_prefix[] = "\\\\.\\";
188 size_t j, size, root_size;
189 char* ret_path = NULL;
195 size = safe_strlen(path)+1;
196 root_size = sizeof(root_prefix)-1;
198 // Microsoft indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
199 if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
200 ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
201 add_root = root_size;
205 if ((ret_path = (char*) calloc(size, 1)) == NULL)
208 safe_strcpy(&ret_path[add_root], size-add_root, path);
210 // Ensure consistancy with root prefix
211 for (j=0; j<root_size; j++)
212 ret_path[j] = root_prefix[j];
214 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
215 for(j=root_size; j<size; j++) {
216 ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
217 if (ret_path[j] == '\\')
225 * Cfgmgr32, OLE32 and SetupAPI DLL functions
227 static int init_dlls(void)
229 DLL_LOAD(Cfgmgr32.dll, CM_Get_Parent, TRUE);
230 DLL_LOAD(Cfgmgr32.dll, CM_Get_Child, TRUE);
231 DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE);
232 DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE);
233 // Prefixed to avoid conflict with header files
234 DLL_LOAD_PREFIXED(OLE32.dll, p, CLSIDFromString, TRUE);
235 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE);
236 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE);
237 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE);
238 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
239 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
240 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
241 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
242 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
243 DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
244 DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
245 return LIBUSB_SUCCESS;
249 * enumerate interfaces for the whole USB class
252 * dev_info: a pointer to a dev_info list
253 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
254 * usb_class: the generic USB class for which to retrieve interface details
255 * index: zero based index of the interface in the device info list
257 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
258 * structure returned and call this function repeatedly using the same guid (with an
259 * incremented index starting at zero) until all interfaces have been returned.
261 static bool get_devinfo_data(struct libusb_context *ctx,
262 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char* usb_class, unsigned _index)
265 *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
266 if (*dev_info == INVALID_HANDLE_VALUE) {
271 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
272 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
273 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
274 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
275 _index, windows_error_str(0));
277 pSetupDiDestroyDeviceInfoList(*dev_info);
278 *dev_info = INVALID_HANDLE_VALUE;
285 * enumerate interfaces for a specific GUID
288 * dev_info: a pointer to a dev_info list
289 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
290 * guid: the GUID for which to retrieve interface details
291 * index: zero based index of the interface in the device info list
293 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
294 * structure returned and call this function repeatedly using the same guid (with an
295 * incremented index starting at zero) until all interfaces have been returned.
297 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details(struct libusb_context *ctx,
298 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index)
300 SP_DEVICE_INTERFACE_DATA dev_interface_data;
301 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
305 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
308 if (dev_info_data != NULL) {
309 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
310 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
311 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
312 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
313 _index, windows_error_str(0));
315 pSetupDiDestroyDeviceInfoList(*dev_info);
316 *dev_info = INVALID_HANDLE_VALUE;
321 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
322 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
323 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
324 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
325 _index, windows_error_str(0));
327 pSetupDiDestroyDeviceInfoList(*dev_info);
328 *dev_info = INVALID_HANDLE_VALUE;
332 // Read interface data (dummy + actual) to access the device path
333 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
334 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
335 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
336 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
337 _index, windows_error_str(0));
341 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
345 if ((dev_interface_details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) calloc(size, 1)) == NULL) {
346 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
350 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
351 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
352 dev_interface_details, size, &size, NULL)) {
353 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
354 _index, windows_error_str(0));
357 return dev_interface_details;
360 pSetupDiDestroyDeviceInfoList(*dev_info);
361 *dev_info = INVALID_HANDLE_VALUE;
365 /* For libusb0 filter */
366 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
367 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index, char* filter_path){
368 SP_DEVICE_INTERFACE_DATA dev_interface_data;
369 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
372 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
374 if (dev_info_data != NULL) {
375 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
376 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
377 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
378 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
379 _index, windows_error_str(0));
381 pSetupDiDestroyDeviceInfoList(*dev_info);
382 *dev_info = INVALID_HANDLE_VALUE;
386 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
387 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
388 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
389 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
390 _index, windows_error_str(0));
392 pSetupDiDestroyDeviceInfoList(*dev_info);
393 *dev_info = INVALID_HANDLE_VALUE;
396 // Read interface data (dummy + actual) to access the device path
397 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
398 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
399 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
400 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
401 _index, windows_error_str(0));
405 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
408 if ((dev_interface_details = malloc(size)) == NULL) {
409 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
412 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
413 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
414 dev_interface_details, size, &size, NULL)) {
415 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
416 _index, windows_error_str(0));
418 // [trobinso] lookup the libusb0 symbolic index.
419 if (dev_interface_details) {
420 HKEY hkey_device_interface=pSetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ);
421 if (hkey_device_interface != INVALID_HANDLE_VALUE) {
422 DWORD libusb0_symboliclink_index=0;
423 DWORD value_length=sizeof(DWORD);
426 status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type,
427 (LPBYTE) &libusb0_symboliclink_index, &value_length);
428 if (status == ERROR_SUCCESS) {
429 if (libusb0_symboliclink_index < 256) {
430 // libusb0.sys is connected to this device instance.
431 // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
432 safe_sprintf(filter_path, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index);
433 usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
435 // libusb0.sys was connected to this device instance at one time; but not anymore.
438 pRegCloseKey(hkey_device_interface);
441 return dev_interface_details;
443 pSetupDiDestroyDeviceInfoList(*dev_info);
444 *dev_info = INVALID_HANDLE_VALUE;
447 /* Hash table functions - modified From glibc 2.3.2:
448 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
449 [Knuth] The Art of Computer Programming, part 3 (6.4) */
450 typedef struct htab_entry {
454 htab_entry* htab_table = NULL;
455 usbi_mutex_t htab_write_mutex = NULL;
456 unsigned long htab_size, htab_filled;
458 /* For the used double hash method the table size has to be a prime. To
459 correct the user given table size we need a prime test. This trivial
460 algorithm is adequate because the code is called only during init and
461 the number is likely to be small */
462 static int isprime(unsigned long number)
464 // no even number will be passed
465 unsigned int divider = 3;
467 while((divider * divider < number) && (number % divider != 0))
470 return (number % divider != 0);
473 /* Before using the hash table we must allocate memory for it.
474 We allocate one element more as the found prime number says.
475 This is done for more effective indexing as explained in the
476 comment for the hash function. */
477 static int htab_create(struct libusb_context *ctx, unsigned long nel)
479 if (htab_table != NULL) {
480 usbi_err(ctx, "hash table already allocated");
484 usbi_mutex_init(&htab_write_mutex, NULL);
486 // Change nel to the first prime number not smaller as nel.
492 usbi_dbg("using %d entries hash table", nel);
495 // allocate memory and zero out.
496 htab_table = (htab_entry*) calloc(htab_size + 1, sizeof(htab_entry));
497 if (htab_table == NULL) {
498 usbi_err(ctx, "could not allocate space for hash table");
505 /* After using the hash table it has to be destroyed. */
506 static void htab_destroy(void)
509 if (htab_table == NULL) {
513 for (i=0; i<htab_size; i++) {
514 if (htab_table[i].used) {
515 safe_free(htab_table[i].str);
518 usbi_mutex_destroy(&htab_write_mutex);
519 safe_free(htab_table);
522 /* This is the search function. It uses double hashing with open addressing.
523 We use an trick to speed up the lookup. The table is created with one
524 more element available. This enables us to use the index zero special.
525 This index will never be used because we store the first hash index in
526 the field used where zero means not used. Every other value means used.
527 The used field can be used as a first fast comparison for equality of
528 the stored and the parameter value. This helps to prevent unnecessary
529 expensive calls of strcmp. */
530 static unsigned long htab_hash(char* str)
532 unsigned long hval, hval2;
534 unsigned long r = 5381;
538 // Compute main hash value (algorithm suggested by Nokia)
539 while ((c = *sz++) != 0)
540 r = ((r << 5) + r) + c;
544 // compute table hash: simply take the modulus
545 hval = r % htab_size;
549 // Try the first index
552 if (htab_table[idx].used) {
553 if ( (htab_table[idx].used == hval)
554 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
558 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
560 // Second hash function, as suggested in [Knuth]
561 hval2 = 1 + hval % (htab_size - 2);
564 // Because size is prime this guarantees to step through all available indexes
566 idx = htab_size + idx - hval2;
571 // If we visited all entries leave the loop unsuccessfully
576 // If entry is found use it.
577 if ( (htab_table[idx].used == hval)
578 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
582 while (htab_table[idx].used);
585 // Not found => New entry
587 // If the table is full return an error
588 if (htab_filled >= htab_size) {
589 usbi_err(NULL, "hash table is full (%d entries)", htab_size);
593 // Concurrent threads might be storing the same entry at the same time
594 // (eg. "simultaneous" enums from different threads) => use a mutex
595 usbi_mutex_lock(&htab_write_mutex);
596 // Just free any previously allocated string (which should be the same as
597 // new one). The possibility of concurrent threads storing a collision
598 // string (same hash, different string) at the same time is extremely low
599 safe_free(htab_table[idx].str);
600 htab_table[idx].used = hval;
601 htab_table[idx].str = (char*) malloc(safe_strlen(str)+1);
602 if (htab_table[idx].str == NULL) {
603 usbi_err(NULL, "could not duplicate string for hash table");
604 usbi_mutex_unlock(&htab_write_mutex);
607 memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
609 usbi_mutex_unlock(&htab_write_mutex);
615 * Returns the session ID of a device's nth level ancestor
616 * If there's no device at the nth level, return 0
618 static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
620 DWORD parent_devinst;
621 unsigned long session_id = 0;
622 char* sanitized_path = NULL;
623 char path[MAX_PATH_LENGTH];
626 if (level < 1) return 0;
627 for (i = 0; i<level; i++) {
628 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
631 devinst = parent_devinst;
633 if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
636 // TODO: (post hotplug): try without sanitizing
637 sanitized_path = sanitize_path(path);
638 if (sanitized_path == NULL) {
641 session_id = htab_hash(sanitized_path);
642 safe_free(sanitized_path);
647 * Populate the endpoints addresses of the device_priv interface helper structs
649 static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
652 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
653 struct libusb_config_descriptor *conf_desc;
654 const struct libusb_interface_descriptor *if_desc;
655 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
657 r = libusb_get_config_descriptor(dev_handle->dev, 0, &conf_desc);
658 if (r != LIBUSB_SUCCESS) {
659 usbi_warn(ctx, "could not read config descriptor: error %d", r);
663 if_desc = &conf_desc->interface[iface].altsetting[altsetting];
664 safe_free(priv->usb_interface[iface].endpoint);
666 if (if_desc->bNumEndpoints == 0) {
667 usbi_dbg("no endpoints found for interface %d", iface);
668 return LIBUSB_SUCCESS;
671 priv->usb_interface[iface].endpoint = (uint8_t*) malloc(if_desc->bNumEndpoints);
672 if (priv->usb_interface[iface].endpoint == NULL) {
673 return LIBUSB_ERROR_NO_MEM;
676 priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
677 for (i=0; i<if_desc->bNumEndpoints; i++) {
678 priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
679 usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface);
681 libusb_free_config_descriptor(conf_desc);
683 // Extra init may be required to configure endpoints
684 return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
687 // Lookup for a match in the list of API driver names
688 // return -1 if not found, driver match number otherwise
689 static int get_sub_api(char* driver, int api){
691 const char sep_str[2] = {LIST_SEPARATOR, 0};
693 size_t len = safe_strlen(driver);
695 if (len == 0) return SUB_API_NOTSET;
696 tmp_str = (char*) calloc(len+1, 1);
697 if (tmp_str == NULL) return SUB_API_NOTSET;
698 memcpy(tmp_str, driver, len+1);
699 tok = strtok(tmp_str, sep_str);
700 while (tok != NULL) {
701 for (i=0; i<usb_api_backend[api].nb_driver_names; i++) {
702 if (safe_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
707 tok = strtok(NULL, sep_str);
710 return SUB_API_NOTSET;
714 * auto-claiming and auto-release helper functions
716 static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
718 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
719 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
720 transfer->dev_handle);
721 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
722 int current_interface = *interface_number;
723 int r = LIBUSB_SUCCESS;
726 case USB_API_WINUSBX:
730 return LIBUSB_ERROR_INVALID_PARAM;
733 usbi_mutex_lock(&autoclaim_lock);
734 if (current_interface < 0) // No serviceable interface was found
736 for (current_interface=0; current_interface<USB_MAXINTERFACES; current_interface++) {
737 // Must claim an interface of the same API type
738 if ( (priv->usb_interface[current_interface].apib->id == api_type)
739 && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS) ) {
740 usbi_dbg("auto-claimed interface %d for control request", current_interface);
741 if (handle_priv->autoclaim_count[current_interface] != 0) {
742 usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero");
744 handle_priv->autoclaim_count[current_interface]++;
748 if (current_interface == USB_MAXINTERFACES) {
749 usbi_err(ctx, "could not auto-claim any interface");
750 r = LIBUSB_ERROR_NOT_FOUND;
753 // If we have a valid interface that was autoclaimed, we must increment
754 // its autoclaim count so that we can prevent an early release.
755 if (handle_priv->autoclaim_count[current_interface] != 0) {
756 handle_priv->autoclaim_count[current_interface]++;
759 usbi_mutex_unlock(&autoclaim_lock);
761 *interface_number = current_interface;
766 static void auto_release(struct usbi_transfer *itransfer)
768 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
769 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
770 libusb_device_handle *dev_handle = transfer->dev_handle;
771 struct windows_device_handle_priv* handle_priv = _device_handle_priv(dev_handle);
774 usbi_mutex_lock(&autoclaim_lock);
775 if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
776 handle_priv->autoclaim_count[transfer_priv->interface_number]--;
777 if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
778 r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
779 if (r == LIBUSB_SUCCESS) {
780 usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
782 usbi_dbg("failed to auto-release interface %d (%s)",
783 transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
787 usbi_mutex_unlock(&autoclaim_lock);
791 * init: libusbx backend init function
793 * This function enumerates the HCDs (Host Controller Drivers) and populates our private HCD list
794 * In our implementation, we equate Windows' "HCD" to libusbx's "bus". Note that bus is zero indexed.
795 * HCDs are not expected to change after init (might not hold true for hot pluggable USB PCI card?)
797 static int windows_init(struct libusb_context *ctx)
799 int i, r = LIBUSB_ERROR_OTHER;
800 OSVERSIONINFO os_version;
802 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
804 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
805 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
806 if (semaphore == NULL) {
807 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
808 return LIBUSB_ERROR_NO_MEM;
811 // A successful wait brings our semaphore count to 0 (unsignaled)
812 // => any concurent wait stalls until the semaphore's release
813 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
814 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
815 CloseHandle(semaphore);
816 return LIBUSB_ERROR_NO_MEM;
819 // NB: concurrent usage supposes that init calls are equally balanced with
820 // exit calls. If init is called more than exit, we will not exit properly
821 if ( ++concurrent_usage == 0 ) { // First init?
823 memset(&os_version, 0, sizeof(OSVERSIONINFO));
824 os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
825 windows_version = WINDOWS_UNSUPPORTED;
826 if ((GetVersionEx(&os_version) != 0) && (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
827 if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 1)) {
828 windows_version = WINDOWS_XP;
829 } else if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 2)) {
830 windows_version = WINDOWS_2003; // also includes XP 64
831 } else if (os_version.dwMajorVersion >= 6) {
832 windows_version = WINDOWS_VISTA_AND_LATER;
835 if (windows_version == WINDOWS_UNSUPPORTED) {
836 usbi_err(ctx, "This version of Windows is NOT supported");
837 r = LIBUSB_ERROR_NOT_SUPPORTED;
841 // We need a lock for proper auto-release
842 usbi_mutex_init(&autoclaim_lock, NULL);
844 // Initialize pollable file descriptors
848 if (init_dlls() != LIBUSB_SUCCESS) {
849 usbi_err(ctx, "could not resolve DLL functions");
850 return LIBUSB_ERROR_NOT_FOUND;
853 // Initialize the low level APIs (we don't care about errors at this stage)
854 for (i=0; i<USB_API_MAX; i++) {
855 usb_api_backend[i].init(SUB_API_NOTSET, ctx);
858 // Because QueryPerformanceCounter might report different values when
859 // running on different cores, we create a separate thread for the timer
860 // calls, which we glue to the first core always to prevent timing discrepancies.
861 r = LIBUSB_ERROR_NO_MEM;
862 for (i = 0; i < 2; i++) {
863 timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
864 if (timer_request[i] == NULL) {
865 usbi_err(ctx, "could not create timer request event %d - aborting", i);
869 timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
870 if (timer_response == NULL) {
871 usbi_err(ctx, "could not create timer response semaphore - aborting");
874 timer_mutex = CreateMutex(NULL, FALSE, NULL);
875 if (timer_mutex == NULL) {
876 usbi_err(ctx, "could not create timer mutex - aborting");
879 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, NULL, 0, NULL);
880 if (timer_thread == NULL) {
881 usbi_err(ctx, "Unable to create timer thread - aborting");
884 SetThreadAffinityMask(timer_thread, 0);
886 // Create a hash table to store session ids. Second parameter is better if prime
887 htab_create(ctx, HTAB_SIZE);
889 // At this stage, either we went through full init successfully, or didn't need to
892 init_exit: // Holds semaphore here.
893 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
895 SetEvent(timer_request[1]); // actually the signal to quit the thread.
896 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
897 usbi_warn(ctx, "could not wait for timer thread to quit");
898 TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
899 // all objects it might have held anyway.
901 CloseHandle(timer_thread);
904 for (i = 0; i < 2; i++) {
905 if (timer_request[i]) {
906 CloseHandle(timer_request[i]);
907 timer_request[i] = NULL;
910 if (timer_response) {
911 CloseHandle(timer_response);
912 timer_response = NULL;
915 CloseHandle(timer_mutex);
921 if (r != LIBUSB_SUCCESS)
922 --concurrent_usage; // Not expected to call libusb_exit if we failed.
924 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
925 CloseHandle(semaphore);
930 * HCD (root) hubs need to have their device descriptor manually populated
932 * Note that, like Microsoft does in the device manager, we populate the
933 * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device.
935 static int force_hcd_device_descriptor(struct libusb_device *dev)
937 struct windows_device_priv *parent_priv, *priv = _device_priv(dev);
938 struct libusb_context *ctx = DEVICE_CTX(dev);
941 dev->num_configurations = 1;
942 priv->dev_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
943 priv->dev_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
944 priv->dev_descriptor.bNumConfigurations = 1;
945 priv->active_config = 1;
947 if (priv->parent_dev == NULL) {
948 usbi_err(ctx, "program assertion failed - HCD hub has no parent");
949 return LIBUSB_ERROR_NO_DEVICE;
951 parent_priv = _device_priv(priv->parent_dev);
952 if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) {
953 priv->dev_descriptor.idVendor = (uint16_t)vid;
954 priv->dev_descriptor.idProduct = (uint16_t)pid;
956 usbi_warn(ctx, "could not infer VID/PID of HCD hub from '%s'", parent_priv->path);
957 priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub
958 priv->dev_descriptor.idProduct = 1;
960 return LIBUSB_SUCCESS;
964 * fetch and cache all the config descriptors through I/O
966 static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char* device_id)
968 DWORD size, ret_size;
969 struct libusb_context *ctx = DEVICE_CTX(dev);
970 struct windows_device_priv *priv = _device_priv(dev);
974 USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
975 PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
976 PUSB_CONFIGURATION_DESCRIPTOR cd_data = NULL;
978 if (dev->num_configurations == 0)
979 return LIBUSB_ERROR_INVALID_PARAM;
981 priv->config_descriptor = (unsigned char**) calloc(dev->num_configurations, sizeof(unsigned char*));
982 if (priv->config_descriptor == NULL)
983 return LIBUSB_ERROR_NO_MEM;
984 for (i=0; i<dev->num_configurations; i++)
985 priv->config_descriptor[i] = NULL;
987 for (i=0, r=LIBUSB_SUCCESS; ; i++)
989 // safe loop: release all dynamic resources
990 safe_free(cd_buf_actual);
992 // safe loop: end of loop condition
993 if ((i >= dev->num_configurations) || (r != LIBUSB_SUCCESS))
996 size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT);
997 memset(&cd_buf_short, 0, size);
999 cd_buf_short.req.ConnectionIndex = (ULONG)priv->port;
1000 cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1001 cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1002 cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1003 cd_buf_short.req.SetupPacket.wIndex = i;
1004 cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1006 // Dummy call to get the required data size. Initial failures are reported as info rather
1007 // than error as they can occur for non-penalizing situations, such as with some hubs.
1008 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
1009 &cd_buf_short, size, &ret_size, NULL)) {
1010 usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
1011 LOOP_BREAK(LIBUSB_ERROR_IO);
1014 if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
1015 usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
1016 LOOP_BREAK(LIBUSB_ERROR_IO);
1019 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
1020 if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
1021 usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
1022 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1024 memset(cd_buf_actual, 0, size);
1027 cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
1028 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1029 cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1030 cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1031 cd_buf_actual->SetupPacket.wIndex = i;
1032 cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1034 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1035 cd_buf_actual, size, &ret_size, NULL)) {
1036 usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1037 LOOP_BREAK(LIBUSB_ERROR_IO);
1040 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1042 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1043 usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1044 LOOP_BREAK(LIBUSB_ERROR_IO);
1047 if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1048 usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1049 LOOP_BREAK(LIBUSB_ERROR_IO);
1052 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1053 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1055 // Cache the descriptor
1056 priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1057 if (priv->config_descriptor[i] == NULL)
1058 return LIBUSB_ERROR_NO_MEM;
1059 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1061 return LIBUSB_SUCCESS;
1065 * Populate a libusbx device structure
1067 static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1068 uint8_t port_number, char* device_id, DWORD devinst)
1072 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1073 struct windows_device_priv *priv, *parent_priv;
1074 struct libusb_context *ctx = DEVICE_CTX(dev);
1075 struct libusb_device* tmp_dev;
1078 if ((dev == NULL) || (parent_dev == NULL)) {
1079 return LIBUSB_ERROR_NOT_FOUND;
1081 priv = _device_priv(dev);
1082 parent_priv = _device_priv(parent_dev);
1083 if (parent_priv->apib->id != USB_API_HUB) {
1084 usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1085 return LIBUSB_ERROR_NOT_FOUND;
1088 // It is possible for the parent hub not to have been initialized yet
1089 // If that's the case, lookup the ancestors to set the bus number
1090 if (parent_dev->bus_number == 0) {
1092 tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
1093 if (tmp_dev == NULL) break;
1094 if (tmp_dev->bus_number != 0) {
1095 usbi_dbg("got bus number from ancestor #%d", i);
1096 parent_dev->bus_number = tmp_dev->bus_number;
1101 if (parent_dev->bus_number == 0) {
1102 usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1103 return LIBUSB_ERROR_NOT_FOUND;
1105 dev->bus_number = parent_dev->bus_number;
1106 priv->port = port_number;
1107 dev->port_number = port_number;
1108 priv->depth = parent_priv->depth + 1;
1109 priv->parent_dev = parent_dev;
1110 dev->parent_dev = parent_dev;
1112 // If the device address is already set, we can stop here
1113 if (dev->device_address != 0) {
1114 return LIBUSB_SUCCESS;
1116 memset(&conn_info, 0, sizeof(conn_info));
1117 if (priv->depth != 0) { // Not a HCD hub
1118 handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1119 FILE_FLAG_OVERLAPPED, NULL);
1120 if (handle == INVALID_HANDLE_VALUE) {
1121 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1122 return LIBUSB_ERROR_ACCESS;
1124 size = sizeof(conn_info);
1125 conn_info.ConnectionIndex = (ULONG)port_number;
1126 if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1127 &conn_info, size, &size, NULL)) {
1128 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1129 device_id, windows_error_str(0));
1130 safe_closehandle(handle);
1131 return LIBUSB_ERROR_NO_DEVICE;
1133 if (conn_info.ConnectionStatus == NoDeviceConnected) {
1134 usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1135 safe_closehandle(handle);
1136 return LIBUSB_ERROR_NO_DEVICE;
1138 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1139 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1140 priv->active_config = conn_info.CurrentConfigurationValue;
1141 usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1142 // If we can't read the config descriptors, just set the number of confs to zero
1143 if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1144 dev->num_configurations = 0;
1145 priv->dev_descriptor.bNumConfigurations = 0;
1147 safe_closehandle(handle);
1149 if (conn_info.DeviceAddress > UINT8_MAX) {
1150 usbi_err(ctx, "program assertion failed: device address overflow");
1152 dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1153 if (dev->device_address == 1) {
1154 usbi_err(ctx, "program assertion failed: device address collision with root hub");
1156 switch (conn_info.Speed) {
1157 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1158 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1159 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1160 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1162 usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1166 dev->device_address = 1; // root hubs are set to use device number 1
1167 force_hcd_device_descriptor(dev);
1170 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1171 dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1173 return LIBUSB_SUCCESS;
1176 // Returns the api type, or 0 if not found/unsupported
1177 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1178 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1180 // Precedence for filter drivers vs driver is in the order of this array
1181 struct driver_lookup lookup[3] = {
1182 {"\0\0", SPDRP_SERVICE, "driver"},
1183 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1184 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1186 DWORD size, reg_type;
1190 *api = USB_API_UNSUPPORTED;
1191 *sub_api = SUB_API_NOTSET;
1192 // Check the service & filter names to know the API we should use
1193 for (k=0; k<3; k++) {
1194 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1195 ®_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1196 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1197 if (lookup[k].reg_prop == SPDRP_SERVICE) {
1198 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1199 lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1201 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1202 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1203 // (currently ';'), so even if an unsuported one does, it's not an issue
1204 for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1205 if (lookup[k].list[l] == 0) {
1206 lookup[k].list[l] = LIST_SEPARATOR;
1209 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1211 if (GetLastError() != ERROR_INVALID_DATA) {
1212 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1214 lookup[k].list[0] = 0;
1218 for (i=1; i<USB_API_MAX; i++) {
1219 for (k=0; k<3; k++) {
1220 j = get_sub_api(lookup[k].list, i);
1222 usbi_dbg("matched %s name against %s API",
1223 lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1232 static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1233 char* dev_interface_path, char* device_id, int api, int sub_api)
1236 struct windows_device_priv *priv = _device_priv(dev);
1237 int interface_number;
1239 if (priv->apib->id != USB_API_COMPOSITE) {
1240 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1241 return LIBUSB_ERROR_NO_DEVICE;
1244 // Because MI_## are not necessarily in sequential order (some composite
1245 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1246 // interface number from the path's MI value
1247 interface_number = 0;
1248 for (i=0; device_id[i] != 0; ) {
1249 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1250 && (device_id[i++] == '_') ) {
1251 interface_number = (device_id[i++] - '0')*10;
1252 interface_number += device_id[i] - '0';
1257 if (device_id[i] == 0) {
1258 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1259 device_id, interface_number);
1262 if (priv->usb_interface[interface_number].path != NULL) {
1263 if (api == USB_API_HID) {
1264 // HID devices can have multiple collections (COL##) for each MI_## interface
1265 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1266 interface_number, device_id);
1267 return LIBUSB_ERROR_ACCESS;
1269 // In other cases, just use the latest data
1270 safe_free(priv->usb_interface[interface_number].path);
1273 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1274 priv->usb_interface[interface_number].path = dev_interface_path;
1275 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1276 priv->usb_interface[interface_number].sub_api = sub_api;
1277 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1278 priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
1279 if (priv->hid == NULL)
1280 return LIBUSB_ERROR_NO_MEM;
1283 return LIBUSB_SUCCESS;
1286 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1287 char* dev_interface_path)
1289 struct windows_device_priv *priv = _device_priv(dev);
1291 if (priv->hid == NULL) {
1292 usbi_err(ctx, "program assertion failed: parent is not HID");
1293 return LIBUSB_ERROR_NO_DEVICE;
1295 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1296 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1297 return LIBUSB_ERROR_NO_DEVICE;
1299 if (priv->usb_interface[priv->hid->nb_interfaces].path != NULL) {
1300 safe_free(priv->usb_interface[priv->hid->nb_interfaces].path);
1303 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1304 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1305 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1306 priv->hid->nb_interfaces++;
1307 return LIBUSB_SUCCESS;
1311 * get_device_list: libusbx backend device enumeration function
1313 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1315 struct discovered_devs *discdevs;
1316 HDEVINFO dev_info = { 0 };
1317 const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1318 SP_DEVINFO_DATA dev_info_data = { 0 };
1319 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1321 #define MAX_ENUM_GUIDS 64
1322 const GUID* guid[MAX_ENUM_GUIDS];
1328 int r = LIBUSB_SUCCESS;
1330 size_t class_index = 0;
1331 unsigned int nb_guids, pass, i, j, ancestor;
1332 char path[MAX_PATH_LENGTH];
1333 char strbuf[MAX_PATH_LENGTH];
1334 struct libusb_device *dev, *parent_dev;
1335 struct windows_device_priv *priv, *parent_priv;
1336 char* dev_interface_path = NULL;
1337 char* dev_id_path = NULL;
1338 unsigned long session_id;
1339 DWORD size, reg_type, port_nr, install_state;
1341 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1344 // Keep a list of newly allocated devs to unref
1345 libusb_device** unref_list;
1346 unsigned int unref_size = 64;
1347 unsigned int unref_cur = 0;
1349 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1350 // PASS 2 : (re)enumerate HUBS
1351 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1352 // and list additional USB device interface GUIDs to explore
1353 // PASS 4 : (re)enumerate master USB devices that have a device interface
1354 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1355 // set the device interfaces.
1357 // Init the GUID table
1358 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1359 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1360 guid[GEN_PASS] = NULL;
1361 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1362 HidD_GetHidGuid(&hid_guid);
1363 guid[HID_PASS] = &hid_guid;
1364 nb_guids = HID_PASS+1;
1366 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1367 if (unref_list == NULL) {
1368 return LIBUSB_ERROR_NO_MEM;
1371 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1372 //#define ENUM_DEBUG
1374 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1375 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1376 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1378 for (i = 0; ; i++) {
1379 // safe loop: free up any (unprotected) dynamic resource
1380 // NB: this is always executed before breaking the loop
1381 safe_free(dev_interface_details);
1382 safe_free(dev_interface_path);
1383 safe_free(dev_id_path);
1384 priv = parent_priv = NULL;
1385 dev = parent_dev = NULL;
1387 // Safe loop: end of loop conditions
1388 if (r != LIBUSB_SUCCESS) {
1391 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1392 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1395 if (pass != GEN_PASS) {
1396 // Except for GEN, all passes deal with device interfaces
1397 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1398 if (dev_interface_details == NULL) {
1401 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1402 if (dev_interface_path == NULL) {
1403 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1408 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1409 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1410 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1411 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1412 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1416 if (class_index >= ARRAYSIZE(usb_class))
1420 // Read the Device ID path. This is what we'll use as UID
1421 // Note that if the device is plugged in a different port or hub, the Device ID changes
1422 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1423 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1424 dev_info_data.DevInst);
1427 dev_id_path = sanitize_path(path);
1428 if (dev_id_path == NULL) {
1429 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1430 dev_info_data.DevInst);
1434 usbi_dbg("PRO: %s", dev_id_path);
1437 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1439 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1440 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1441 ®_type, (BYTE*)&port_nr, 4, &size))
1443 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1444 dev_id_path, windows_error_str(0));
1449 // Set API to use or get additional data from generic pass
1450 api = USB_API_UNSUPPORTED;
1451 sub_api = SUB_API_NOTSET;
1456 // We use the GEN pass to detect driverless devices...
1457 size = sizeof(strbuf);
1458 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1459 ®_type, (BYTE*)strbuf, size, &size)) {
1460 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1461 usbi_info(ctx, "libusbx will not be able to access it.");
1463 // ...and to add the additional device interface GUIDs
1464 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1465 if (key != INVALID_HANDLE_VALUE) {
1466 size = sizeof(guid_string_w);
1467 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1468 (BYTE*)guid_string_w, &size);
1470 if (s == ERROR_SUCCESS) {
1471 if (nb_guids >= MAX_ENUM_GUIDS) {
1472 // If this assert is ever reported, grow a GUID table dynamically
1473 usbi_err(ctx, "program assertion failed: too many GUIDs");
1474 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1476 if_guid = (GUID*) calloc(1, sizeof(GUID));
1477 pCLSIDFromString(guid_string_w, if_guid);
1478 guid[nb_guids++] = if_guid;
1479 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1487 // Get the API type (after checking that the driver installation is OK)
1488 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1489 ®_type, (BYTE*)&install_state, 4, &size))
1491 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1492 dev_id_path, windows_error_str(0));
1493 } else if (install_state != 0) {
1494 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1495 dev_id_path, install_state);
1498 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1502 // Find parent device (for the passes that need it)
1509 // Go through the ancestors until we see a face we recognize
1511 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1512 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1513 if (session_id == 0) {
1516 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1518 if (parent_dev == NULL) {
1519 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1522 parent_priv = _device_priv(parent_dev);
1523 // virtual USB devices are also listed during GEN - don't process these yet
1524 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1530 // Create new or match existing device, using the (hashed) device_id as session id
1531 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1532 // These are the passes that create "new" devices
1533 session_id = htab_hash(dev_id_path);
1534 dev = usbi_get_device_by_session_id(ctx, session_id);
1536 if (pass == DEV_PASS) {
1537 // This can occur if the OS only reports a newly plugged device after we started enum
1538 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1539 " - ignoring", dev_id_path);
1542 usbi_dbg("allocating new device for session [%X]", session_id);
1543 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1544 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1546 windows_device_priv_init(dev);
1547 // Keep track of devices that need unref
1548 unref_list[unref_cur++] = dev;
1549 if (unref_cur >= unref_size) {
1551 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1552 if (unref_list == NULL) {
1553 usbi_err(ctx, "could not realloc list for unref - aborting.");
1554 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1558 usbi_dbg("found existing device for session [%X] (%d.%d)",
1559 session_id, dev->bus_number, dev->device_address);
1561 priv = _device_priv(dev);
1567 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1568 dev->device_address = 0;
1569 dev->num_configurations = 0;
1570 priv->apib = &usb_api_backend[USB_API_HUB];
1571 priv->sub_api = SUB_API_NOTSET;
1572 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1573 priv->path = dev_interface_path; dev_interface_path = NULL;
1577 // If the device has already been setup, don't do it again
1578 if (priv->path != NULL)
1580 // Take care of API initialization
1581 priv->path = dev_interface_path; dev_interface_path = NULL;
1582 priv->apib = &usb_api_backend[api];
1583 priv->sub_api = sub_api;
1585 case USB_API_COMPOSITE:
1589 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1590 if (priv->hid == NULL) {
1591 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1593 priv->hid->nb_interfaces = 0;
1596 // For other devices, the first interface is the same as the device
1597 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1598 if (priv->usb_interface[0].path != NULL) {
1599 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1601 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1603 // The following is needed if we want API calls to work for both simple
1604 // and composite devices.
1605 for(j=0; j<USB_MAXINTERFACES; j++) {
1606 priv->usb_interface[j].apib = &usb_api_backend[api];
1612 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1613 if (r == LIBUSB_SUCCESS) {
1614 // Append device to the list of discovered devices
1615 discdevs = discovered_devs_append(*_discdevs, dev);
1617 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1619 *_discdevs = discdevs;
1620 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1621 // This can occur if the device was disconnected but Windows hasn't
1622 // refreshed its enumeration yet - in that case, we ignore the device
1626 default: // HID_PASS and later
1627 if (parent_priv->apib->id == USB_API_HID) {
1628 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1629 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1630 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1631 dev_interface_path = NULL;
1632 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1633 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1634 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1635 case LIBUSB_SUCCESS:
1636 dev_interface_path = NULL;
1638 case LIBUSB_ERROR_ACCESS:
1639 // interface has already been set => make sure dev_interface_path is freed then
1651 // Free any additional GUIDs
1652 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1653 safe_free(guid[pass]);
1656 // Unref newly allocated devs
1657 for (i=0; i<unref_cur; i++) {
1658 safe_unref_device(unref_list[i]);
1660 safe_free(unref_list);
1666 * exit: libusbx backend deinitialization function
1668 static void windows_exit(void)
1672 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1674 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1675 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1676 if (semaphore == NULL) {
1680 // A successful wait brings our semaphore count to 0 (unsignaled)
1681 // => any concurent wait stalls until the semaphore release
1682 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1683 CloseHandle(semaphore);
1687 // Only works if exits and inits are balanced exactly
1688 if (--concurrent_usage < 0) { // Last exit
1689 for (i=0; i<USB_API_MAX; i++) {
1690 usb_api_backend[i].exit(SUB_API_NOTSET);
1695 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1696 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1697 usbi_dbg("could not wait for timer thread to quit");
1698 TerminateThread(timer_thread, 1);
1700 CloseHandle(timer_thread);
1701 timer_thread = NULL;
1703 for (i = 0; i < 2; i++) {
1704 if (timer_request[i]) {
1705 CloseHandle(timer_request[i]);
1706 timer_request[i] = NULL;
1709 if (timer_response) {
1710 CloseHandle(timer_response);
1711 timer_response = NULL;
1714 CloseHandle(timer_mutex);
1720 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1721 CloseHandle(semaphore);
1724 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1726 struct windows_device_priv *priv = _device_priv(dev);
1728 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1731 return LIBUSB_SUCCESS;
1734 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1736 struct windows_device_priv *priv = _device_priv(dev);
1737 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1740 // config index is zero based
1741 if (config_index >= dev->num_configurations)
1742 return LIBUSB_ERROR_INVALID_PARAM;
1744 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1745 return LIBUSB_ERROR_NOT_FOUND;
1747 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1749 size = min(config_header->wTotalLength, len);
1750 memcpy(buffer, priv->config_descriptor[config_index], size);
1752 return LIBUSB_SUCCESS;
1756 * return the cached copy of the active config descriptor
1758 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1760 struct windows_device_priv *priv = _device_priv(dev);
1762 if (priv->active_config == 0)
1763 return LIBUSB_ERROR_NOT_FOUND;
1765 // config index is zero based
1766 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1769 static int windows_open(struct libusb_device_handle *dev_handle)
1771 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1772 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1774 if (priv->apib == NULL) {
1775 usbi_err(ctx, "program assertion failed - device is not initialized");
1776 return LIBUSB_ERROR_NO_DEVICE;
1779 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1782 static void windows_close(struct libusb_device_handle *dev_handle)
1784 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1786 priv->apib->close(SUB_API_NOTSET, dev_handle);
1789 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1791 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1793 if (priv->active_config == 0) {
1795 return LIBUSB_ERROR_NOT_FOUND;
1798 *config = priv->active_config;
1799 return LIBUSB_SUCCESS;
1803 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1804 * does not currently expose a service that allows higher-level drivers to set
1805 * the configuration."
1807 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1809 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1810 int r = LIBUSB_SUCCESS;
1812 if (config >= USB_MAXCONFIG)
1813 return LIBUSB_ERROR_INVALID_PARAM;
1815 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1816 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1817 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1820 if (r == LIBUSB_SUCCESS) {
1821 priv->active_config = (uint8_t)config;
1826 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1828 int r = LIBUSB_SUCCESS;
1829 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1831 if (iface >= USB_MAXINTERFACES)
1832 return LIBUSB_ERROR_INVALID_PARAM;
1834 safe_free(priv->usb_interface[iface].endpoint);
1835 priv->usb_interface[iface].nb_endpoints= 0;
1837 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1839 if (r == LIBUSB_SUCCESS) {
1840 r = windows_assign_endpoints(dev_handle, iface, 0);
1846 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1848 int r = LIBUSB_SUCCESS;
1849 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1851 safe_free(priv->usb_interface[iface].endpoint);
1852 priv->usb_interface[iface].nb_endpoints= 0;
1854 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1856 if (r == LIBUSB_SUCCESS) {
1857 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1863 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1865 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1867 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1870 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1872 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1873 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1876 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1878 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1879 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1882 // The 3 functions below are unlikely to ever get supported on Windows
1883 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1885 return LIBUSB_ERROR_NOT_SUPPORTED;
1888 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1890 return LIBUSB_ERROR_NOT_SUPPORTED;
1893 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1895 return LIBUSB_ERROR_NOT_SUPPORTED;
1898 static void windows_destroy_device(struct libusb_device *dev)
1900 windows_device_priv_release(dev);
1903 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1905 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1907 usbi_free_fd(transfer_priv->pollable_fd.fd);
1908 safe_free(transfer_priv->hid_buffer);
1909 // When auto claim is in use, attempt to release the auto-claimed interface
1910 auto_release(itransfer);
1913 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1915 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1916 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1917 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1918 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1921 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1922 if (r != LIBUSB_SUCCESS) {
1926 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1927 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1929 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1930 return LIBUSB_SUCCESS;
1933 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1935 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1936 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1937 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1938 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1941 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1942 if (r != LIBUSB_SUCCESS) {
1946 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1947 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1949 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1950 return LIBUSB_SUCCESS;
1953 static int submit_control_transfer(struct usbi_transfer *itransfer)
1955 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1956 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1957 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1958 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1961 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1962 if (r != LIBUSB_SUCCESS) {
1966 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
1968 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1969 return LIBUSB_SUCCESS;
1973 static int windows_submit_transfer(struct usbi_transfer *itransfer)
1975 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1977 switch (transfer->type) {
1978 case LIBUSB_TRANSFER_TYPE_CONTROL:
1979 return submit_control_transfer(itransfer);
1980 case LIBUSB_TRANSFER_TYPE_BULK:
1981 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1982 if (IS_XFEROUT(transfer) &&
1983 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
1984 return LIBUSB_ERROR_NOT_SUPPORTED;
1985 return submit_bulk_transfer(itransfer);
1986 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1987 return submit_iso_transfer(itransfer);
1989 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1990 return LIBUSB_ERROR_INVALID_PARAM;
1994 static int windows_abort_control(struct usbi_transfer *itransfer)
1996 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1997 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1999 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2002 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2004 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2005 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2007 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2010 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2012 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2014 switch (transfer->type) {
2015 case LIBUSB_TRANSFER_TYPE_CONTROL:
2016 return windows_abort_control(itransfer);
2017 case LIBUSB_TRANSFER_TYPE_BULK:
2018 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2019 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2020 return windows_abort_transfers(itransfer);
2022 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2023 return LIBUSB_ERROR_INVALID_PARAM;
2027 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2029 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2030 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2031 int status, istatus;
2033 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
2037 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2039 case ERROR_GEN_FAILURE:
2040 usbi_dbg("detected endpoint stall");
2041 status = LIBUSB_TRANSFER_STALL;
2043 case ERROR_SEM_TIMEOUT:
2044 usbi_dbg("detected semaphore timeout");
2045 status = LIBUSB_TRANSFER_TIMED_OUT;
2047 case ERROR_OPERATION_ABORTED:
2048 istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2049 if (istatus != LIBUSB_TRANSFER_COMPLETED) {
2050 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
2052 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2053 usbi_dbg("detected timeout");
2054 status = LIBUSB_TRANSFER_TIMED_OUT;
2056 usbi_dbg("detected operation aborted");
2057 status = LIBUSB_TRANSFER_CANCELLED;
2061 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(0));
2062 status = LIBUSB_TRANSFER_ERROR;
2065 windows_clear_transfer_priv(itransfer); // Cancel polling
2066 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2069 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2071 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2073 switch (transfer->type) {
2074 case LIBUSB_TRANSFER_TYPE_CONTROL:
2075 case LIBUSB_TRANSFER_TYPE_BULK:
2076 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2077 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2078 windows_transfer_callback (itransfer, io_result, io_size);
2081 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2085 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2087 struct windows_transfer_priv* transfer_priv = NULL;
2088 POLL_NFDS_TYPE i = 0;
2090 struct usbi_transfer *transfer;
2091 DWORD io_size, io_result;
2093 usbi_mutex_lock(&ctx->open_devs_lock);
2094 for (i = 0; i < nfds && num_ready > 0; i++) {
2096 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2098 if (!fds[i].revents) {
2104 // Because a Windows OVERLAPPED is used for poll emulation,
2105 // a pollable fd is created and stored with each transfer
2106 usbi_mutex_lock(&ctx->flying_transfers_lock);
2107 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2108 transfer_priv = usbi_transfer_get_os_priv(transfer);
2109 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2114 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2117 // Handle async requests that completed synchronously first
2118 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2119 io_result = NO_ERROR;
2120 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2121 // Regular async overlapped
2122 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2123 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2124 io_result = NO_ERROR;
2126 io_result = GetLastError();
2128 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2129 // let handle_callback free the event using the transfer wfd
2130 // If you don't use the transfer wfd, you run a risk of trying to free a
2131 // newly allocated wfd that took the place of the one from the transfer.
2132 windows_handle_callback(transfer, io_result, io_size);
2134 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2135 return LIBUSB_ERROR_NOT_FOUND;
2139 usbi_mutex_unlock(&ctx->open_devs_lock);
2140 return LIBUSB_SUCCESS;
2144 * Monotonic and real time functions
2146 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2148 LARGE_INTEGER hires_counter, li_frequency;
2152 // Init - find out if we have access to a monotonic (hires) timer
2153 if (!QueryPerformanceFrequency(&li_frequency)) {
2154 usbi_dbg("no hires timer available on this platform");
2155 hires_frequency = 0;
2156 hires_ticks_to_ps = UINT64_C(0);
2158 hires_frequency = li_frequency.QuadPart;
2159 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2160 // to picoseconds to compute the tv_nsecs part in clock_gettime
2161 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2162 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2165 // Main loop - wait for requests
2167 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2168 if ( (timer_index != 0) && (timer_index != 1) ) {
2169 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2172 if (request_count[timer_index] == 0) {
2173 // Request already handled
2174 ResetEvent(timer_request[timer_index]);
2175 // There's still a possiblity that a thread sends a request between the
2176 // time we test request_count[] == 0 and we reset the event, in which case
2177 // the request would be ignored. The simple solution to that is to test
2178 // request_count again and process requests if non zero.
2179 if (request_count[timer_index] == 0)
2182 switch (timer_index) {
2184 WaitForSingleObject(timer_mutex, INFINITE);
2185 // Requests to this thread are for hires always
2186 if (QueryPerformanceCounter(&hires_counter) != 0) {
2187 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2188 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2190 // Fallback to real-time if we can't get monotonic value
2191 // Note that real-time clock does not wait on the mutex or this thread.
2192 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2194 ReleaseMutex(timer_mutex);
2196 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2198 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2199 usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0));
2202 case 1: // time to quit
2203 usbi_dbg("timer thread quitting");
2209 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2212 ULARGE_INTEGER rtime;
2215 case USBI_CLOCK_MONOTONIC:
2216 if (hires_frequency != 0) {
2218 InterlockedIncrement((LONG*)&request_count[0]);
2219 SetEvent(timer_request[0]);
2220 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2223 WaitForSingleObject(timer_mutex, INFINITE);
2225 ReleaseMutex(timer_mutex);
2226 return LIBUSB_SUCCESS;
2228 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2229 break; // Retry until successful
2231 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2232 return LIBUSB_ERROR_OTHER;
2236 // Fall through and return real-time if monotonic was not detected @ timer init
2237 case USBI_CLOCK_REALTIME:
2238 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2239 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2240 // Note however that our resolution is bounded by the Windows system time
2241 // functions and is at best of the order of 1 ms (or, usually, worse)
2242 GetSystemTimeAsFileTime(&filetime);
2243 rtime.LowPart = filetime.dwLowDateTime;
2244 rtime.HighPart = filetime.dwHighDateTime;
2245 rtime.QuadPart -= epoch_time;
2246 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2247 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2248 return LIBUSB_SUCCESS;
2250 return LIBUSB_ERROR_INVALID_PARAM;
2255 // NB: MSVC6 does not support named initializers.
2256 const struct usbi_os_backend windows_backend = {
2261 windows_get_device_list,
2265 windows_get_device_descriptor,
2266 windows_get_active_config_descriptor,
2267 windows_get_config_descriptor,
2269 windows_get_configuration,
2270 windows_set_configuration,
2271 windows_claim_interface,
2272 windows_release_interface,
2274 windows_set_interface_altsetting,
2276 windows_reset_device,
2278 windows_kernel_driver_active,
2279 windows_detach_kernel_driver,
2280 windows_attach_kernel_driver,
2282 windows_destroy_device,
2284 windows_submit_transfer,
2285 windows_cancel_transfer,
2286 windows_clear_transfer_priv,
2288 windows_handle_events,
2290 windows_clock_gettime,
2291 #if defined(USBI_TIMERFD_AVAILABLE)
2294 sizeof(struct windows_device_priv),
2295 sizeof(struct windows_device_handle_priv),
2296 sizeof(struct windows_transfer_priv),
2304 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2305 return LIBUSB_SUCCESS;
2307 static int unsupported_exit(int sub_api) {
2308 return LIBUSB_SUCCESS;
2310 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2311 PRINT_UNSUPPORTED_API(open);
2313 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2314 usbi_dbg("unsupported API call for 'close'");
2316 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2317 PRINT_UNSUPPORTED_API(configure_endpoints);
2319 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2320 PRINT_UNSUPPORTED_API(claim_interface);
2322 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2323 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2325 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2326 PRINT_UNSUPPORTED_API(release_interface);
2328 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2329 PRINT_UNSUPPORTED_API(clear_halt);
2331 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2332 PRINT_UNSUPPORTED_API(reset_device);
2334 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2335 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2337 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2338 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2340 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2341 PRINT_UNSUPPORTED_API(submit_control_transfer);
2343 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2344 PRINT_UNSUPPORTED_API(abort_control);
2346 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2347 PRINT_UNSUPPORTED_API(abort_transfers);
2349 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2350 PRINT_UNSUPPORTED_API(copy_transfer_data);
2352 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2353 return LIBUSB_SUCCESS;
2355 // These names must be uppercase
2356 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2357 const char* composite_driver_names[] = {"USBCCGP"};
2358 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2359 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2360 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2362 USB_API_UNSUPPORTED,
2370 unsupported_configure_endpoints,
2371 unsupported_claim_interface,
2372 unsupported_set_interface_altsetting,
2373 unsupported_release_interface,
2374 unsupported_clear_halt,
2375 unsupported_reset_device,
2376 unsupported_submit_bulk_transfer,
2377 unsupported_submit_iso_transfer,
2378 unsupported_submit_control_transfer,
2379 unsupported_abort_control,
2380 unsupported_abort_transfers,
2381 unsupported_copy_transfer_data,
2386 ARRAYSIZE(hub_driver_names),
2391 unsupported_configure_endpoints,
2392 unsupported_claim_interface,
2393 unsupported_set_interface_altsetting,
2394 unsupported_release_interface,
2395 unsupported_clear_halt,
2396 unsupported_reset_device,
2397 unsupported_submit_bulk_transfer,
2398 unsupported_submit_iso_transfer,
2399 unsupported_submit_control_transfer,
2400 unsupported_abort_control,
2401 unsupported_abort_transfers,
2402 unsupported_copy_transfer_data,
2406 composite_driver_names,
2407 ARRAYSIZE(composite_driver_names),
2412 common_configure_endpoints,
2413 composite_claim_interface,
2414 composite_set_interface_altsetting,
2415 composite_release_interface,
2416 composite_clear_halt,
2417 composite_reset_device,
2418 composite_submit_bulk_transfer,
2419 composite_submit_iso_transfer,
2420 composite_submit_control_transfer,
2421 composite_abort_control,
2422 composite_abort_transfers,
2423 composite_copy_transfer_data,
2427 winusbx_driver_names,
2428 ARRAYSIZE(winusbx_driver_names),
2433 winusbx_configure_endpoints,
2434 winusbx_claim_interface,
2435 winusbx_set_interface_altsetting,
2436 winusbx_release_interface,
2438 winusbx_reset_device,
2439 winusbx_submit_bulk_transfer,
2440 unsupported_submit_iso_transfer,
2441 winusbx_submit_control_transfer,
2442 winusbx_abort_control,
2443 winusbx_abort_transfers,
2444 winusbx_copy_transfer_data,
2449 ARRAYSIZE(hid_driver_names),
2454 common_configure_endpoints,
2455 hid_claim_interface,
2456 hid_set_interface_altsetting,
2457 hid_release_interface,
2460 hid_submit_bulk_transfer,
2461 unsupported_submit_iso_transfer,
2462 hid_submit_control_transfer,
2463 hid_abort_transfers,
2464 hid_abort_transfers,
2465 hid_copy_transfer_data,
2471 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2473 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2474 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2476 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2479 bool native_winusb = false;
2481 KLIB_VERSION LibK_Version;
2482 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2483 LibK_GetVersion_t pLibK_GetVersion = NULL;
2485 h = GetModuleHandleA("libusbK");
2487 h = LoadLibraryA("libusbK");
2490 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2491 h = GetModuleHandleA("WinUSB");
2493 h = LoadLibraryA("WinUSB");
2495 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2496 "you will not be able to access devices outside of enumeration");
2497 return LIBUSB_ERROR_NOT_FOUND;
2500 usbi_dbg("using libusbK DLL for universal access");
2501 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2502 if (pLibK_GetVersion != NULL) {
2503 pLibK_GetVersion(&LibK_Version);
2504 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2505 LibK_Version.Micro, LibK_Version.Nano);
2507 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2508 if (pLibK_GetProcAddress == NULL) {
2509 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2510 return LIBUSB_ERROR_NOT_FOUND;
2513 native_winusb = (pLibK_GetProcAddress == NULL);
2514 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2515 WinUSBX_Set(AbortPipe);
2516 WinUSBX_Set(ControlTransfer);
2517 WinUSBX_Set(FlushPipe);
2519 WinUSBX_Set(GetAssociatedInterface);
2520 WinUSBX_Set(GetCurrentAlternateSetting);
2521 WinUSBX_Set(GetDescriptor);
2522 WinUSBX_Set(GetOverlappedResult);
2523 WinUSBX_Set(GetPipePolicy);
2524 WinUSBX_Set(GetPowerPolicy);
2525 WinUSBX_Set(Initialize);
2526 WinUSBX_Set(QueryDeviceInformation);
2527 WinUSBX_Set(QueryInterfaceSettings);
2528 WinUSBX_Set(QueryPipe);
2529 WinUSBX_Set(ReadPipe);
2530 WinUSBX_Set(ResetPipe);
2531 WinUSBX_Set(SetCurrentAlternateSetting);
2532 WinUSBX_Set(SetPipePolicy);
2533 WinUSBX_Set(SetPowerPolicy);
2534 WinUSBX_Set(WritePipe);
2535 if (!native_winusb) {
2536 WinUSBX_Set(ResetDevice);
2538 if (WinUSBX[i].Initialize != NULL) {
2539 WinUSBX[i].initialized = true;
2540 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2542 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2543 WinUSBX[i].initialized = false;
2546 return LIBUSB_SUCCESS;
2549 static int winusbx_exit(int sub_api)
2551 return LIBUSB_SUCCESS;
2554 // NB: open and close must ensure that they only handle interface of
2555 // the right API type, as these functions can be called wholesale from
2556 // composite_open(), with interfaces belonging to different APIs
2557 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2559 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2560 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2561 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2566 CHECK_WINUSBX_AVAILABLE(sub_api);
2568 // WinUSB requires a seperate handle for each interface
2569 for (i = 0; i < USB_MAXINTERFACES; i++) {
2570 if ( (priv->usb_interface[i].path != NULL)
2571 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2572 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2573 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2574 if (file_handle == INVALID_HANDLE_VALUE) {
2575 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2576 switch(GetLastError()) {
2577 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2578 return LIBUSB_ERROR_NO_DEVICE;
2579 case ERROR_ACCESS_DENIED:
2580 return LIBUSB_ERROR_ACCESS;
2582 return LIBUSB_ERROR_IO;
2585 handle_priv->interface_handle[i].dev_handle = file_handle;
2589 return LIBUSB_SUCCESS;
2592 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2594 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2595 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2599 if (sub_api == SUB_API_NOTSET)
2600 sub_api = priv->sub_api;
2601 if (!WinUSBX[sub_api].initialized)
2604 for (i = 0; i < USB_MAXINTERFACES; i++) {
2605 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2606 file_handle = handle_priv->interface_handle[i].dev_handle;
2607 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2608 CloseHandle(file_handle);
2614 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2616 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2617 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2618 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2621 uint8_t endpoint_address;
2624 CHECK_WINUSBX_AVAILABLE(sub_api);
2626 // With handle and enpoints set (in parent), we can setup the default pipe properties
2627 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2628 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2629 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2630 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2631 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2632 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2634 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2635 continue; // Other policies don't apply to control endpoint or libusb0
2638 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2639 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2640 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2642 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2643 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2644 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2647 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2648 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2649 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2650 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2651 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2653 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2654 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2655 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2659 return LIBUSB_SUCCESS;
2662 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2664 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2665 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2666 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2667 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2668 HANDLE file_handle, winusb_handle;
2671 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2673 SP_DEVINFO_DATA dev_info_data;
2674 char* dev_path_no_guid = NULL;
2675 char filter_path[] = "\\\\.\\libusb0-0000";
2676 bool found_filter = false;
2678 CHECK_WINUSBX_AVAILABLE(sub_api);
2680 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2681 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2682 if ((is_using_usbccgp) || (iface == 0)) {
2683 // composite device (independent interfaces) or interface 0
2684 file_handle = handle_priv->interface_handle[iface].dev_handle;
2685 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2686 return LIBUSB_ERROR_NOT_FOUND;
2689 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2690 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2691 err = GetLastError();
2693 case ERROR_BAD_COMMAND:
2694 // The device was disconnected
2695 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2696 return LIBUSB_ERROR_NO_DEVICE;
2698 // it may be that we're using the libusb0 filter driver.
2699 // TODO: can we move this whole business into the K/0 DLL?
2700 for (i = 0; ; i++) {
2701 safe_free(dev_interface_details);
2702 safe_free(dev_path_no_guid);
2703 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2704 if ((found_filter) || (dev_interface_details == NULL)) {
2708 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2709 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2710 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2711 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2712 if (file_handle == INVALID_HANDLE_VALUE) {
2713 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2715 WinUSBX[sub_api].Free(winusb_handle);
2716 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2719 found_filter = true;
2724 if (!found_filter) {
2725 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2726 return LIBUSB_ERROR_ACCESS;
2730 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2732 // For all other interfaces, use GetAssociatedInterface()
2733 winusb_handle = handle_priv->interface_handle[0].api_handle;
2734 // It is a requirement for multiple interface devices on Windows that, to you
2735 // must first claim the first interface before you claim the others
2736 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2737 file_handle = handle_priv->interface_handle[0].dev_handle;
2738 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2739 handle_priv->interface_handle[0].api_handle = winusb_handle;
2740 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2742 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2743 return LIBUSB_ERROR_ACCESS;
2746 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2747 &handle_priv->interface_handle[iface].api_handle)) {
2748 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2749 switch(GetLastError()) {
2750 case ERROR_NO_MORE_ITEMS: // invalid iface
2751 return LIBUSB_ERROR_NOT_FOUND;
2752 case ERROR_BAD_COMMAND: // The device was disconnected
2753 return LIBUSB_ERROR_NO_DEVICE;
2754 case ERROR_ALREADY_EXISTS: // already claimed
2755 return LIBUSB_ERROR_BUSY;
2757 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2758 return LIBUSB_ERROR_ACCESS;
2762 usbi_dbg("claimed interface %d", iface);
2763 handle_priv->active_interface = iface;
2765 return LIBUSB_SUCCESS;
2768 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2770 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2771 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2772 HANDLE winusb_handle;
2774 CHECK_WINUSBX_AVAILABLE(sub_api);
2776 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2777 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2778 return LIBUSB_ERROR_NOT_FOUND;
2781 WinUSBX[sub_api].Free(winusb_handle);
2782 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2784 return LIBUSB_SUCCESS;
2788 * Return the first valid interface (of the same API type), for control transfers
2790 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2792 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2793 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2796 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2797 usbi_dbg("unsupported API ID");
2801 for (i=0; i<USB_MAXINTERFACES; i++) {
2802 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2803 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2804 && (handle_priv->interface_handle[i].api_handle != 0)
2805 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2806 && (priv->usb_interface[i].apib->id == api_id) ) {
2814 * Lookup interface by endpoint address. -1 if not found
2816 static int interface_by_endpoint(struct windows_device_priv *priv,
2817 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2820 for (i=0; i<USB_MAXINTERFACES; i++) {
2821 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2823 if (handle_priv->interface_handle[i].api_handle == 0)
2825 if (priv->usb_interface[i].endpoint == NULL)
2827 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2828 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2836 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2838 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2839 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2840 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2841 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2842 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2843 transfer->dev_handle);
2844 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2846 HANDLE winusb_handle;
2847 int current_interface;
2850 CHECK_WINUSBX_AVAILABLE(sub_api);
2852 transfer_priv->pollable_fd = INVALID_WINFD;
2853 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2855 if (size > MAX_CTRL_BUFFER_LENGTH)
2856 return LIBUSB_ERROR_INVALID_PARAM;
2858 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2859 if (current_interface < 0) {
2860 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2861 return LIBUSB_ERROR_NOT_FOUND;
2865 usbi_dbg("will use interface %d", current_interface);
2866 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2868 wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
2869 // Always use the handle returned from usbi_create_fd (wfd.handle)
2871 return LIBUSB_ERROR_NO_MEM;
2874 // Sending of set configuration control requests from WinUSB creates issues
2875 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2876 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2877 if (setup->value != priv->active_config) {
2878 usbi_warn(ctx, "cannot set configuration other than the default one");
2879 usbi_free_fd(wfd.fd);
2880 return LIBUSB_ERROR_INVALID_PARAM;
2882 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2883 wfd.overlapped->InternalHigh = 0;
2885 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2886 if(GetLastError() != ERROR_IO_PENDING) {
2887 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2888 usbi_free_fd(wfd.fd);
2889 return LIBUSB_ERROR_IO;
2892 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2893 wfd.overlapped->InternalHigh = (DWORD)size;
2897 // Use priv_transfer to store data needed for async polling
2898 transfer_priv->pollable_fd = wfd;
2899 transfer_priv->interface_number = (uint8_t)current_interface;
2901 return LIBUSB_SUCCESS;
2904 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2906 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2907 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2908 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2909 HANDLE winusb_handle;
2911 CHECK_WINUSBX_AVAILABLE(sub_api);
2913 if (altsetting > 255) {
2914 return LIBUSB_ERROR_INVALID_PARAM;
2917 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2918 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2919 usbi_err(ctx, "interface must be claimed first");
2920 return LIBUSB_ERROR_NOT_FOUND;
2923 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2924 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2925 return LIBUSB_ERROR_IO;
2928 return LIBUSB_SUCCESS;
2931 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2933 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2934 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2935 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2936 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2937 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2938 HANDLE winusb_handle;
2940 int current_interface;
2943 CHECK_WINUSBX_AVAILABLE(sub_api);
2945 transfer_priv->pollable_fd = INVALID_WINFD;
2947 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2948 if (current_interface < 0) {
2949 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2950 return LIBUSB_ERROR_NOT_FOUND;
2953 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2955 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2957 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
2958 // Always use the handle returned from usbi_create_fd (wfd.handle)
2960 return LIBUSB_ERROR_NO_MEM;
2963 if (IS_XFERIN(transfer)) {
2964 usbi_dbg("reading %d bytes", transfer->length);
2965 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2967 usbi_dbg("writing %d bytes", transfer->length);
2968 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2971 if(GetLastError() != ERROR_IO_PENDING) {
2972 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2973 usbi_free_fd(wfd.fd);
2974 return LIBUSB_ERROR_IO;
2977 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2978 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
2981 transfer_priv->pollable_fd = wfd;
2982 transfer_priv->interface_number = (uint8_t)current_interface;
2984 return LIBUSB_SUCCESS;
2987 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
2989 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2990 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2991 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2992 HANDLE winusb_handle;
2993 int current_interface;
2995 CHECK_WINUSBX_AVAILABLE(sub_api);
2997 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
2998 if (current_interface < 0) {
2999 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3000 return LIBUSB_ERROR_NOT_FOUND;
3003 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3004 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3006 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3007 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3008 return LIBUSB_ERROR_NO_DEVICE;
3011 return LIBUSB_SUCCESS;
3015 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3016 * through testing as well):
3017 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3018 * the control transfer using CancelIo"
3020 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3022 // Cancelling of the I/O is done in the parent
3023 return LIBUSB_SUCCESS;
3026 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3028 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3029 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3030 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3031 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3032 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3033 HANDLE winusb_handle;
3034 int current_interface;
3036 CHECK_WINUSBX_AVAILABLE(sub_api);
3038 current_interface = transfer_priv->interface_number;
3039 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3040 usbi_err(ctx, "program assertion failed: invalid interface_number");
3041 return LIBUSB_ERROR_NOT_FOUND;
3043 usbi_dbg("will use interface %d", current_interface);
3045 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3047 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3048 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3049 return LIBUSB_ERROR_NO_DEVICE;
3052 return LIBUSB_SUCCESS;
3056 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3057 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3058 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3059 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3060 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3061 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3063 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3064 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3066 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3067 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3068 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3070 HANDLE winusb_handle;
3073 CHECK_WINUSBX_AVAILABLE(sub_api);
3075 // Reset any available pipe (except control)
3076 for (i=0; i<USB_MAXINTERFACES; i++) {
3077 winusb_handle = handle_priv->interface_handle[i].api_handle;
3078 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3080 // Cancel any pollable I/O
3081 usbi_remove_pollfd(ctx, wfd.fd);
3082 usbi_free_fd(wfd.fd);
3083 wfd = handle_to_winfd(winusb_handle);
3086 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3087 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3088 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3089 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3090 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3091 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3093 // FlushPipe seems to fail on OUT pipes
3094 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3095 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3096 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3097 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3099 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3100 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3101 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3107 // libusbK & libusb0 have the ability to issue an actual device reset
3108 if (WinUSBX[sub_api].ResetDevice != NULL) {
3109 winusb_handle = handle_priv->interface_handle[0].api_handle;
3110 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3111 WinUSBX[sub_api].ResetDevice(winusb_handle);
3114 return LIBUSB_SUCCESS;
3117 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3119 itransfer->transferred += io_size;
3120 return LIBUSB_TRANSFER_COMPLETED;
3124 * Internal HID Support functions (from libusb-win32)
3125 * Note that functions that complete data transfer synchronously must return
3126 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3128 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3129 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3131 static int _hid_wcslen(WCHAR *str)
3134 while (str[i] && (str[i] != 0x409)) {
3140 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3142 struct libusb_device_descriptor d;
3144 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3145 d.bDescriptorType = LIBUSB_DT_DEVICE;
3146 d.bcdUSB = 0x0200; /* 2.00 */
3148 d.bDeviceSubClass = 0;
3149 d.bDeviceProtocol = 0;
3150 d.bMaxPacketSize0 = 64; /* fix this! */
3151 d.idVendor = (uint16_t)dev->vid;
3152 d.idProduct = (uint16_t)dev->pid;
3153 d.bcdDevice = 0x0100;
3154 d.iManufacturer = dev->string_index[0];
3155 d.iProduct = dev->string_index[1];
3156 d.iSerialNumber = dev->string_index[2];
3157 d.bNumConfigurations = 1;
3159 if (*size > LIBUSB_DT_DEVICE_SIZE)
3160 *size = LIBUSB_DT_DEVICE_SIZE;
3161 memcpy(data, &d, *size);
3162 return LIBUSB_COMPLETED;
3165 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3167 char num_endpoints = 0;
3168 size_t config_total_len = 0;
3169 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3170 struct libusb_config_descriptor *cd;
3171 struct libusb_interface_descriptor *id;
3172 struct libusb_hid_descriptor *hd;
3173 struct libusb_endpoint_descriptor *ed;
3176 if (dev->input_report_size)
3178 if (dev->output_report_size)
3181 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3182 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3185 cd = (struct libusb_config_descriptor *)tmp;
3186 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3187 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3188 + LIBUSB_DT_INTERFACE_SIZE);
3189 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3190 + LIBUSB_DT_INTERFACE_SIZE
3191 + LIBUSB_DT_HID_SIZE);
3193 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3194 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3195 cd->wTotalLength = (uint16_t) config_total_len;
3196 cd->bNumInterfaces = 1;
3197 cd->bConfigurationValue = 1;
3198 cd->iConfiguration = 0;
3199 cd->bmAttributes = 1 << 7; /* bus powered */
3202 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3203 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3204 id->bInterfaceNumber = 0;
3205 id->bAlternateSetting = 0;
3206 id->bNumEndpoints = num_endpoints;
3207 id->bInterfaceClass = 3;
3208 id->bInterfaceSubClass = 0;
3209 id->bInterfaceProtocol = 0;
3212 tmp_size = LIBUSB_DT_HID_SIZE;
3213 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3215 if (dev->input_report_size) {
3216 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3217 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3218 ed->bEndpointAddress = HID_IN_EP;
3219 ed->bmAttributes = 3;
3220 ed->wMaxPacketSize = dev->input_report_size - 1;
3226 if (dev->output_report_size) {
3227 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3228 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3229 ed->bEndpointAddress = HID_OUT_EP;
3230 ed->bmAttributes = 3;
3231 ed->wMaxPacketSize = dev->output_report_size - 1;
3235 if (*size > config_total_len)
3236 *size = config_total_len;
3237 memcpy(data, tmp, *size);
3238 return LIBUSB_COMPLETED;
3241 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3242 void *data, size_t *size)
3245 size_t tmp_size = 0;
3248 /* language ID, EN-US */
3249 char string_langid[] = {
3254 if ((*size < 2) || (*size > 255)) {
3255 return LIBUSB_ERROR_OVERFLOW;
3259 tmp = string_langid;
3260 tmp_size = sizeof(string_langid)+2;
3262 for (i=0; i<3; i++) {
3263 if (_index == (dev->string_index[i])) {
3264 tmp = dev->string[i];
3265 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3269 if (i == 3) { // not found
3270 return LIBUSB_ERROR_INVALID_PARAM;
3275 return LIBUSB_ERROR_INVALID_PARAM;
3278 if (tmp_size < *size) {
3282 ((uint8_t*)data)[0] = (uint8_t)*size;
3283 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3284 memcpy((uint8_t*)data+2, tmp, *size-2);
3285 return LIBUSB_COMPLETED;
3288 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3290 struct libusb_hid_descriptor d;
3291 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3292 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3294 _hid_get_report_descriptor(dev, tmp, &report_len);
3296 d.bLength = LIBUSB_DT_HID_SIZE;
3297 d.bDescriptorType = LIBUSB_DT_HID;
3298 d.bcdHID = 0x0110; /* 1.10 */
3300 d.bNumDescriptors = 1;
3301 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3302 d.wClassDescriptorLength = (uint16_t)report_len;
3304 if (*size > LIBUSB_DT_HID_SIZE)
3305 *size = LIBUSB_DT_HID_SIZE;
3306 memcpy(data, &d, *size);
3307 return LIBUSB_COMPLETED;
3310 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3312 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3315 /* usage page (0xFFA0 == vendor defined) */
3316 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3317 /* usage (vendor defined) */
3318 d[i++] = 0x09; d[i++] = 0x01;
3319 /* start collection (application) */
3320 d[i++] = 0xA1; d[i++] = 0x01;
3322 if (dev->input_report_size) {
3323 /* usage (vendor defined) */
3324 d[i++] = 0x09; d[i++] = 0x01;
3325 /* logical minimum (0) */
3326 d[i++] = 0x15; d[i++] = 0x00;
3327 /* logical maximum (255) */
3328 d[i++] = 0x25; d[i++] = 0xFF;
3329 /* report size (8 bits) */
3330 d[i++] = 0x75; d[i++] = 0x08;
3332 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3333 /* input (data, variable, absolute) */
3334 d[i++] = 0x81; d[i++] = 0x00;
3337 if (dev->output_report_size) {
3338 /* usage (vendor defined) */
3339 d[i++] = 0x09; d[i++] = 0x02;
3340 /* logical minimum (0) */
3341 d[i++] = 0x15; d[i++] = 0x00;
3342 /* logical maximum (255) */
3343 d[i++] = 0x25; d[i++] = 0xFF;
3344 /* report size (8 bits) */
3345 d[i++] = 0x75; d[i++] = 0x08;
3347 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3348 /* output (data, variable, absolute) */
3349 d[i++] = 0x91; d[i++] = 0x00;
3351 /* feature report */
3352 if (dev->feature_report_size) {
3353 /* usage (vendor defined) */
3354 d[i++] = 0x09; d[i++] = 0x03;
3355 /* logical minimum (0) */
3356 d[i++] = 0x15; d[i++] = 0x00;
3357 /* logical maximum (255) */
3358 d[i++] = 0x25; d[i++] = 0xFF;
3359 /* report size (8 bits) */
3360 d[i++] = 0x75; d[i++] = 0x08;
3362 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3363 /* feature (data, variable, absolute) */
3364 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3367 /* end collection */
3372 memcpy(data, d, *size);
3373 return LIBUSB_COMPLETED;
3376 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3377 int type, int _index, void *data, size_t *size)
3380 case LIBUSB_DT_DEVICE:
3381 usbi_dbg("LIBUSB_DT_DEVICE");
3382 return _hid_get_device_descriptor(dev, data, size);
3383 case LIBUSB_DT_CONFIG:
3384 usbi_dbg("LIBUSB_DT_CONFIG");
3386 return _hid_get_config_descriptor(dev, data, size);
3387 return LIBUSB_ERROR_INVALID_PARAM;
3388 case LIBUSB_DT_STRING:
3389 usbi_dbg("LIBUSB_DT_STRING");
3390 return _hid_get_string_descriptor(dev, _index, data, size);
3392 usbi_dbg("LIBUSB_DT_HID");
3394 return _hid_get_hid_descriptor(dev, data, size);
3395 return LIBUSB_ERROR_INVALID_PARAM;
3396 case LIBUSB_DT_REPORT:
3397 usbi_dbg("LIBUSB_DT_REPORT");
3399 return _hid_get_report_descriptor(dev, data, size);
3400 return LIBUSB_ERROR_INVALID_PARAM;
3401 case LIBUSB_DT_PHYSICAL:
3402 usbi_dbg("LIBUSB_DT_PHYSICAL");
3403 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3404 return LIBUSB_COMPLETED;
3405 return LIBUSB_ERROR_OTHER;
3407 usbi_dbg("unsupported");
3408 return LIBUSB_ERROR_INVALID_PARAM;
3411 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3412 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3416 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3417 int r = LIBUSB_SUCCESS;
3419 if (tp->hid_buffer != NULL) {
3420 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3423 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3424 usbi_dbg("invalid size (%d)", *size);
3425 return LIBUSB_ERROR_INVALID_PARAM;
3428 switch (report_type) {
3429 case HID_REPORT_TYPE_INPUT:
3430 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3432 case HID_REPORT_TYPE_FEATURE:
3433 ioctl_code = IOCTL_HID_GET_FEATURE;
3436 usbi_dbg("unknown HID report type %d", report_type);
3437 return LIBUSB_ERROR_INVALID_PARAM;
3440 // Add a trailing byte to detect overflows
3441 buf = (uint8_t*)calloc(expected_size+1, 1);
3443 return LIBUSB_ERROR_NO_MEM;
3445 buf[0] = (uint8_t)id; // Must be set always
3446 usbi_dbg("report ID: 0x%02X", buf[0]);
3448 tp->hid_expected_size = expected_size;
3449 read_size = expected_size;
3451 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3452 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3453 buf, expected_size+1, &read_size, overlapped)) {
3454 if (GetLastError() != ERROR_IO_PENDING) {
3455 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3457 return LIBUSB_ERROR_IO;
3459 // Asynchronous wait
3460 tp->hid_buffer = buf;
3461 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3462 return LIBUSB_SUCCESS;
3465 // Transfer completed synchronously => copy and discard extra buffer
3466 if (read_size == 0) {
3467 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3471 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3473 if ((size_t)read_size > expected_size) {
3474 r = LIBUSB_ERROR_OVERFLOW;
3475 usbi_dbg("OVERFLOW!");
3477 r = LIBUSB_COMPLETED;
3480 *size = MIN((size_t)read_size, *size);
3482 // Discard report ID
3483 memcpy(data, buf+1, *size);
3485 memcpy(data, buf, *size);
3492 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3493 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3496 uint8_t *buf = NULL;
3497 DWORD ioctl_code, write_size= (DWORD)*size;
3499 if (tp->hid_buffer != NULL) {
3500 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3503 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3504 usbi_dbg("invalid size (%d)", *size);
3505 return LIBUSB_ERROR_INVALID_PARAM;
3508 switch (report_type) {
3509 case HID_REPORT_TYPE_OUTPUT:
3510 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3512 case HID_REPORT_TYPE_FEATURE:
3513 ioctl_code = IOCTL_HID_SET_FEATURE;
3516 usbi_dbg("unknown HID report type %d", report_type);
3517 return LIBUSB_ERROR_INVALID_PARAM;
3520 usbi_dbg("report ID: 0x%02X", id);
3521 // When report IDs are not used (i.e. when id == 0), we must add
3522 // a null report ID. Otherwise, we just use original data buffer
3526 buf = (uint8_t*) malloc(write_size);
3528 return LIBUSB_ERROR_NO_MEM;
3532 memcpy(buf + 1, data, *size);
3534 // This seems like a waste, but if we don't duplicate the
3535 // data, we'll get issues when freeing hid_buffer
3536 memcpy(buf, data, *size);
3538 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3542 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3543 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3544 buf, write_size, &write_size, overlapped)) {
3545 if (GetLastError() != ERROR_IO_PENDING) {
3546 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3548 return LIBUSB_ERROR_IO;
3550 tp->hid_buffer = buf;
3551 tp->hid_dest = NULL;
3552 return LIBUSB_SUCCESS;
3555 // Transfer completed synchronously
3557 if (write_size == 0) {
3558 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3561 return LIBUSB_COMPLETED;
3564 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3565 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3566 size_t *size, OVERLAPPED* overlapped)
3568 int report_type = (value >> 8) & 0xFF;
3569 int report_id = value & 0xFF;
3571 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3572 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3573 return LIBUSB_ERROR_INVALID_PARAM;
3575 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3576 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3578 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3579 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3581 return LIBUSB_ERROR_INVALID_PARAM;
3588 static int hid_init(int sub_api, struct libusb_context *ctx)
3590 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3591 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3592 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3593 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3594 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3595 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3596 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3597 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3598 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3599 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3600 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3601 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3602 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3603 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3604 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3605 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3607 api_hid_available = true;
3608 return LIBUSB_SUCCESS;
3611 static int hid_exit(int sub_api)
3613 return LIBUSB_SUCCESS;
3616 // NB: open and close must ensure that they only handle interface of
3617 // the right API type, as these functions can be called wholesale from
3618 // composite_open(), with interfaces belonging to different APIs
3619 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3621 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3622 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3623 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3625 HIDD_ATTRIBUTES hid_attributes;
3626 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3627 HIDP_CAPS capabilities;
3628 HIDP_VALUE_CAPS *value_caps;
3630 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3632 // report IDs handling
3634 const char* type[3] = {"input", "output", "feature"};
3635 int nb_ids[2]; // zero and nonzero report IDs
3637 CHECK_HID_AVAILABLE;
3638 if (priv->hid == NULL) {
3639 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3640 return LIBUSB_ERROR_NOT_FOUND;
3643 for (i = 0; i < USB_MAXINTERFACES; i++) {
3644 if ( (priv->usb_interface[i].path != NULL)
3645 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3646 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3647 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3649 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3650 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3651 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3652 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3653 * HidD_GetFeature (if the device supports Feature reports)."
3655 if (hid_handle == INVALID_HANDLE_VALUE) {
3656 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3657 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3658 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3659 if (hid_handle == INVALID_HANDLE_VALUE) {
3660 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3661 switch(GetLastError()) {
3662 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3663 return LIBUSB_ERROR_NO_DEVICE;
3664 case ERROR_ACCESS_DENIED:
3665 return LIBUSB_ERROR_ACCESS;
3667 return LIBUSB_ERROR_IO;
3670 priv->usb_interface[i].restricted_functionality = true;
3672 handle_priv->interface_handle[i].api_handle = hid_handle;
3676 hid_attributes.Size = sizeof(hid_attributes);
3678 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3679 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3683 priv->hid->vid = hid_attributes.VendorID;
3684 priv->hid->pid = hid_attributes.ProductID;
3686 // Set the maximum available input buffer size
3687 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3688 usbi_dbg("set maximum input buffer size to %d", i/2);
3690 // Get the maximum input and output report size
3691 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3692 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3695 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3696 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3700 // Find out if interrupt will need report IDs
3701 size[0] = capabilities.NumberInputValueCaps;
3702 size[1] = capabilities.NumberOutputValueCaps;
3703 size[2] = capabilities.NumberFeatureValueCaps;
3704 for (j=HidP_Input; j<=HidP_Feature; j++) {
3705 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3706 priv->hid->uses_report_ids[j] = false;
3708 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3709 if ( (value_caps != NULL)
3710 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3711 && (size[j] >= 1) ) {
3714 for (i=0; i<(int)size[j]; i++) {
3715 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3716 if (value_caps[i].ReportID != 0) {
3722 if (nb_ids[1] != 0) {
3723 if (nb_ids[0] != 0) {
3724 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3727 priv->hid->uses_report_ids[j] = true;
3730 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3732 safe_free(value_caps);
3736 // Set the report sizes
3737 priv->hid->input_report_size = capabilities.InputReportByteLength;
3738 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3739 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3741 // Fetch string descriptors
3742 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3743 if (priv->hid->string_index[0] != 0) {
3744 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3745 sizeof(priv->hid->string[0]));
3747 priv->hid->string[0][0] = 0;
3749 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3750 if (priv->hid->string_index[1] != 0) {
3751 HidD_GetProductString(hid_handle, priv->hid->string[1],
3752 sizeof(priv->hid->string[1]));
3754 priv->hid->string[1][0] = 0;
3756 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3757 if (priv->hid->string_index[2] != 0) {
3758 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3759 sizeof(priv->hid->string[2]));
3761 priv->hid->string[2][0] = 0;
3765 if (preparsed_data) {
3766 HidD_FreePreparsedData(preparsed_data);
3769 return LIBUSB_SUCCESS;
3772 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3774 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3775 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3779 if (!api_hid_available)
3782 for (i = 0; i < USB_MAXINTERFACES; i++) {
3783 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3784 file_handle = handle_priv->interface_handle[i].api_handle;
3785 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3786 CloseHandle(file_handle);
3792 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3794 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3795 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3797 CHECK_HID_AVAILABLE;
3799 // NB: Disconnection detection is not possible in this function
3800 if (priv->usb_interface[iface].path == NULL) {
3801 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3804 // We use dev_handle as a flag for interface claimed
3805 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3806 return LIBUSB_ERROR_BUSY; // already claimed
3809 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3811 usbi_dbg("claimed interface %d", iface);
3812 handle_priv->active_interface = iface;
3814 return LIBUSB_SUCCESS;
3817 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3819 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3820 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3822 CHECK_HID_AVAILABLE;
3824 if (priv->usb_interface[iface].path == NULL) {
3825 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3828 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3829 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3832 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3834 return LIBUSB_SUCCESS;
3837 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3839 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3841 CHECK_HID_AVAILABLE;
3843 if (altsetting > 255) {
3844 return LIBUSB_ERROR_INVALID_PARAM;
3847 if (altsetting != 0) {
3848 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3849 return LIBUSB_ERROR_NOT_SUPPORTED;
3852 return LIBUSB_SUCCESS;
3855 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3857 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3858 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3859 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3860 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3861 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3862 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3865 int current_interface, config;
3867 int r = LIBUSB_ERROR_INVALID_PARAM;
3869 CHECK_HID_AVAILABLE;
3871 transfer_priv->pollable_fd = INVALID_WINFD;
3872 safe_free(transfer_priv->hid_buffer);
3873 transfer_priv->hid_dest = NULL;
3874 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3876 if (size > MAX_CTRL_BUFFER_LENGTH) {
3877 return LIBUSB_ERROR_INVALID_PARAM;
3880 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3881 if (current_interface < 0) {
3882 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3883 return LIBUSB_ERROR_NOT_FOUND;
3887 usbi_dbg("will use interface %d", current_interface);
3888 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3889 // Always use the handle returned from usbi_create_fd (wfd.handle)
3890 wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
3892 return LIBUSB_ERROR_NOT_FOUND;
3895 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3896 case LIBUSB_REQUEST_TYPE_STANDARD:
3897 switch(setup->request) {
3898 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3899 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3900 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3902 case LIBUSB_REQUEST_GET_CONFIGURATION:
3903 r = windows_get_configuration(transfer->dev_handle, &config);
3904 if (r == LIBUSB_SUCCESS) {
3906 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3907 r = LIBUSB_COMPLETED;
3910 case LIBUSB_REQUEST_SET_CONFIGURATION:
3911 if (setup->value == priv->active_config) {
3912 r = LIBUSB_COMPLETED;
3914 usbi_warn(ctx, "cannot set configuration other than the default one");
3915 r = LIBUSB_ERROR_INVALID_PARAM;
3918 case LIBUSB_REQUEST_GET_INTERFACE:
3920 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3921 r = LIBUSB_COMPLETED;
3923 case LIBUSB_REQUEST_SET_INTERFACE:
3924 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3925 if (r == LIBUSB_SUCCESS) {
3926 r = LIBUSB_COMPLETED;
3930 usbi_warn(ctx, "unsupported HID control request");
3931 r = LIBUSB_ERROR_INVALID_PARAM;
3935 case LIBUSB_REQUEST_TYPE_CLASS:
3936 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3937 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3938 &size, wfd.overlapped);
3941 usbi_warn(ctx, "unsupported HID control request");
3942 r = LIBUSB_ERROR_INVALID_PARAM;
3946 if (r == LIBUSB_COMPLETED) {
3947 // Force request to be completed synchronously. Transferred size has been set by previous call
3948 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3949 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3950 // set InternalHigh to the number of bytes transferred
3951 wfd.overlapped->InternalHigh = (DWORD)size;
3955 if (r == LIBUSB_SUCCESS) {
3956 // Use priv_transfer to store data needed for async polling
3957 transfer_priv->pollable_fd = wfd;
3958 transfer_priv->interface_number = (uint8_t)current_interface;
3960 usbi_free_fd(wfd.fd);
3966 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3967 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3968 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3969 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3970 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3971 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3974 bool direction_in, ret;
3975 int current_interface, length;
3977 int r = LIBUSB_SUCCESS;
3979 CHECK_HID_AVAILABLE;
3981 transfer_priv->pollable_fd = INVALID_WINFD;
3982 transfer_priv->hid_dest = NULL;
3983 safe_free(transfer_priv->hid_buffer);
3985 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3986 if (current_interface < 0) {
3987 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3988 return LIBUSB_ERROR_NOT_FOUND;
3991 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3993 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3994 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
3996 wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
3997 // Always use the handle returned from usbi_create_fd (wfd.handle)
3999 return LIBUSB_ERROR_NO_MEM;
4002 // If report IDs are not in use, an extra prefix byte must be added
4003 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4004 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4005 length = transfer->length+1;
4007 length = transfer->length;
4009 // Add a trailing byte to detect overflows on input
4010 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4011 if (transfer_priv->hid_buffer == NULL) {
4012 return LIBUSB_ERROR_NO_MEM;
4014 transfer_priv->hid_expected_size = length;
4017 transfer_priv->hid_dest = transfer->buffer;
4018 usbi_dbg("reading %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4019 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4021 if (!priv->hid->uses_report_ids[1]) {
4022 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4024 // We could actually do without the calloc and memcpy in this case
4025 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4027 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4028 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4031 if (GetLastError() != ERROR_IO_PENDING) {
4032 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4033 usbi_free_fd(wfd.fd);
4034 safe_free(transfer_priv->hid_buffer);
4035 return LIBUSB_ERROR_IO;
4038 // Only write operations that completed synchronously need to free up
4039 // hid_buffer. For reads, copy_transfer_data() handles that process.
4040 if (!direction_in) {
4041 safe_free(transfer_priv->hid_buffer);
4044 usbi_err(ctx, "program assertion failed - no data was transferred");
4047 if (size > (size_t)length) {
4048 usbi_err(ctx, "OVERFLOW!");
4049 r = LIBUSB_ERROR_OVERFLOW;
4051 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4052 wfd.overlapped->InternalHigh = size;
4055 transfer_priv->pollable_fd = wfd;
4056 transfer_priv->interface_number = (uint8_t)current_interface;
4061 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4063 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4064 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4065 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4067 int current_interface;
4069 CHECK_HID_AVAILABLE;
4071 current_interface = transfer_priv->interface_number;
4072 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4073 CancelIo(hid_handle);
4075 return LIBUSB_SUCCESS;
4078 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4080 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4082 int current_interface;
4084 CHECK_HID_AVAILABLE;
4086 // Flushing the queues on all interfaces is the best we can achieve
4087 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4088 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4089 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4090 HidD_FlushQueue(hid_handle);
4093 return LIBUSB_SUCCESS;
4096 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4098 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4099 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4100 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4102 int current_interface;
4104 CHECK_HID_AVAILABLE;
4106 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4107 if (current_interface < 0) {
4108 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4109 return LIBUSB_ERROR_NOT_FOUND;
4112 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4113 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4115 // No endpoint selection with Microsoft's implementation, so we try to flush the
4116 // whole interface. Should be OK for most case scenarios
4117 if (!HidD_FlushQueue(hid_handle)) {
4118 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4119 // Device was probably disconnected
4120 return LIBUSB_ERROR_NO_DEVICE;
4123 return LIBUSB_SUCCESS;
4126 // This extra function is only needed for HID
4127 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4128 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4129 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4130 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4131 int r = LIBUSB_TRANSFER_COMPLETED;
4132 uint32_t corrected_size = io_size;
4134 if (transfer_priv->hid_buffer != NULL) {
4135 // If we have a valid hid_buffer, it means the transfer was async
4136 if (transfer_priv->hid_dest != NULL) { // Data readout
4137 // First, check for overflow
4138 if (corrected_size > transfer_priv->hid_expected_size) {
4139 usbi_err(ctx, "OVERFLOW!");
4140 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4141 r = LIBUSB_TRANSFER_OVERFLOW;
4144 if (transfer_priv->hid_buffer[0] == 0) {
4145 // Discard the 1 byte report ID prefix
4147 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4149 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4151 transfer_priv->hid_dest = NULL;
4153 // For write, we just need to free the hid buffer
4154 safe_free(transfer_priv->hid_buffer);
4156 itransfer->transferred += corrected_size;
4162 * Composite API functions
4164 static int composite_init(int sub_api, struct libusb_context *ctx)
4166 return LIBUSB_SUCCESS;
4169 static int composite_exit(int sub_api)
4171 return LIBUSB_SUCCESS;
4174 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4176 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4177 int r = LIBUSB_ERROR_NOT_FOUND;
4179 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4180 bool available[SUB_API_MAX+1] = {0};
4182 for (i=0; i<USB_MAXINTERFACES; i++) {
4183 switch (priv->usb_interface[i].apib->id) {
4184 case USB_API_WINUSBX:
4185 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4186 available[priv->usb_interface[i].sub_api] = true;
4189 available[SUB_API_MAX] = true;
4196 for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4198 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4199 if (r != LIBUSB_SUCCESS) {
4204 if (available[SUB_API_MAX]) { // HID driver
4205 r = hid_open(SUB_API_NOTSET, dev_handle);
4210 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4212 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4214 bool available[SUB_API_MAX];
4216 for (i = 0; i<SUB_API_MAX; i++) {
4217 available[i] = false;
4220 for (i=0; i<USB_MAXINTERFACES; i++) {
4221 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4222 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4223 available[priv->usb_interface[i].sub_api] = true;
4227 for (i=0; i<SUB_API_MAX; i++) {
4229 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4234 static int composite_claim_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 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4241 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4243 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4244 return priv->usb_interface[iface].apib->
4245 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4248 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4250 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4251 return priv->usb_interface[iface].apib->
4252 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4255 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4257 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4258 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4259 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4262 // Interface shouldn't matter for control, but it does in practice, with Windows'
4263 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4264 for (pass = 0; pass < 2; pass++) {
4265 for (i=0; i<USB_MAXINTERFACES; i++) {
4266 if (priv->usb_interface[i].path != NULL) {
4267 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4268 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4271 usbi_dbg("using interface %d", i);
4272 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4277 usbi_err(ctx, "no libusbx supported interfaces to complete request");
4278 return LIBUSB_ERROR_NOT_FOUND;
4281 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4282 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4283 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4284 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4285 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4286 int current_interface;
4288 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4289 if (current_interface < 0) {
4290 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4291 return LIBUSB_ERROR_NOT_FOUND;
4294 return priv->usb_interface[current_interface].apib->
4295 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4297 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4298 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4299 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4300 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4301 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4302 int current_interface;
4304 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4305 if (current_interface < 0) {
4306 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4307 return LIBUSB_ERROR_NOT_FOUND;
4310 return priv->usb_interface[current_interface].apib->
4311 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4313 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4315 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4316 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4317 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4318 int current_interface;
4320 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4321 if (current_interface < 0) {
4322 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4323 return LIBUSB_ERROR_NOT_FOUND;
4326 return priv->usb_interface[current_interface].apib->
4327 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4329 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4331 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4332 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4333 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4335 return priv->usb_interface[transfer_priv->interface_number].apib->
4336 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4338 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4340 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4341 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4342 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4344 return priv->usb_interface[transfer_priv->interface_number].apib->
4345 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4347 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4349 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4352 bool available[SUB_API_MAX];
4353 for (i = 0; i<SUB_API_MAX; i++) {
4354 available[i] = false;
4356 for (i=0; i<USB_MAXINTERFACES; i++) {
4357 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4358 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4359 available[priv->usb_interface[i].sub_api] = true;
4362 for (i=0; i<SUB_API_MAX; i++) {
4364 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4365 if (r != LIBUSB_SUCCESS) {
4370 return LIBUSB_SUCCESS;
4373 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4375 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4376 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4377 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4379 return priv->usb_interface[transfer_priv->interface_number].apib->
4380 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);