2 * windows backend for libusb 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 // Translate codes returned by SetupAPI. The ones we are dealing with are either
162 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
163 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
164 switch (error_code & 0xE0000000) {
166 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
169 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
175 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
176 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
177 ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
179 format_error = GetLastError();
181 safe_sprintf(err_string, ERR_BUFFER_SIZE,
182 "Windows error code %u (FormatMessage error code %u)", error_code, format_error);
184 safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
186 // Remove CR/LF terminators
187 for (i=safe_strlen(err_string)-1; (i>=0) && ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
196 * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
197 * Return an allocated sanitized string or NULL on error.
199 static char* sanitize_path(const char* path)
201 const char root_prefix[] = "\\\\.\\";
202 size_t j, size, root_size;
203 char* ret_path = NULL;
209 size = safe_strlen(path)+1;
210 root_size = sizeof(root_prefix)-1;
212 // Microsoft indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
213 if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
214 ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
215 add_root = root_size;
219 if ((ret_path = (char*) calloc(size, 1)) == NULL)
222 safe_strcpy(&ret_path[add_root], size-add_root, path);
224 // Ensure consistancy with root prefix
225 for (j=0; j<root_size; j++)
226 ret_path[j] = root_prefix[j];
228 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
229 for(j=root_size; j<size; j++) {
230 ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
231 if (ret_path[j] == '\\')
239 * Cfgmgr32, OLE32 and SetupAPI DLL functions
241 static int init_dlls(void)
243 DLL_LOAD(Cfgmgr32.dll, CM_Get_Parent, TRUE);
244 DLL_LOAD(Cfgmgr32.dll, CM_Get_Child, TRUE);
245 DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE);
246 DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE);
247 // Prefixed to avoid conflict with header files
248 DLL_LOAD_PREFIXED(OLE32.dll, p, CLSIDFromString, TRUE);
249 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE);
250 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE);
251 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE);
252 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
253 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
254 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
255 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
256 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
257 DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
258 DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
259 return LIBUSB_SUCCESS;
263 * enumerate interfaces for the whole USB class
266 * dev_info: a pointer to a dev_info list
267 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
268 * usb_class: the generic USB class for which to retrieve interface details
269 * index: zero based index of the interface in the device info list
271 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
272 * structure returned and call this function repeatedly using the same guid (with an
273 * incremented index starting at zero) until all interfaces have been returned.
275 static bool get_devinfo_data(struct libusb_context *ctx,
276 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char* usb_class, unsigned _index)
279 *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
280 if (*dev_info == INVALID_HANDLE_VALUE) {
285 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
286 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
287 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
288 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
289 _index, windows_error_str(0));
291 pSetupDiDestroyDeviceInfoList(*dev_info);
292 *dev_info = INVALID_HANDLE_VALUE;
299 * enumerate interfaces for a specific GUID
302 * dev_info: a pointer to a dev_info list
303 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
304 * guid: the GUID for which to retrieve interface details
305 * index: zero based index of the interface in the device info list
307 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
308 * structure returned and call this function repeatedly using the same guid (with an
309 * incremented index starting at zero) until all interfaces have been returned.
311 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details(struct libusb_context *ctx,
312 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index)
314 SP_DEVICE_INTERFACE_DATA dev_interface_data;
315 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
319 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
322 if (dev_info_data != NULL) {
323 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
324 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
325 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
326 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
327 _index, windows_error_str(0));
329 pSetupDiDestroyDeviceInfoList(*dev_info);
330 *dev_info = INVALID_HANDLE_VALUE;
335 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
336 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
337 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
338 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
339 _index, windows_error_str(0));
341 pSetupDiDestroyDeviceInfoList(*dev_info);
342 *dev_info = INVALID_HANDLE_VALUE;
346 // Read interface data (dummy + actual) to access the device path
347 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
348 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
349 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
350 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
351 _index, windows_error_str(0));
355 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
359 if ((dev_interface_details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) calloc(size, 1)) == NULL) {
360 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
364 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
365 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
366 dev_interface_details, size, &size, NULL)) {
367 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
368 _index, windows_error_str(0));
371 return dev_interface_details;
374 pSetupDiDestroyDeviceInfoList(*dev_info);
375 *dev_info = INVALID_HANDLE_VALUE;
379 /* For libusb0 filter */
380 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
381 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index, char* filter_path){
382 SP_DEVICE_INTERFACE_DATA dev_interface_data;
383 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
386 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
388 if (dev_info_data != NULL) {
389 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
390 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
391 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
392 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
393 _index, windows_error_str(0));
395 pSetupDiDestroyDeviceInfoList(*dev_info);
396 *dev_info = INVALID_HANDLE_VALUE;
400 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
401 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
402 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
403 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
404 _index, windows_error_str(0));
406 pSetupDiDestroyDeviceInfoList(*dev_info);
407 *dev_info = INVALID_HANDLE_VALUE;
410 // Read interface data (dummy + actual) to access the device path
411 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
412 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
413 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
414 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
415 _index, windows_error_str(0));
419 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
422 if ((dev_interface_details = malloc(size)) == NULL) {
423 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
426 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
427 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
428 dev_interface_details, size, &size, NULL)) {
429 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
430 _index, windows_error_str(0));
432 // [trobinso] lookup the libusb0 symbolic index.
433 if (dev_interface_details) {
434 HKEY hkey_device_interface=pSetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ);
435 if (hkey_device_interface != INVALID_HANDLE_VALUE) {
436 DWORD libusb0_symboliclink_index=0;
437 DWORD value_length=sizeof(DWORD);
440 status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type,
441 (LPBYTE) &libusb0_symboliclink_index, &value_length);
442 if (status == ERROR_SUCCESS) {
443 if (libusb0_symboliclink_index < 256) {
444 // libusb0.sys is connected to this device instance.
445 // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
446 safe_sprintf(filter_path, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index);
447 usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
449 // libusb0.sys was connected to this device instance at one time; but not anymore.
452 pRegCloseKey(hkey_device_interface);
455 return dev_interface_details;
457 pSetupDiDestroyDeviceInfoList(*dev_info);
458 *dev_info = INVALID_HANDLE_VALUE;
461 /* Hash table functions - modified From glibc 2.3.2:
462 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
463 [Knuth] The Art of Computer Programming, part 3 (6.4) */
464 typedef struct htab_entry {
468 htab_entry* htab_table = NULL;
469 usbi_mutex_t htab_write_mutex = NULL;
470 unsigned long htab_size, htab_filled;
472 /* For the used double hash method the table size has to be a prime. To
473 correct the user given table size we need a prime test. This trivial
474 algorithm is adequate because the code is called only during init and
475 the number is likely to be small */
476 static int isprime(unsigned long number)
478 // no even number will be passed
479 unsigned int divider = 3;
481 while((divider * divider < number) && (number % divider != 0))
484 return (number % divider != 0);
487 /* Before using the hash table we must allocate memory for it.
488 We allocate one element more as the found prime number says.
489 This is done for more effective indexing as explained in the
490 comment for the hash function. */
491 static int htab_create(struct libusb_context *ctx, unsigned long nel)
493 if (htab_table != NULL) {
494 usbi_err(ctx, "hash table already allocated");
498 usbi_mutex_init(&htab_write_mutex, NULL);
500 // Change nel to the first prime number not smaller as nel.
506 usbi_dbg("using %d entries hash table", nel);
509 // allocate memory and zero out.
510 htab_table = (htab_entry*) calloc(htab_size + 1, sizeof(htab_entry));
511 if (htab_table == NULL) {
512 usbi_err(ctx, "could not allocate space for hash table");
519 /* After using the hash table it has to be destroyed. */
520 static void htab_destroy(void)
523 if (htab_table == NULL) {
527 for (i=0; i<htab_size; i++) {
528 if (htab_table[i].used) {
529 safe_free(htab_table[i].str);
532 usbi_mutex_destroy(&htab_write_mutex);
533 safe_free(htab_table);
536 /* This is the search function. It uses double hashing with open addressing.
537 We use an trick to speed up the lookup. The table is created with one
538 more element available. This enables us to use the index zero special.
539 This index will never be used because we store the first hash index in
540 the field used where zero means not used. Every other value means used.
541 The used field can be used as a first fast comparison for equality of
542 the stored and the parameter value. This helps to prevent unnecessary
543 expensive calls of strcmp. */
544 static unsigned long htab_hash(char* str)
546 unsigned long hval, hval2;
548 unsigned long r = 5381;
555 // Compute main hash value (algorithm suggested by Nokia)
556 while ((c = *sz++) != 0)
557 r = ((r << 5) + r) + c;
561 // compute table hash: simply take the modulus
562 hval = r % htab_size;
566 // Try the first index
569 if (htab_table[idx].used) {
570 if ( (htab_table[idx].used == hval)
571 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
575 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
577 // Second hash function, as suggested in [Knuth]
578 hval2 = 1 + hval % (htab_size - 2);
581 // Because size is prime this guarantees to step through all available indexes
583 idx = htab_size + idx - hval2;
588 // If we visited all entries leave the loop unsuccessfully
593 // If entry is found use it.
594 if ( (htab_table[idx].used == hval)
595 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
599 while (htab_table[idx].used);
602 // Not found => New entry
604 // If the table is full return an error
605 if (htab_filled >= htab_size) {
606 usbi_err(NULL, "hash table is full (%d entries)", htab_size);
610 // Concurrent threads might be storing the same entry at the same time
611 // (eg. "simultaneous" enums from different threads) => use a mutex
612 usbi_mutex_lock(&htab_write_mutex);
613 // Just free any previously allocated string (which should be the same as
614 // new one). The possibility of concurrent threads storing a collision
615 // string (same hash, different string) at the same time is extremely low
616 safe_free(htab_table[idx].str);
617 htab_table[idx].used = hval;
618 htab_table[idx].str = (char*) malloc(safe_strlen(str)+1);
619 if (htab_table[idx].str == NULL) {
620 usbi_err(NULL, "could not duplicate string for hash table");
621 usbi_mutex_unlock(&htab_write_mutex);
624 memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
626 usbi_mutex_unlock(&htab_write_mutex);
632 * Returns the session ID of a device's nth level ancestor
633 * If there's no device at the nth level, return 0
635 static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
637 DWORD parent_devinst;
638 unsigned long session_id = 0;
639 char* sanitized_path = NULL;
640 char path[MAX_PATH_LENGTH];
643 if (level < 1) return 0;
644 for (i = 0; i<level; i++) {
645 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
648 devinst = parent_devinst;
650 if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
653 // TODO: (post hotplug): try without sanitizing
654 sanitized_path = sanitize_path(path);
655 if (sanitized_path == NULL) {
658 session_id = htab_hash(sanitized_path);
659 safe_free(sanitized_path);
664 * Populate the endpoints addresses of the device_priv interface helper structs
666 static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
669 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
670 struct libusb_config_descriptor *conf_desc;
671 const struct libusb_interface_descriptor *if_desc;
672 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
674 r = libusb_get_config_descriptor(dev_handle->dev, 0, &conf_desc);
675 if (r != LIBUSB_SUCCESS) {
676 usbi_warn(ctx, "could not read config descriptor: error %d", r);
680 if_desc = &conf_desc->interface[iface].altsetting[altsetting];
681 safe_free(priv->usb_interface[iface].endpoint);
683 if (if_desc->bNumEndpoints == 0) {
684 usbi_dbg("no endpoints found for interface %d", iface);
685 return LIBUSB_SUCCESS;
688 priv->usb_interface[iface].endpoint = (uint8_t*) malloc(if_desc->bNumEndpoints);
689 if (priv->usb_interface[iface].endpoint == NULL) {
690 return LIBUSB_ERROR_NO_MEM;
693 priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
694 for (i=0; i<if_desc->bNumEndpoints; i++) {
695 priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
696 usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface);
698 libusb_free_config_descriptor(conf_desc);
700 // Extra init may be required to configure endpoints
701 return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
704 // Lookup for a match in the list of API driver names
705 // return -1 if not found, driver match number otherwise
706 static int get_sub_api(char* driver, int api){
708 const char sep_str[2] = {LIST_SEPARATOR, 0};
710 size_t len = safe_strlen(driver);
712 if (len == 0) return SUB_API_NOTSET;
713 tmp_str = (char*) calloc(len+1, 1);
714 if (tmp_str == NULL) return SUB_API_NOTSET;
715 memcpy(tmp_str, driver, len+1);
716 tok = strtok(tmp_str, sep_str);
717 while (tok != NULL) {
718 for (i=0; i<usb_api_backend[api].nb_driver_names; i++) {
719 if (safe_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
724 tok = strtok(NULL, sep_str);
727 return SUB_API_NOTSET;
731 * auto-claiming and auto-release helper functions
733 static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
735 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
736 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
737 transfer->dev_handle);
738 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
739 int current_interface = *interface_number;
740 int r = LIBUSB_SUCCESS;
743 case USB_API_WINUSBX:
747 return LIBUSB_ERROR_INVALID_PARAM;
750 usbi_mutex_lock(&autoclaim_lock);
751 if (current_interface < 0) // No serviceable interface was found
753 for (current_interface=0; current_interface<USB_MAXINTERFACES; current_interface++) {
754 // Must claim an interface of the same API type
755 if ( (priv->usb_interface[current_interface].apib->id == api_type)
756 && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS) ) {
757 usbi_dbg("auto-claimed interface %d for control request", current_interface);
758 if (handle_priv->autoclaim_count[current_interface] != 0) {
759 usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero");
761 handle_priv->autoclaim_count[current_interface]++;
765 if (current_interface == USB_MAXINTERFACES) {
766 usbi_err(ctx, "could not auto-claim any interface");
767 r = LIBUSB_ERROR_NOT_FOUND;
770 // If we have a valid interface that was autoclaimed, we must increment
771 // its autoclaim count so that we can prevent an early release.
772 if (handle_priv->autoclaim_count[current_interface] != 0) {
773 handle_priv->autoclaim_count[current_interface]++;
776 usbi_mutex_unlock(&autoclaim_lock);
778 *interface_number = current_interface;
783 static void auto_release(struct usbi_transfer *itransfer)
785 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
786 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
787 libusb_device_handle *dev_handle = transfer->dev_handle;
788 struct windows_device_handle_priv* handle_priv = _device_handle_priv(dev_handle);
791 usbi_mutex_lock(&autoclaim_lock);
792 if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
793 handle_priv->autoclaim_count[transfer_priv->interface_number]--;
794 if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
795 r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
796 if (r == LIBUSB_SUCCESS) {
797 usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
799 usbi_dbg("failed to auto-release interface %d (%s)",
800 transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
804 usbi_mutex_unlock(&autoclaim_lock);
808 * init: libusb backend init function
810 * This function enumerates the HCDs (Host Controller Drivers) and populates our private HCD list
811 * In our implementation, we equate Windows' "HCD" to libusb's "bus". Note that bus is zero indexed.
812 * HCDs are not expected to change after init (might not hold true for hot pluggable USB PCI card?)
814 static int windows_init(struct libusb_context *ctx)
816 int i, r = LIBUSB_ERROR_OTHER;
817 OSVERSIONINFO os_version;
819 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
821 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
822 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
823 if (semaphore == NULL) {
824 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
825 return LIBUSB_ERROR_NO_MEM;
828 // A successful wait brings our semaphore count to 0 (unsignaled)
829 // => any concurent wait stalls until the semaphore's release
830 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
831 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
832 CloseHandle(semaphore);
833 return LIBUSB_ERROR_NO_MEM;
836 // NB: concurrent usage supposes that init calls are equally balanced with
837 // exit calls. If init is called more than exit, we will not exit properly
838 if ( ++concurrent_usage == 0 ) { // First init?
840 memset(&os_version, 0, sizeof(OSVERSIONINFO));
841 os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
842 windows_version = WINDOWS_UNSUPPORTED;
843 if ((GetVersionEx(&os_version) != 0) && (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
844 if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 1)) {
845 windows_version = WINDOWS_XP;
846 } else if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 2)) {
847 windows_version = WINDOWS_2003; // also includes XP 64
848 } else if (os_version.dwMajorVersion >= 6) {
849 windows_version = WINDOWS_VISTA_AND_LATER;
852 if (windows_version == WINDOWS_UNSUPPORTED) {
853 usbi_err(ctx, "This version of Windows is NOT supported");
854 r = LIBUSB_ERROR_NOT_SUPPORTED;
858 // We need a lock for proper auto-release
859 usbi_mutex_init(&autoclaim_lock, NULL);
861 // Initialize pollable file descriptors
865 if (init_dlls() != LIBUSB_SUCCESS) {
866 usbi_err(ctx, "could not resolve DLL functions");
867 return LIBUSB_ERROR_NOT_FOUND;
870 // Initialize the low level APIs (we don't care about errors at this stage)
871 for (i=0; i<USB_API_MAX; i++) {
872 usb_api_backend[i].init(SUB_API_NOTSET, ctx);
875 // Because QueryPerformanceCounter might report different values when
876 // running on different cores, we create a separate thread for the timer
877 // calls, which we glue to the first core always to prevent timing discrepancies.
878 r = LIBUSB_ERROR_NO_MEM;
879 for (i = 0; i < 2; i++) {
880 timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
881 if (timer_request[i] == NULL) {
882 usbi_err(ctx, "could not create timer request event %d - aborting", i);
886 timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
887 if (timer_response == NULL) {
888 usbi_err(ctx, "could not create timer response semaphore - aborting");
891 timer_mutex = CreateMutex(NULL, FALSE, NULL);
892 if (timer_mutex == NULL) {
893 usbi_err(ctx, "could not create timer mutex - aborting");
896 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, NULL, 0, NULL);
897 if (timer_thread == NULL) {
898 usbi_err(ctx, "Unable to create timer thread - aborting");
901 SetThreadAffinityMask(timer_thread, 0);
903 // Wait for timer thread to init before continuing.
904 if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
905 usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
909 // Create a hash table to store session ids. Second parameter is better if prime
910 htab_create(ctx, HTAB_SIZE);
912 // At this stage, either we went through full init successfully, or didn't need to
915 init_exit: // Holds semaphore here.
916 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
918 SetEvent(timer_request[1]); // actually the signal to quit the thread.
919 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
920 usbi_warn(ctx, "could not wait for timer thread to quit");
921 TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
922 // all objects it might have held anyway.
924 CloseHandle(timer_thread);
927 for (i = 0; i < 2; i++) {
928 if (timer_request[i]) {
929 CloseHandle(timer_request[i]);
930 timer_request[i] = NULL;
933 if (timer_response) {
934 CloseHandle(timer_response);
935 timer_response = NULL;
938 CloseHandle(timer_mutex);
944 if (r != LIBUSB_SUCCESS)
945 --concurrent_usage; // Not expected to call libusb_exit if we failed.
947 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
948 CloseHandle(semaphore);
953 * HCD (root) hubs need to have their device descriptor manually populated
955 * Note that, like Microsoft does in the device manager, we populate the
956 * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device.
958 static int force_hcd_device_descriptor(struct libusb_device *dev)
960 struct windows_device_priv *parent_priv, *priv = _device_priv(dev);
961 struct libusb_context *ctx = DEVICE_CTX(dev);
964 dev->num_configurations = 1;
965 priv->dev_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
966 priv->dev_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
967 priv->dev_descriptor.bNumConfigurations = 1;
968 priv->active_config = 1;
970 if (priv->parent_dev == NULL) {
971 usbi_err(ctx, "program assertion failed - HCD hub has no parent");
972 return LIBUSB_ERROR_NO_DEVICE;
974 parent_priv = _device_priv(priv->parent_dev);
975 if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) {
976 priv->dev_descriptor.idVendor = (uint16_t)vid;
977 priv->dev_descriptor.idProduct = (uint16_t)pid;
979 usbi_warn(ctx, "could not infer VID/PID of HCD hub from '%s'", parent_priv->path);
980 priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub
981 priv->dev_descriptor.idProduct = 1;
983 return LIBUSB_SUCCESS;
987 * fetch and cache all the config descriptors through I/O
989 static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char* device_id)
991 DWORD size, ret_size;
992 struct libusb_context *ctx = DEVICE_CTX(dev);
993 struct windows_device_priv *priv = _device_priv(dev);
997 USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
998 PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
999 PUSB_CONFIGURATION_DESCRIPTOR cd_data = NULL;
1001 if (dev->num_configurations == 0)
1002 return LIBUSB_ERROR_INVALID_PARAM;
1004 priv->config_descriptor = (unsigned char**) calloc(dev->num_configurations, sizeof(unsigned char*));
1005 if (priv->config_descriptor == NULL)
1006 return LIBUSB_ERROR_NO_MEM;
1007 for (i=0; i<dev->num_configurations; i++)
1008 priv->config_descriptor[i] = NULL;
1010 for (i=0, r=LIBUSB_SUCCESS; ; i++)
1012 // safe loop: release all dynamic resources
1013 safe_free(cd_buf_actual);
1015 // safe loop: end of loop condition
1016 if ((i >= dev->num_configurations) || (r != LIBUSB_SUCCESS))
1019 size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT);
1020 memset(&cd_buf_short, 0, size);
1022 cd_buf_short.req.ConnectionIndex = (ULONG)priv->port;
1023 cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1024 cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1025 cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1026 cd_buf_short.req.SetupPacket.wIndex = i;
1027 cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1029 // Dummy call to get the required data size. Initial failures are reported as info rather
1030 // than error as they can occur for non-penalizing situations, such as with some hubs.
1031 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
1032 &cd_buf_short, size, &ret_size, NULL)) {
1033 usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
1034 LOOP_BREAK(LIBUSB_ERROR_IO);
1037 if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
1038 usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
1039 LOOP_BREAK(LIBUSB_ERROR_IO);
1042 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
1043 if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
1044 usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
1045 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1047 memset(cd_buf_actual, 0, size);
1050 cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
1051 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1052 cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1053 cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1054 cd_buf_actual->SetupPacket.wIndex = i;
1055 cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1057 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1058 cd_buf_actual, size, &ret_size, NULL)) {
1059 usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1060 LOOP_BREAK(LIBUSB_ERROR_IO);
1063 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1065 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1066 usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1067 LOOP_BREAK(LIBUSB_ERROR_IO);
1070 if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1071 usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1072 LOOP_BREAK(LIBUSB_ERROR_IO);
1075 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1076 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1078 // Cache the descriptor
1079 priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1080 if (priv->config_descriptor[i] == NULL)
1081 return LIBUSB_ERROR_NO_MEM;
1082 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1084 return LIBUSB_SUCCESS;
1088 * Populate a libusb device structure
1090 static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1091 uint8_t port_number, char* device_id, DWORD devinst)
1095 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1096 struct windows_device_priv *priv, *parent_priv;
1097 struct libusb_context *ctx = DEVICE_CTX(dev);
1098 struct libusb_device* tmp_dev;
1101 if ((dev == NULL) || (parent_dev == NULL)) {
1102 return LIBUSB_ERROR_NOT_FOUND;
1104 priv = _device_priv(dev);
1105 parent_priv = _device_priv(parent_dev);
1106 if (parent_priv->apib->id != USB_API_HUB) {
1107 usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1108 return LIBUSB_ERROR_NOT_FOUND;
1111 // It is possible for the parent hub not to have been initialized yet
1112 // If that's the case, lookup the ancestors to set the bus number
1113 if (parent_dev->bus_number == 0) {
1115 tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
1116 if (tmp_dev == NULL) break;
1117 if (tmp_dev->bus_number != 0) {
1118 usbi_dbg("got bus number from ancestor #%d", i);
1119 parent_dev->bus_number = tmp_dev->bus_number;
1120 libusb_unref_device(tmp_dev);
1123 libusb_unref_device(tmp_dev);
1126 if (parent_dev->bus_number == 0) {
1127 usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1128 return LIBUSB_ERROR_NOT_FOUND;
1130 dev->bus_number = parent_dev->bus_number;
1131 priv->port = port_number;
1132 dev->port_number = port_number;
1133 priv->depth = parent_priv->depth + 1;
1134 priv->parent_dev = parent_dev;
1135 dev->parent_dev = parent_dev;
1137 // If the device address is already set, we can stop here
1138 if (dev->device_address != 0) {
1139 return LIBUSB_SUCCESS;
1141 memset(&conn_info, 0, sizeof(conn_info));
1142 if (priv->depth != 0) { // Not a HCD hub
1143 handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1144 FILE_FLAG_OVERLAPPED, NULL);
1145 if (handle == INVALID_HANDLE_VALUE) {
1146 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1147 return LIBUSB_ERROR_ACCESS;
1149 size = sizeof(conn_info);
1150 conn_info.ConnectionIndex = (ULONG)port_number;
1151 if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1152 &conn_info, size, &size, NULL)) {
1153 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1154 device_id, windows_error_str(0));
1155 safe_closehandle(handle);
1156 return LIBUSB_ERROR_NO_DEVICE;
1158 if (conn_info.ConnectionStatus == NoDeviceConnected) {
1159 usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1160 safe_closehandle(handle);
1161 return LIBUSB_ERROR_NO_DEVICE;
1163 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1164 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1165 priv->active_config = conn_info.CurrentConfigurationValue;
1166 usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1167 // If we can't read the config descriptors, just set the number of confs to zero
1168 if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1169 dev->num_configurations = 0;
1170 priv->dev_descriptor.bNumConfigurations = 0;
1172 safe_closehandle(handle);
1174 if (conn_info.DeviceAddress > UINT8_MAX) {
1175 usbi_err(ctx, "program assertion failed: device address overflow");
1177 dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1178 if (dev->device_address == 1) {
1179 usbi_err(ctx, "program assertion failed: device address collision with root hub");
1181 switch (conn_info.Speed) {
1182 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1183 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1184 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1185 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1187 usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1191 dev->device_address = 1; // root hubs are set to use device number 1
1192 force_hcd_device_descriptor(dev);
1195 usbi_sanitize_device(dev);
1197 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1198 dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1200 return LIBUSB_SUCCESS;
1203 // Returns the api type, or 0 if not found/unsupported
1204 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1205 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1207 // Precedence for filter drivers vs driver is in the order of this array
1208 struct driver_lookup lookup[3] = {
1209 {"\0\0", SPDRP_SERVICE, "driver"},
1210 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1211 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1213 DWORD size, reg_type;
1217 *api = USB_API_UNSUPPORTED;
1218 *sub_api = SUB_API_NOTSET;
1219 // Check the service & filter names to know the API we should use
1220 for (k=0; k<3; k++) {
1221 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1222 ®_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1223 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1224 if (lookup[k].reg_prop == SPDRP_SERVICE) {
1225 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1226 lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1228 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1229 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1230 // (currently ';'), so even if an unsuported one does, it's not an issue
1231 for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1232 if (lookup[k].list[l] == 0) {
1233 lookup[k].list[l] = LIST_SEPARATOR;
1236 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1238 if (GetLastError() != ERROR_INVALID_DATA) {
1239 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1241 lookup[k].list[0] = 0;
1245 for (i=1; i<USB_API_MAX; i++) {
1246 for (k=0; k<3; k++) {
1247 j = get_sub_api(lookup[k].list, i);
1249 usbi_dbg("matched %s name against %s",
1250 lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1259 static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1260 char* dev_interface_path, char* device_id, int api, int sub_api)
1263 struct windows_device_priv *priv = _device_priv(dev);
1264 int interface_number;
1266 if (priv->apib->id != USB_API_COMPOSITE) {
1267 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1268 return LIBUSB_ERROR_NO_DEVICE;
1271 // Because MI_## are not necessarily in sequential order (some composite
1272 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1273 // interface number from the path's MI value
1274 interface_number = 0;
1275 for (i=0; device_id[i] != 0; ) {
1276 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1277 && (device_id[i++] == '_') ) {
1278 interface_number = (device_id[i++] - '0')*10;
1279 interface_number += device_id[i] - '0';
1284 if (device_id[i] == 0) {
1285 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1286 device_id, interface_number);
1289 if (priv->usb_interface[interface_number].path != NULL) {
1290 if (api == USB_API_HID) {
1291 // HID devices can have multiple collections (COL##) for each MI_## interface
1292 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1293 interface_number, device_id);
1294 return LIBUSB_ERROR_ACCESS;
1296 // In other cases, just use the latest data
1297 safe_free(priv->usb_interface[interface_number].path);
1300 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1301 priv->usb_interface[interface_number].path = dev_interface_path;
1302 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1303 priv->usb_interface[interface_number].sub_api = sub_api;
1304 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1305 priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
1306 if (priv->hid == NULL)
1307 return LIBUSB_ERROR_NO_MEM;
1310 return LIBUSB_SUCCESS;
1313 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1314 char* dev_interface_path)
1317 struct windows_device_priv *priv = _device_priv(dev);
1319 if (priv->hid == NULL) {
1320 usbi_err(ctx, "program assertion failed: parent is not HID");
1321 return LIBUSB_ERROR_NO_DEVICE;
1323 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1324 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1325 return LIBUSB_ERROR_NO_DEVICE;
1327 for (i=0; i<priv->hid->nb_interfaces; i++) {
1328 if (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
1329 usbi_dbg("interface[%d] already set to %s", i, dev_interface_path);
1330 return LIBUSB_SUCCESS;
1334 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1335 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1336 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1337 priv->hid->nb_interfaces++;
1338 return LIBUSB_SUCCESS;
1342 * get_device_list: libusb backend device enumeration function
1344 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1346 struct discovered_devs *discdevs;
1347 HDEVINFO dev_info = { 0 };
1348 const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1349 SP_DEVINFO_DATA dev_info_data = { 0 };
1350 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1352 #define MAX_ENUM_GUIDS 64
1353 const GUID* guid[MAX_ENUM_GUIDS];
1359 int r = LIBUSB_SUCCESS;
1361 size_t class_index = 0;
1362 unsigned int nb_guids, pass, i, j, ancestor;
1363 char path[MAX_PATH_LENGTH];
1364 char strbuf[MAX_PATH_LENGTH];
1365 struct libusb_device *dev, *parent_dev;
1366 struct windows_device_priv *priv, *parent_priv;
1367 char* dev_interface_path = NULL;
1368 char* dev_id_path = NULL;
1369 unsigned long session_id;
1370 DWORD size, reg_type, port_nr, install_state;
1372 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1375 // Keep a list of newly allocated devs to unref
1376 libusb_device** unref_list;
1377 unsigned int unref_size = 64;
1378 unsigned int unref_cur = 0;
1380 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1381 // PASS 2 : (re)enumerate HUBS
1382 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1383 // and list additional USB device interface GUIDs to explore
1384 // PASS 4 : (re)enumerate master USB devices that have a device interface
1385 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1386 // set the device interfaces.
1388 // Init the GUID table
1389 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1390 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1391 guid[GEN_PASS] = NULL;
1392 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1393 HidD_GetHidGuid(&hid_guid);
1394 guid[HID_PASS] = &hid_guid;
1395 nb_guids = HID_PASS+1;
1397 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1398 if (unref_list == NULL) {
1399 return LIBUSB_ERROR_NO_MEM;
1402 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1403 //#define ENUM_DEBUG
1405 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1406 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1407 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1409 for (i = 0; ; i++) {
1410 // safe loop: free up any (unprotected) dynamic resource
1411 // NB: this is always executed before breaking the loop
1412 safe_free(dev_interface_details);
1413 safe_free(dev_interface_path);
1414 safe_free(dev_id_path);
1415 priv = parent_priv = NULL;
1416 dev = parent_dev = NULL;
1418 // Safe loop: end of loop conditions
1419 if (r != LIBUSB_SUCCESS) {
1422 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1423 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1426 if (pass != GEN_PASS) {
1427 // Except for GEN, all passes deal with device interfaces
1428 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1429 if (dev_interface_details == NULL) {
1432 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1433 if (dev_interface_path == NULL) {
1434 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1439 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1440 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1441 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1442 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1443 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1447 if (class_index >= ARRAYSIZE(usb_class))
1451 // Read the Device ID path. This is what we'll use as UID
1452 // Note that if the device is plugged in a different port or hub, the Device ID changes
1453 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1454 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1455 dev_info_data.DevInst);
1458 dev_id_path = sanitize_path(path);
1459 if (dev_id_path == NULL) {
1460 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1461 dev_info_data.DevInst);
1465 usbi_dbg("PRO: %s", dev_id_path);
1468 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1470 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1471 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1472 ®_type, (BYTE*)&port_nr, 4, &size))
1474 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1475 dev_id_path, windows_error_str(0));
1480 // Set API to use or get additional data from generic pass
1481 api = USB_API_UNSUPPORTED;
1482 sub_api = SUB_API_NOTSET;
1487 // We use the GEN pass to detect driverless devices...
1488 size = sizeof(strbuf);
1489 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1490 ®_type, (BYTE*)strbuf, size, &size)) {
1491 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1492 usbi_info(ctx, "libusb will not be able to access it.");
1494 // ...and to add the additional device interface GUIDs
1495 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1496 if (key != INVALID_HANDLE_VALUE) {
1497 size = sizeof(guid_string_w);
1498 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1499 (BYTE*)guid_string_w, &size);
1501 if (s == ERROR_SUCCESS) {
1502 if (nb_guids >= MAX_ENUM_GUIDS) {
1503 // If this assert is ever reported, grow a GUID table dynamically
1504 usbi_err(ctx, "program assertion failed: too many GUIDs");
1505 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1507 if_guid = (GUID*) calloc(1, sizeof(GUID));
1508 pCLSIDFromString(guid_string_w, if_guid);
1509 guid[nb_guids++] = if_guid;
1510 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1518 // Get the API type (after checking that the driver installation is OK)
1519 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1520 ®_type, (BYTE*)&install_state, 4, &size))
1522 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1523 dev_id_path, windows_error_str(0));
1524 } else if (install_state != 0) {
1525 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1526 dev_id_path, install_state);
1529 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1533 // Find parent device (for the passes that need it)
1540 // Go through the ancestors until we see a face we recognize
1542 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1543 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1544 if (session_id == 0) {
1547 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1549 if (parent_dev == NULL) {
1550 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1553 parent_priv = _device_priv(parent_dev);
1554 // virtual USB devices are also listed during GEN - don't process these yet
1555 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1556 libusb_unref_device(parent_dev);
1562 // Create new or match existing device, using the (hashed) device_id as session id
1563 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1564 // These are the passes that create "new" devices
1565 session_id = htab_hash(dev_id_path);
1566 dev = usbi_get_device_by_session_id(ctx, session_id);
1568 if (pass == DEV_PASS) {
1569 // This can occur if the OS only reports a newly plugged device after we started enum
1570 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1571 " - ignoring", dev_id_path);
1574 usbi_dbg("allocating new device for session [%X]", session_id);
1575 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1576 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1578 windows_device_priv_init(dev);
1580 usbi_dbg("found existing device for session [%X] (%d.%d)",
1581 session_id, dev->bus_number, dev->device_address);
1583 // Keep track of devices that need unref
1584 unref_list[unref_cur++] = dev;
1585 if (unref_cur >= unref_size) {
1587 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1588 if (unref_list == NULL) {
1589 usbi_err(ctx, "could not realloc list for unref - aborting.");
1590 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1593 priv = _device_priv(dev);
1599 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1600 dev->device_address = 0;
1601 dev->num_configurations = 0;
1602 priv->apib = &usb_api_backend[USB_API_HUB];
1603 priv->sub_api = SUB_API_NOTSET;
1604 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1605 priv->path = dev_interface_path; dev_interface_path = NULL;
1609 // If the device has already been setup, don't do it again
1610 if (priv->path != NULL)
1612 // Take care of API initialization
1613 priv->path = dev_interface_path; dev_interface_path = NULL;
1614 priv->apib = &usb_api_backend[api];
1615 priv->sub_api = sub_api;
1617 case USB_API_COMPOSITE:
1621 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1622 if (priv->hid == NULL) {
1623 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1625 priv->hid->nb_interfaces = 0;
1628 // For other devices, the first interface is the same as the device
1629 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1630 if (priv->usb_interface[0].path != NULL) {
1631 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1633 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1635 // The following is needed if we want API calls to work for both simple
1636 // and composite devices.
1637 for(j=0; j<USB_MAXINTERFACES; j++) {
1638 priv->usb_interface[j].apib = &usb_api_backend[api];
1644 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1645 if (r == LIBUSB_SUCCESS) {
1646 // Append device to the list of discovered devices
1647 discdevs = discovered_devs_append(*_discdevs, dev);
1649 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1651 *_discdevs = discdevs;
1652 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1653 // This can occur if the device was disconnected but Windows hasn't
1654 // refreshed its enumeration yet - in that case, we ignore the device
1658 default: // HID_PASS and later
1659 if (parent_priv->apib->id == USB_API_HID) {
1660 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1661 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1662 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1663 dev_interface_path = NULL;
1664 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1665 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1666 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1667 case LIBUSB_SUCCESS:
1668 dev_interface_path = NULL;
1670 case LIBUSB_ERROR_ACCESS:
1671 // interface has already been set => make sure dev_interface_path is freed then
1678 libusb_unref_device(parent_dev);
1684 // Free any additional GUIDs
1685 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1686 safe_free(guid[pass]);
1689 // Unref newly allocated devs
1690 for (i=0; i<unref_cur; i++) {
1691 safe_unref_device(unref_list[i]);
1693 safe_free(unref_list);
1699 * exit: libusb backend deinitialization function
1701 static void windows_exit(void)
1705 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1707 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1708 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1709 if (semaphore == NULL) {
1713 // A successful wait brings our semaphore count to 0 (unsignaled)
1714 // => any concurent wait stalls until the semaphore release
1715 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1716 CloseHandle(semaphore);
1720 // Only works if exits and inits are balanced exactly
1721 if (--concurrent_usage < 0) { // Last exit
1722 for (i=0; i<USB_API_MAX; i++) {
1723 usb_api_backend[i].exit(SUB_API_NOTSET);
1728 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1729 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1730 usbi_dbg("could not wait for timer thread to quit");
1731 TerminateThread(timer_thread, 1);
1733 CloseHandle(timer_thread);
1734 timer_thread = NULL;
1736 for (i = 0; i < 2; i++) {
1737 if (timer_request[i]) {
1738 CloseHandle(timer_request[i]);
1739 timer_request[i] = NULL;
1742 if (timer_response) {
1743 CloseHandle(timer_response);
1744 timer_response = NULL;
1747 CloseHandle(timer_mutex);
1753 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1754 CloseHandle(semaphore);
1757 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1759 struct windows_device_priv *priv = _device_priv(dev);
1761 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1764 return LIBUSB_SUCCESS;
1767 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1769 struct windows_device_priv *priv = _device_priv(dev);
1770 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1773 // config index is zero based
1774 if (config_index >= dev->num_configurations)
1775 return LIBUSB_ERROR_INVALID_PARAM;
1777 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1778 return LIBUSB_ERROR_NOT_FOUND;
1780 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1782 size = min(config_header->wTotalLength, len);
1783 memcpy(buffer, priv->config_descriptor[config_index], size);
1790 * return the cached copy of the active config descriptor
1792 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1794 struct windows_device_priv *priv = _device_priv(dev);
1796 if (priv->active_config == 0)
1797 return LIBUSB_ERROR_NOT_FOUND;
1799 // config index is zero based
1800 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1803 static int windows_open(struct libusb_device_handle *dev_handle)
1805 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1806 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1808 if (priv->apib == NULL) {
1809 usbi_err(ctx, "program assertion failed - device is not initialized");
1810 return LIBUSB_ERROR_NO_DEVICE;
1813 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1816 static void windows_close(struct libusb_device_handle *dev_handle)
1818 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1820 priv->apib->close(SUB_API_NOTSET, dev_handle);
1823 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1825 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1827 if (priv->active_config == 0) {
1829 return LIBUSB_ERROR_NOT_FOUND;
1832 *config = priv->active_config;
1833 return LIBUSB_SUCCESS;
1837 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1838 * does not currently expose a service that allows higher-level drivers to set
1839 * the configuration."
1841 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1843 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1844 int r = LIBUSB_SUCCESS;
1846 if (config >= USB_MAXCONFIG)
1847 return LIBUSB_ERROR_INVALID_PARAM;
1849 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1850 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1851 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1854 if (r == LIBUSB_SUCCESS) {
1855 priv->active_config = (uint8_t)config;
1860 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1862 int r = LIBUSB_SUCCESS;
1863 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1865 if (iface >= USB_MAXINTERFACES)
1866 return LIBUSB_ERROR_INVALID_PARAM;
1868 safe_free(priv->usb_interface[iface].endpoint);
1869 priv->usb_interface[iface].nb_endpoints= 0;
1871 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1873 if (r == LIBUSB_SUCCESS) {
1874 r = windows_assign_endpoints(dev_handle, iface, 0);
1880 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1882 int r = LIBUSB_SUCCESS;
1883 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1885 safe_free(priv->usb_interface[iface].endpoint);
1886 priv->usb_interface[iface].nb_endpoints= 0;
1888 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1890 if (r == LIBUSB_SUCCESS) {
1891 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1897 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1899 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1901 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1904 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1906 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1907 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1910 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1912 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1913 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1916 // The 3 functions below are unlikely to ever get supported on Windows
1917 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1919 return LIBUSB_ERROR_NOT_SUPPORTED;
1922 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1924 return LIBUSB_ERROR_NOT_SUPPORTED;
1927 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1929 return LIBUSB_ERROR_NOT_SUPPORTED;
1932 static void windows_destroy_device(struct libusb_device *dev)
1934 windows_device_priv_release(dev);
1937 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1939 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1941 usbi_free_fd(&transfer_priv->pollable_fd);
1942 safe_free(transfer_priv->hid_buffer);
1943 // When auto claim is in use, attempt to release the auto-claimed interface
1944 auto_release(itransfer);
1947 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1949 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1950 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1951 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1952 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1955 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1956 if (r != LIBUSB_SUCCESS) {
1960 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1961 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1963 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1964 return LIBUSB_SUCCESS;
1967 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1969 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1970 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1971 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1972 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1975 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1976 if (r != LIBUSB_SUCCESS) {
1980 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1981 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1983 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1984 return LIBUSB_SUCCESS;
1987 static int submit_control_transfer(struct usbi_transfer *itransfer)
1989 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1990 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1991 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1992 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1995 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1996 if (r != LIBUSB_SUCCESS) {
2000 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
2002 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
2003 return LIBUSB_SUCCESS;
2007 static int windows_submit_transfer(struct usbi_transfer *itransfer)
2009 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2011 switch (transfer->type) {
2012 case LIBUSB_TRANSFER_TYPE_CONTROL:
2013 return submit_control_transfer(itransfer);
2014 case LIBUSB_TRANSFER_TYPE_BULK:
2015 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2016 if (IS_XFEROUT(transfer) &&
2017 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
2018 return LIBUSB_ERROR_NOT_SUPPORTED;
2019 return submit_bulk_transfer(itransfer);
2020 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2021 return submit_iso_transfer(itransfer);
2022 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2023 return LIBUSB_ERROR_NOT_SUPPORTED;
2025 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2026 return LIBUSB_ERROR_INVALID_PARAM;
2030 static int windows_abort_control(struct usbi_transfer *itransfer)
2032 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2033 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2035 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2038 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2040 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2041 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2043 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2046 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2048 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2050 switch (transfer->type) {
2051 case LIBUSB_TRANSFER_TYPE_CONTROL:
2052 return windows_abort_control(itransfer);
2053 case LIBUSB_TRANSFER_TYPE_BULK:
2054 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2055 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2056 return windows_abort_transfers(itransfer);
2057 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2058 return LIBUSB_ERROR_NOT_SUPPORTED;
2060 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2061 return LIBUSB_ERROR_INVALID_PARAM;
2065 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2067 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2068 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2069 int status, istatus;
2071 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
2075 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2077 case ERROR_GEN_FAILURE:
2078 usbi_dbg("detected endpoint stall");
2079 status = LIBUSB_TRANSFER_STALL;
2081 case ERROR_SEM_TIMEOUT:
2082 usbi_dbg("detected semaphore timeout");
2083 status = LIBUSB_TRANSFER_TIMED_OUT;
2085 case ERROR_OPERATION_ABORTED:
2086 istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2087 if (istatus != LIBUSB_TRANSFER_COMPLETED) {
2088 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
2090 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2091 usbi_dbg("detected timeout");
2092 status = LIBUSB_TRANSFER_TIMED_OUT;
2094 usbi_dbg("detected operation aborted");
2095 status = LIBUSB_TRANSFER_CANCELLED;
2099 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(io_result));
2100 status = LIBUSB_TRANSFER_ERROR;
2103 windows_clear_transfer_priv(itransfer); // Cancel polling
2104 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2107 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2109 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2111 switch (transfer->type) {
2112 case LIBUSB_TRANSFER_TYPE_CONTROL:
2113 case LIBUSB_TRANSFER_TYPE_BULK:
2114 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2115 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2116 windows_transfer_callback (itransfer, io_result, io_size);
2118 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2119 usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
2122 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2126 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2128 struct windows_transfer_priv* transfer_priv = NULL;
2129 POLL_NFDS_TYPE i = 0;
2131 struct usbi_transfer *transfer;
2132 DWORD io_size, io_result;
2134 usbi_mutex_lock(&ctx->open_devs_lock);
2135 for (i = 0; i < nfds && num_ready > 0; i++) {
2137 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2139 if (!fds[i].revents) {
2145 // Because a Windows OVERLAPPED is used for poll emulation,
2146 // a pollable fd is created and stored with each transfer
2147 usbi_mutex_lock(&ctx->flying_transfers_lock);
2148 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2149 transfer_priv = usbi_transfer_get_os_priv(transfer);
2150 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2155 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2158 // Handle async requests that completed synchronously first
2159 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2160 io_result = NO_ERROR;
2161 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2162 // Regular async overlapped
2163 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2164 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2165 io_result = NO_ERROR;
2167 io_result = GetLastError();
2169 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2170 // let handle_callback free the event using the transfer wfd
2171 // If you don't use the transfer wfd, you run a risk of trying to free a
2172 // newly allocated wfd that took the place of the one from the transfer.
2173 windows_handle_callback(transfer, io_result, io_size);
2175 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2176 return LIBUSB_ERROR_NOT_FOUND;
2180 usbi_mutex_unlock(&ctx->open_devs_lock);
2181 return LIBUSB_SUCCESS;
2185 * Monotonic and real time functions
2187 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2189 LARGE_INTEGER hires_counter, li_frequency;
2193 // Init - find out if we have access to a monotonic (hires) timer
2194 if (!QueryPerformanceFrequency(&li_frequency)) {
2195 usbi_dbg("no hires timer available on this platform");
2196 hires_frequency = 0;
2197 hires_ticks_to_ps = UINT64_C(0);
2199 hires_frequency = li_frequency.QuadPart;
2200 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2201 // to picoseconds to compute the tv_nsecs part in clock_gettime
2202 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2203 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2206 // Signal windows_init() that we're ready to service requests
2207 if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
2208 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2211 // Main loop - wait for requests
2213 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2214 if ( (timer_index != 0) && (timer_index != 1) ) {
2215 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2218 if (request_count[timer_index] == 0) {
2219 // Request already handled
2220 ResetEvent(timer_request[timer_index]);
2221 // There's still a possiblity that a thread sends a request between the
2222 // time we test request_count[] == 0 and we reset the event, in which case
2223 // the request would be ignored. The simple solution to that is to test
2224 // request_count again and process requests if non zero.
2225 if (request_count[timer_index] == 0)
2228 switch (timer_index) {
2230 WaitForSingleObject(timer_mutex, INFINITE);
2231 // Requests to this thread are for hires always
2232 if (QueryPerformanceCounter(&hires_counter) != 0) {
2233 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2234 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2236 // Fallback to real-time if we can't get monotonic value
2237 // Note that real-time clock does not wait on the mutex or this thread.
2238 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2240 ReleaseMutex(timer_mutex);
2242 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2244 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2245 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2248 case 1: // time to quit
2249 usbi_dbg("timer thread quitting");
2255 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2258 ULARGE_INTEGER rtime;
2261 case USBI_CLOCK_MONOTONIC:
2262 if (hires_frequency != 0) {
2264 InterlockedIncrement((LONG*)&request_count[0]);
2265 SetEvent(timer_request[0]);
2266 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2269 WaitForSingleObject(timer_mutex, INFINITE);
2271 ReleaseMutex(timer_mutex);
2272 return LIBUSB_SUCCESS;
2274 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2275 break; // Retry until successful
2277 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2278 return LIBUSB_ERROR_OTHER;
2282 // Fall through and return real-time if monotonic was not detected @ timer init
2283 case USBI_CLOCK_REALTIME:
2284 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2285 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2286 // Note however that our resolution is bounded by the Windows system time
2287 // functions and is at best of the order of 1 ms (or, usually, worse)
2288 GetSystemTimeAsFileTime(&filetime);
2289 rtime.LowPart = filetime.dwLowDateTime;
2290 rtime.HighPart = filetime.dwHighDateTime;
2291 rtime.QuadPart -= epoch_time;
2292 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2293 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2294 return LIBUSB_SUCCESS;
2296 return LIBUSB_ERROR_INVALID_PARAM;
2301 // NB: MSVC6 does not support named initializers.
2302 const struct usbi_os_backend windows_backend = {
2304 USBI_CAP_HAS_HID_ACCESS,
2308 windows_get_device_list,
2309 NULL, /* hotplug_poll */
2313 windows_get_device_descriptor,
2314 windows_get_active_config_descriptor,
2315 windows_get_config_descriptor,
2316 NULL, /* get_config_descriptor_by_value() */
2318 windows_get_configuration,
2319 windows_set_configuration,
2320 windows_claim_interface,
2321 windows_release_interface,
2323 windows_set_interface_altsetting,
2325 windows_reset_device,
2327 NULL, /* alloc_streams */
2328 NULL, /* free_streams */
2330 windows_kernel_driver_active,
2331 windows_detach_kernel_driver,
2332 windows_attach_kernel_driver,
2334 windows_destroy_device,
2336 windows_submit_transfer,
2337 windows_cancel_transfer,
2338 windows_clear_transfer_priv,
2340 windows_handle_events,
2342 windows_clock_gettime,
2343 #if defined(USBI_TIMERFD_AVAILABLE)
2346 sizeof(struct windows_device_priv),
2347 sizeof(struct windows_device_handle_priv),
2348 sizeof(struct windows_transfer_priv),
2356 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2357 return LIBUSB_SUCCESS;
2359 static int unsupported_exit(int sub_api) {
2360 return LIBUSB_SUCCESS;
2362 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2363 PRINT_UNSUPPORTED_API(open);
2365 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2366 usbi_dbg("unsupported API call for 'close'");
2368 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2369 PRINT_UNSUPPORTED_API(configure_endpoints);
2371 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2372 PRINT_UNSUPPORTED_API(claim_interface);
2374 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2375 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2377 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2378 PRINT_UNSUPPORTED_API(release_interface);
2380 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2381 PRINT_UNSUPPORTED_API(clear_halt);
2383 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2384 PRINT_UNSUPPORTED_API(reset_device);
2386 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2387 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2389 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2390 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2392 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2393 PRINT_UNSUPPORTED_API(submit_control_transfer);
2395 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2396 PRINT_UNSUPPORTED_API(abort_control);
2398 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2399 PRINT_UNSUPPORTED_API(abort_transfers);
2401 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2402 PRINT_UNSUPPORTED_API(copy_transfer_data);
2404 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2405 return LIBUSB_SUCCESS;
2407 // These names must be uppercase
2408 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "USB3HUB", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB", "VUSB3HUB", "AMDHUB30"};
2409 const char* composite_driver_names[] = {"USBCCGP"};
2410 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2411 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2412 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2414 USB_API_UNSUPPORTED,
2422 unsupported_configure_endpoints,
2423 unsupported_claim_interface,
2424 unsupported_set_interface_altsetting,
2425 unsupported_release_interface,
2426 unsupported_clear_halt,
2427 unsupported_reset_device,
2428 unsupported_submit_bulk_transfer,
2429 unsupported_submit_iso_transfer,
2430 unsupported_submit_control_transfer,
2431 unsupported_abort_control,
2432 unsupported_abort_transfers,
2433 unsupported_copy_transfer_data,
2438 ARRAYSIZE(hub_driver_names),
2443 unsupported_configure_endpoints,
2444 unsupported_claim_interface,
2445 unsupported_set_interface_altsetting,
2446 unsupported_release_interface,
2447 unsupported_clear_halt,
2448 unsupported_reset_device,
2449 unsupported_submit_bulk_transfer,
2450 unsupported_submit_iso_transfer,
2451 unsupported_submit_control_transfer,
2452 unsupported_abort_control,
2453 unsupported_abort_transfers,
2454 unsupported_copy_transfer_data,
2458 composite_driver_names,
2459 ARRAYSIZE(composite_driver_names),
2464 common_configure_endpoints,
2465 composite_claim_interface,
2466 composite_set_interface_altsetting,
2467 composite_release_interface,
2468 composite_clear_halt,
2469 composite_reset_device,
2470 composite_submit_bulk_transfer,
2471 composite_submit_iso_transfer,
2472 composite_submit_control_transfer,
2473 composite_abort_control,
2474 composite_abort_transfers,
2475 composite_copy_transfer_data,
2479 winusbx_driver_names,
2480 ARRAYSIZE(winusbx_driver_names),
2485 winusbx_configure_endpoints,
2486 winusbx_claim_interface,
2487 winusbx_set_interface_altsetting,
2488 winusbx_release_interface,
2490 winusbx_reset_device,
2491 winusbx_submit_bulk_transfer,
2492 unsupported_submit_iso_transfer,
2493 winusbx_submit_control_transfer,
2494 winusbx_abort_control,
2495 winusbx_abort_transfers,
2496 winusbx_copy_transfer_data,
2501 ARRAYSIZE(hid_driver_names),
2506 common_configure_endpoints,
2507 hid_claim_interface,
2508 hid_set_interface_altsetting,
2509 hid_release_interface,
2512 hid_submit_bulk_transfer,
2513 unsupported_submit_iso_transfer,
2514 hid_submit_control_transfer,
2515 hid_abort_transfers,
2516 hid_abort_transfers,
2517 hid_copy_transfer_data,
2523 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2525 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2526 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2528 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2531 bool native_winusb = false;
2533 KLIB_VERSION LibK_Version;
2534 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2535 LibK_GetVersion_t pLibK_GetVersion = NULL;
2537 h = GetModuleHandleA("libusbK");
2539 h = LoadLibraryA("libusbK");
2542 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2543 h = GetModuleHandleA("WinUSB");
2545 h = LoadLibraryA("WinUSB");
2547 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2548 "you will not be able to access devices outside of enumeration");
2549 return LIBUSB_ERROR_NOT_FOUND;
2552 usbi_dbg("using libusbK DLL for universal access");
2553 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2554 if (pLibK_GetVersion != NULL) {
2555 pLibK_GetVersion(&LibK_Version);
2556 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2557 LibK_Version.Micro, LibK_Version.Nano);
2559 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2560 if (pLibK_GetProcAddress == NULL) {
2561 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2562 return LIBUSB_ERROR_NOT_FOUND;
2565 native_winusb = (pLibK_GetProcAddress == NULL);
2566 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2567 WinUSBX_Set(AbortPipe);
2568 WinUSBX_Set(ControlTransfer);
2569 WinUSBX_Set(FlushPipe);
2571 WinUSBX_Set(GetAssociatedInterface);
2572 WinUSBX_Set(GetCurrentAlternateSetting);
2573 WinUSBX_Set(GetDescriptor);
2574 WinUSBX_Set(GetOverlappedResult);
2575 WinUSBX_Set(GetPipePolicy);
2576 WinUSBX_Set(GetPowerPolicy);
2577 WinUSBX_Set(Initialize);
2578 WinUSBX_Set(QueryDeviceInformation);
2579 WinUSBX_Set(QueryInterfaceSettings);
2580 WinUSBX_Set(QueryPipe);
2581 WinUSBX_Set(ReadPipe);
2582 WinUSBX_Set(ResetPipe);
2583 WinUSBX_Set(SetCurrentAlternateSetting);
2584 WinUSBX_Set(SetPipePolicy);
2585 WinUSBX_Set(SetPowerPolicy);
2586 WinUSBX_Set(WritePipe);
2587 if (!native_winusb) {
2588 WinUSBX_Set(ResetDevice);
2590 if (WinUSBX[i].Initialize != NULL) {
2591 WinUSBX[i].initialized = true;
2592 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2594 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2595 WinUSBX[i].initialized = false;
2598 return LIBUSB_SUCCESS;
2601 static int winusbx_exit(int sub_api)
2603 return LIBUSB_SUCCESS;
2606 // NB: open and close must ensure that they only handle interface of
2607 // the right API type, as these functions can be called wholesale from
2608 // composite_open(), with interfaces belonging to different APIs
2609 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2611 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2612 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2613 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2618 CHECK_WINUSBX_AVAILABLE(sub_api);
2620 // WinUSB requires a seperate handle for each interface
2621 for (i = 0; i < USB_MAXINTERFACES; i++) {
2622 if ( (priv->usb_interface[i].path != NULL)
2623 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2624 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2625 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2626 if (file_handle == INVALID_HANDLE_VALUE) {
2627 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2628 switch(GetLastError()) {
2629 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2630 return LIBUSB_ERROR_NO_DEVICE;
2631 case ERROR_ACCESS_DENIED:
2632 return LIBUSB_ERROR_ACCESS;
2634 return LIBUSB_ERROR_IO;
2637 handle_priv->interface_handle[i].dev_handle = file_handle;
2641 return LIBUSB_SUCCESS;
2644 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2646 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2647 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2651 if (sub_api == SUB_API_NOTSET)
2652 sub_api = priv->sub_api;
2653 if (!WinUSBX[sub_api].initialized)
2656 for (i = 0; i < USB_MAXINTERFACES; i++) {
2657 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2658 file_handle = handle_priv->interface_handle[i].dev_handle;
2659 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2660 CloseHandle(file_handle);
2666 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2668 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2669 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2670 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2673 uint8_t endpoint_address;
2676 CHECK_WINUSBX_AVAILABLE(sub_api);
2678 // With handle and enpoints set (in parent), we can setup the default pipe properties
2679 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2680 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2681 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2682 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2683 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2684 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2686 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2687 continue; // Other policies don't apply to control endpoint or libusb0
2690 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2691 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2692 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2694 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2695 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2696 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2699 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2700 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2701 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2702 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2703 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2705 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2706 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2707 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2711 return LIBUSB_SUCCESS;
2714 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2716 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2717 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2718 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2719 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2720 HANDLE file_handle, winusb_handle;
2723 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2724 HDEVINFO dev_info = INVALID_HANDLE_VALUE;
2725 SP_DEVINFO_DATA dev_info_data;
2726 char* dev_path_no_guid = NULL;
2727 char filter_path[] = "\\\\.\\libusb0-0000";
2728 bool found_filter = false;
2730 CHECK_WINUSBX_AVAILABLE(sub_api);
2732 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2733 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2734 if ((is_using_usbccgp) || (iface == 0)) {
2735 // composite device (independent interfaces) or interface 0
2736 file_handle = handle_priv->interface_handle[iface].dev_handle;
2737 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2738 return LIBUSB_ERROR_NOT_FOUND;
2741 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2742 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2743 err = GetLastError();
2745 case ERROR_BAD_COMMAND:
2746 // The device was disconnected
2747 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2748 return LIBUSB_ERROR_NO_DEVICE;
2750 // it may be that we're using the libusb0 filter driver.
2751 // TODO: can we move this whole business into the K/0 DLL?
2752 for (i = 0; ; i++) {
2753 safe_free(dev_interface_details);
2754 safe_free(dev_path_no_guid);
2755 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2756 if ((found_filter) || (dev_interface_details == NULL)) {
2760 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2761 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2762 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2763 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2764 if (file_handle == INVALID_HANDLE_VALUE) {
2765 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2767 WinUSBX[sub_api].Free(winusb_handle);
2768 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2771 found_filter = true;
2776 if (!found_filter) {
2777 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2778 return LIBUSB_ERROR_ACCESS;
2782 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2784 // For all other interfaces, use GetAssociatedInterface()
2785 winusb_handle = handle_priv->interface_handle[0].api_handle;
2786 // It is a requirement for multiple interface devices on Windows that, to you
2787 // must first claim the first interface before you claim the others
2788 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2789 file_handle = handle_priv->interface_handle[0].dev_handle;
2790 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2791 handle_priv->interface_handle[0].api_handle = winusb_handle;
2792 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2794 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2795 return LIBUSB_ERROR_ACCESS;
2798 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2799 &handle_priv->interface_handle[iface].api_handle)) {
2800 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2801 switch(GetLastError()) {
2802 case ERROR_NO_MORE_ITEMS: // invalid iface
2803 return LIBUSB_ERROR_NOT_FOUND;
2804 case ERROR_BAD_COMMAND: // The device was disconnected
2805 return LIBUSB_ERROR_NO_DEVICE;
2806 case ERROR_ALREADY_EXISTS: // already claimed
2807 return LIBUSB_ERROR_BUSY;
2809 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2810 return LIBUSB_ERROR_ACCESS;
2814 usbi_dbg("claimed interface %d", iface);
2815 handle_priv->active_interface = iface;
2817 return LIBUSB_SUCCESS;
2820 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2822 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2823 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2824 HANDLE winusb_handle;
2826 CHECK_WINUSBX_AVAILABLE(sub_api);
2828 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2829 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2830 return LIBUSB_ERROR_NOT_FOUND;
2833 WinUSBX[sub_api].Free(winusb_handle);
2834 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2836 return LIBUSB_SUCCESS;
2840 * Return the first valid interface (of the same API type), for control transfers
2842 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2844 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2845 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2848 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2849 usbi_dbg("unsupported API ID");
2853 for (i=0; i<USB_MAXINTERFACES; i++) {
2854 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2855 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2856 && (handle_priv->interface_handle[i].api_handle != 0)
2857 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2858 && (priv->usb_interface[i].apib->id == api_id) ) {
2866 * Lookup interface by endpoint address. -1 if not found
2868 static int interface_by_endpoint(struct windows_device_priv *priv,
2869 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2872 for (i=0; i<USB_MAXINTERFACES; i++) {
2873 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2875 if (handle_priv->interface_handle[i].api_handle == 0)
2877 if (priv->usb_interface[i].endpoint == NULL)
2879 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2880 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2888 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2890 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2891 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2892 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2893 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2894 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2895 transfer->dev_handle);
2896 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2898 HANDLE winusb_handle;
2899 int current_interface;
2902 CHECK_WINUSBX_AVAILABLE(sub_api);
2904 transfer_priv->pollable_fd = INVALID_WINFD;
2905 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2907 if (size > MAX_CTRL_BUFFER_LENGTH)
2908 return LIBUSB_ERROR_INVALID_PARAM;
2910 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2911 if (current_interface < 0) {
2912 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2913 return LIBUSB_ERROR_NOT_FOUND;
2917 usbi_dbg("will use interface %d", current_interface);
2918 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2920 wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
2921 // Always use the handle returned from usbi_create_fd (wfd.handle)
2923 return LIBUSB_ERROR_NO_MEM;
2926 // Sending of set configuration control requests from WinUSB creates issues
2927 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2928 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2929 if (setup->value != priv->active_config) {
2930 usbi_warn(ctx, "cannot set configuration other than the default one");
2932 return LIBUSB_ERROR_INVALID_PARAM;
2934 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2935 wfd.overlapped->InternalHigh = 0;
2937 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2938 if(GetLastError() != ERROR_IO_PENDING) {
2939 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2941 return LIBUSB_ERROR_IO;
2944 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2945 wfd.overlapped->InternalHigh = (DWORD)size;
2949 // Use priv_transfer to store data needed for async polling
2950 transfer_priv->pollable_fd = wfd;
2951 transfer_priv->interface_number = (uint8_t)current_interface;
2953 return LIBUSB_SUCCESS;
2956 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2958 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2959 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2960 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2961 HANDLE winusb_handle;
2963 CHECK_WINUSBX_AVAILABLE(sub_api);
2965 if (altsetting > 255) {
2966 return LIBUSB_ERROR_INVALID_PARAM;
2969 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2970 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2971 usbi_err(ctx, "interface must be claimed first");
2972 return LIBUSB_ERROR_NOT_FOUND;
2975 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2976 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2977 return LIBUSB_ERROR_IO;
2980 return LIBUSB_SUCCESS;
2983 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2985 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2986 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2987 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2988 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2989 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2990 HANDLE winusb_handle;
2992 int current_interface;
2995 CHECK_WINUSBX_AVAILABLE(sub_api);
2997 transfer_priv->pollable_fd = INVALID_WINFD;
2999 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3000 if (current_interface < 0) {
3001 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3002 return LIBUSB_ERROR_NOT_FOUND;
3005 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3007 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3009 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
3010 // Always use the handle returned from usbi_create_fd (wfd.handle)
3012 return LIBUSB_ERROR_NO_MEM;
3015 if (IS_XFERIN(transfer)) {
3016 usbi_dbg("reading %d bytes", transfer->length);
3017 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
3019 usbi_dbg("writing %d bytes", transfer->length);
3020 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
3023 if(GetLastError() != ERROR_IO_PENDING) {
3024 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
3026 return LIBUSB_ERROR_IO;
3029 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3030 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
3033 transfer_priv->pollable_fd = wfd;
3034 transfer_priv->interface_number = (uint8_t)current_interface;
3036 return LIBUSB_SUCCESS;
3039 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3041 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3042 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3043 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3044 HANDLE winusb_handle;
3045 int current_interface;
3047 CHECK_WINUSBX_AVAILABLE(sub_api);
3049 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3050 if (current_interface < 0) {
3051 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3052 return LIBUSB_ERROR_NOT_FOUND;
3055 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3056 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3058 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3059 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3060 return LIBUSB_ERROR_NO_DEVICE;
3063 return LIBUSB_SUCCESS;
3067 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3068 * through testing as well):
3069 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3070 * the control transfer using CancelIo"
3072 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3074 // Cancelling of the I/O is done in the parent
3075 return LIBUSB_SUCCESS;
3078 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3080 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3081 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3082 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3083 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3084 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3085 HANDLE winusb_handle;
3086 int current_interface;
3088 CHECK_WINUSBX_AVAILABLE(sub_api);
3090 current_interface = transfer_priv->interface_number;
3091 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3092 usbi_err(ctx, "program assertion failed: invalid interface_number");
3093 return LIBUSB_ERROR_NOT_FOUND;
3095 usbi_dbg("will use interface %d", current_interface);
3097 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3099 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3100 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3101 return LIBUSB_ERROR_NO_DEVICE;
3104 return LIBUSB_SUCCESS;
3108 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3109 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3110 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3111 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3112 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3113 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3115 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3116 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3118 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3119 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3120 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3122 HANDLE winusb_handle;
3125 CHECK_WINUSBX_AVAILABLE(sub_api);
3127 // Reset any available pipe (except control)
3128 for (i=0; i<USB_MAXINTERFACES; i++) {
3129 winusb_handle = handle_priv->interface_handle[i].api_handle;
3130 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3132 // Cancel any pollable I/O
3133 usbi_remove_pollfd(ctx, wfd.fd);
3135 wfd = handle_to_winfd(winusb_handle);
3138 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3139 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3140 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3141 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3142 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3143 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3145 // FlushPipe seems to fail on OUT pipes
3146 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3147 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3148 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3149 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3151 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3152 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3153 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3159 // libusbK & libusb0 have the ability to issue an actual device reset
3160 if (WinUSBX[sub_api].ResetDevice != NULL) {
3161 winusb_handle = handle_priv->interface_handle[0].api_handle;
3162 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3163 WinUSBX[sub_api].ResetDevice(winusb_handle);
3166 return LIBUSB_SUCCESS;
3169 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3171 itransfer->transferred += io_size;
3172 return LIBUSB_TRANSFER_COMPLETED;
3176 * Internal HID Support functions (from libusb-win32)
3177 * Note that functions that complete data transfer synchronously must return
3178 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3180 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3181 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3183 static int _hid_wcslen(WCHAR *str)
3186 while (str[i] && (str[i] != 0x409)) {
3192 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3194 struct libusb_device_descriptor d;
3196 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3197 d.bDescriptorType = LIBUSB_DT_DEVICE;
3198 d.bcdUSB = 0x0200; /* 2.00 */
3200 d.bDeviceSubClass = 0;
3201 d.bDeviceProtocol = 0;
3202 d.bMaxPacketSize0 = 64; /* fix this! */
3203 d.idVendor = (uint16_t)dev->vid;
3204 d.idProduct = (uint16_t)dev->pid;
3205 d.bcdDevice = 0x0100;
3206 d.iManufacturer = dev->string_index[0];
3207 d.iProduct = dev->string_index[1];
3208 d.iSerialNumber = dev->string_index[2];
3209 d.bNumConfigurations = 1;
3211 if (*size > LIBUSB_DT_DEVICE_SIZE)
3212 *size = LIBUSB_DT_DEVICE_SIZE;
3213 memcpy(data, &d, *size);
3214 return LIBUSB_COMPLETED;
3217 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3219 char num_endpoints = 0;
3220 size_t config_total_len = 0;
3221 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3222 struct libusb_config_descriptor *cd;
3223 struct libusb_interface_descriptor *id;
3224 struct libusb_hid_descriptor *hd;
3225 struct libusb_endpoint_descriptor *ed;
3228 if (dev->input_report_size)
3230 if (dev->output_report_size)
3233 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3234 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3237 cd = (struct libusb_config_descriptor *)tmp;
3238 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3239 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3240 + LIBUSB_DT_INTERFACE_SIZE);
3241 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3242 + LIBUSB_DT_INTERFACE_SIZE
3243 + LIBUSB_DT_HID_SIZE);
3245 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3246 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3247 cd->wTotalLength = (uint16_t) config_total_len;
3248 cd->bNumInterfaces = 1;
3249 cd->bConfigurationValue = 1;
3250 cd->iConfiguration = 0;
3251 cd->bmAttributes = 1 << 7; /* bus powered */
3254 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3255 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3256 id->bInterfaceNumber = 0;
3257 id->bAlternateSetting = 0;
3258 id->bNumEndpoints = num_endpoints;
3259 id->bInterfaceClass = 3;
3260 id->bInterfaceSubClass = 0;
3261 id->bInterfaceProtocol = 0;
3264 tmp_size = LIBUSB_DT_HID_SIZE;
3265 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3267 if (dev->input_report_size) {
3268 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3269 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3270 ed->bEndpointAddress = HID_IN_EP;
3271 ed->bmAttributes = 3;
3272 ed->wMaxPacketSize = dev->input_report_size - 1;
3274 ed = (struct libusb_endpoint_descriptor *)((char*)ed + LIBUSB_DT_ENDPOINT_SIZE);
3277 if (dev->output_report_size) {
3278 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3279 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3280 ed->bEndpointAddress = HID_OUT_EP;
3281 ed->bmAttributes = 3;
3282 ed->wMaxPacketSize = dev->output_report_size - 1;
3286 if (*size > config_total_len)
3287 *size = config_total_len;
3288 memcpy(data, tmp, *size);
3289 return LIBUSB_COMPLETED;
3292 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3293 void *data, size_t *size)
3296 size_t tmp_size = 0;
3299 /* language ID, EN-US */
3300 char string_langid[] = {
3305 if ((*size < 2) || (*size > 255)) {
3306 return LIBUSB_ERROR_OVERFLOW;
3310 tmp = string_langid;
3311 tmp_size = sizeof(string_langid)+2;
3313 for (i=0; i<3; i++) {
3314 if (_index == (dev->string_index[i])) {
3315 tmp = dev->string[i];
3316 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3320 if (i == 3) { // not found
3321 return LIBUSB_ERROR_INVALID_PARAM;
3326 return LIBUSB_ERROR_INVALID_PARAM;
3329 if (tmp_size < *size) {
3333 ((uint8_t*)data)[0] = (uint8_t)*size;
3334 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3335 memcpy((uint8_t*)data+2, tmp, *size-2);
3336 return LIBUSB_COMPLETED;
3339 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3341 struct libusb_hid_descriptor d;
3342 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3343 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3345 _hid_get_report_descriptor(dev, tmp, &report_len);
3347 d.bLength = LIBUSB_DT_HID_SIZE;
3348 d.bDescriptorType = LIBUSB_DT_HID;
3349 d.bcdHID = 0x0110; /* 1.10 */
3351 d.bNumDescriptors = 1;
3352 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3353 d.wClassDescriptorLength = (uint16_t)report_len;
3355 if (*size > LIBUSB_DT_HID_SIZE)
3356 *size = LIBUSB_DT_HID_SIZE;
3357 memcpy(data, &d, *size);
3358 return LIBUSB_COMPLETED;
3361 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3363 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3366 /* usage page (0xFFA0 == vendor defined) */
3367 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3368 /* usage (vendor defined) */
3369 d[i++] = 0x09; d[i++] = 0x01;
3370 /* start collection (application) */
3371 d[i++] = 0xA1; d[i++] = 0x01;
3373 if (dev->input_report_size) {
3374 /* usage (vendor defined) */
3375 d[i++] = 0x09; d[i++] = 0x01;
3376 /* logical minimum (0) */
3377 d[i++] = 0x15; d[i++] = 0x00;
3378 /* logical maximum (255) */
3379 d[i++] = 0x25; d[i++] = 0xFF;
3380 /* report size (8 bits) */
3381 d[i++] = 0x75; d[i++] = 0x08;
3383 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3384 /* input (data, variable, absolute) */
3385 d[i++] = 0x81; d[i++] = 0x00;
3388 if (dev->output_report_size) {
3389 /* usage (vendor defined) */
3390 d[i++] = 0x09; d[i++] = 0x02;
3391 /* logical minimum (0) */
3392 d[i++] = 0x15; d[i++] = 0x00;
3393 /* logical maximum (255) */
3394 d[i++] = 0x25; d[i++] = 0xFF;
3395 /* report size (8 bits) */
3396 d[i++] = 0x75; d[i++] = 0x08;
3398 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3399 /* output (data, variable, absolute) */
3400 d[i++] = 0x91; d[i++] = 0x00;
3402 /* feature report */
3403 if (dev->feature_report_size) {
3404 /* usage (vendor defined) */
3405 d[i++] = 0x09; d[i++] = 0x03;
3406 /* logical minimum (0) */
3407 d[i++] = 0x15; d[i++] = 0x00;
3408 /* logical maximum (255) */
3409 d[i++] = 0x25; d[i++] = 0xFF;
3410 /* report size (8 bits) */
3411 d[i++] = 0x75; d[i++] = 0x08;
3413 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3414 /* feature (data, variable, absolute) */
3415 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3418 /* end collection */
3423 memcpy(data, d, *size);
3424 return LIBUSB_COMPLETED;
3427 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3428 int type, int _index, void *data, size_t *size)
3431 case LIBUSB_DT_DEVICE:
3432 usbi_dbg("LIBUSB_DT_DEVICE");
3433 return _hid_get_device_descriptor(dev, data, size);
3434 case LIBUSB_DT_CONFIG:
3435 usbi_dbg("LIBUSB_DT_CONFIG");
3437 return _hid_get_config_descriptor(dev, data, size);
3438 return LIBUSB_ERROR_INVALID_PARAM;
3439 case LIBUSB_DT_STRING:
3440 usbi_dbg("LIBUSB_DT_STRING");
3441 return _hid_get_string_descriptor(dev, _index, data, size);
3443 usbi_dbg("LIBUSB_DT_HID");
3445 return _hid_get_hid_descriptor(dev, data, size);
3446 return LIBUSB_ERROR_INVALID_PARAM;
3447 case LIBUSB_DT_REPORT:
3448 usbi_dbg("LIBUSB_DT_REPORT");
3450 return _hid_get_report_descriptor(dev, data, size);
3451 return LIBUSB_ERROR_INVALID_PARAM;
3452 case LIBUSB_DT_PHYSICAL:
3453 usbi_dbg("LIBUSB_DT_PHYSICAL");
3454 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3455 return LIBUSB_COMPLETED;
3456 return LIBUSB_ERROR_OTHER;
3458 usbi_dbg("unsupported");
3459 return LIBUSB_ERROR_INVALID_PARAM;
3462 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3463 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3467 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3468 int r = LIBUSB_SUCCESS;
3470 if (tp->hid_buffer != NULL) {
3471 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3474 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3475 usbi_dbg("invalid size (%d)", *size);
3476 return LIBUSB_ERROR_INVALID_PARAM;
3479 switch (report_type) {
3480 case HID_REPORT_TYPE_INPUT:
3481 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3483 case HID_REPORT_TYPE_FEATURE:
3484 ioctl_code = IOCTL_HID_GET_FEATURE;
3487 usbi_dbg("unknown HID report type %d", report_type);
3488 return LIBUSB_ERROR_INVALID_PARAM;
3491 // Add a trailing byte to detect overflows
3492 buf = (uint8_t*)calloc(expected_size+1, 1);
3494 return LIBUSB_ERROR_NO_MEM;
3496 buf[0] = (uint8_t)id; // Must be set always
3497 usbi_dbg("report ID: 0x%02X", buf[0]);
3499 tp->hid_expected_size = expected_size;
3500 read_size = expected_size;
3502 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3503 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3504 buf, expected_size+1, &read_size, overlapped)) {
3505 if (GetLastError() != ERROR_IO_PENDING) {
3506 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3508 return LIBUSB_ERROR_IO;
3510 // Asynchronous wait
3511 tp->hid_buffer = buf;
3512 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3513 return LIBUSB_SUCCESS;
3516 // Transfer completed synchronously => copy and discard extra buffer
3517 if (read_size == 0) {
3518 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3522 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3524 if ((size_t)read_size > expected_size) {
3525 r = LIBUSB_ERROR_OVERFLOW;
3526 usbi_dbg("OVERFLOW!");
3528 r = LIBUSB_COMPLETED;
3531 *size = MIN((size_t)read_size, *size);
3533 // Discard report ID
3534 memcpy(data, buf+1, *size);
3536 memcpy(data, buf, *size);
3543 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3544 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3547 uint8_t *buf = NULL;
3548 DWORD ioctl_code, write_size= (DWORD)*size;
3550 if (tp->hid_buffer != NULL) {
3551 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3554 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3555 usbi_dbg("invalid size (%d)", *size);
3556 return LIBUSB_ERROR_INVALID_PARAM;
3559 switch (report_type) {
3560 case HID_REPORT_TYPE_OUTPUT:
3561 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3563 case HID_REPORT_TYPE_FEATURE:
3564 ioctl_code = IOCTL_HID_SET_FEATURE;
3567 usbi_dbg("unknown HID report type %d", report_type);
3568 return LIBUSB_ERROR_INVALID_PARAM;
3571 usbi_dbg("report ID: 0x%02X", id);
3572 // When report IDs are not used (i.e. when id == 0), we must add
3573 // a null report ID. Otherwise, we just use original data buffer
3577 buf = (uint8_t*) malloc(write_size);
3579 return LIBUSB_ERROR_NO_MEM;
3583 memcpy(buf + 1, data, *size);
3585 // This seems like a waste, but if we don't duplicate the
3586 // data, we'll get issues when freeing hid_buffer
3587 memcpy(buf, data, *size);
3589 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3593 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3594 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3595 buf, write_size, &write_size, overlapped)) {
3596 if (GetLastError() != ERROR_IO_PENDING) {
3597 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3599 return LIBUSB_ERROR_IO;
3601 tp->hid_buffer = buf;
3602 tp->hid_dest = NULL;
3603 return LIBUSB_SUCCESS;
3606 // Transfer completed synchronously
3608 if (write_size == 0) {
3609 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3612 return LIBUSB_COMPLETED;
3615 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3616 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3617 size_t *size, OVERLAPPED* overlapped)
3619 int report_type = (value >> 8) & 0xFF;
3620 int report_id = value & 0xFF;
3622 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3623 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3624 return LIBUSB_ERROR_INVALID_PARAM;
3626 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3627 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3629 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3630 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3632 return LIBUSB_ERROR_INVALID_PARAM;
3639 static int hid_init(int sub_api, struct libusb_context *ctx)
3641 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3642 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3643 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3644 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3645 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3646 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3647 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3648 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3649 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3650 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3651 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3652 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3653 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3654 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3655 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3656 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3658 api_hid_available = true;
3659 return LIBUSB_SUCCESS;
3662 static int hid_exit(int sub_api)
3664 return LIBUSB_SUCCESS;
3667 // NB: open and close must ensure that they only handle interface of
3668 // the right API type, as these functions can be called wholesale from
3669 // composite_open(), with interfaces belonging to different APIs
3670 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3672 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3673 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3674 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3676 HIDD_ATTRIBUTES hid_attributes;
3677 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3678 HIDP_CAPS capabilities;
3679 HIDP_VALUE_CAPS *value_caps;
3681 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3683 // report IDs handling
3685 const char* type[3] = {"input", "output", "feature"};
3686 int nb_ids[2]; // zero and nonzero report IDs
3688 CHECK_HID_AVAILABLE;
3689 if (priv->hid == NULL) {
3690 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3691 return LIBUSB_ERROR_NOT_FOUND;
3694 for (i = 0; i < USB_MAXINTERFACES; i++) {
3695 if ( (priv->usb_interface[i].path != NULL)
3696 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3697 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3698 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3700 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3701 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3702 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3703 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3704 * HidD_GetFeature (if the device supports Feature reports)."
3706 if (hid_handle == INVALID_HANDLE_VALUE) {
3707 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3708 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3709 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3710 if (hid_handle == INVALID_HANDLE_VALUE) {
3711 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3712 switch(GetLastError()) {
3713 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3714 return LIBUSB_ERROR_NO_DEVICE;
3715 case ERROR_ACCESS_DENIED:
3716 return LIBUSB_ERROR_ACCESS;
3718 return LIBUSB_ERROR_IO;
3721 priv->usb_interface[i].restricted_functionality = true;
3723 handle_priv->interface_handle[i].api_handle = hid_handle;
3727 hid_attributes.Size = sizeof(hid_attributes);
3729 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3730 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3734 priv->hid->vid = hid_attributes.VendorID;
3735 priv->hid->pid = hid_attributes.ProductID;
3737 // Set the maximum available input buffer size
3738 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3739 usbi_dbg("set maximum input buffer size to %d", i/2);
3741 // Get the maximum input and output report size
3742 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3743 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3746 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3747 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3751 // Find out if interrupt will need report IDs
3752 size[0] = capabilities.NumberInputValueCaps;
3753 size[1] = capabilities.NumberOutputValueCaps;
3754 size[2] = capabilities.NumberFeatureValueCaps;
3755 for (j=HidP_Input; j<=HidP_Feature; j++) {
3756 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3757 priv->hid->uses_report_ids[j] = false;
3759 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3760 if ( (value_caps != NULL)
3761 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3762 && (size[j] >= 1) ) {
3765 for (i=0; i<(int)size[j]; i++) {
3766 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3767 if (value_caps[i].ReportID != 0) {
3773 if (nb_ids[1] != 0) {
3774 if (nb_ids[0] != 0) {
3775 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3778 priv->hid->uses_report_ids[j] = true;
3781 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3783 safe_free(value_caps);
3787 // Set the report sizes
3788 priv->hid->input_report_size = capabilities.InputReportByteLength;
3789 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3790 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3792 // Fetch string descriptors
3793 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3794 if (priv->hid->string_index[0] != 0) {
3795 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3796 sizeof(priv->hid->string[0]));
3798 priv->hid->string[0][0] = 0;
3800 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3801 if (priv->hid->string_index[1] != 0) {
3802 HidD_GetProductString(hid_handle, priv->hid->string[1],
3803 sizeof(priv->hid->string[1]));
3805 priv->hid->string[1][0] = 0;
3807 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3808 if (priv->hid->string_index[2] != 0) {
3809 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3810 sizeof(priv->hid->string[2]));
3812 priv->hid->string[2][0] = 0;
3816 if (preparsed_data) {
3817 HidD_FreePreparsedData(preparsed_data);
3820 return LIBUSB_SUCCESS;
3823 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3825 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3826 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3830 if (!api_hid_available)
3833 for (i = 0; i < USB_MAXINTERFACES; i++) {
3834 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3835 file_handle = handle_priv->interface_handle[i].api_handle;
3836 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3837 CloseHandle(file_handle);
3843 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3845 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3846 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3848 CHECK_HID_AVAILABLE;
3850 // NB: Disconnection detection is not possible in this function
3851 if (priv->usb_interface[iface].path == NULL) {
3852 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3855 // We use dev_handle as a flag for interface claimed
3856 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3857 return LIBUSB_ERROR_BUSY; // already claimed
3860 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3862 usbi_dbg("claimed interface %d", iface);
3863 handle_priv->active_interface = iface;
3865 return LIBUSB_SUCCESS;
3868 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3870 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3871 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3873 CHECK_HID_AVAILABLE;
3875 if (priv->usb_interface[iface].path == NULL) {
3876 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3879 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3880 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3883 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3885 return LIBUSB_SUCCESS;
3888 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3890 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3892 CHECK_HID_AVAILABLE;
3894 if (altsetting > 255) {
3895 return LIBUSB_ERROR_INVALID_PARAM;
3898 if (altsetting != 0) {
3899 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3900 return LIBUSB_ERROR_NOT_SUPPORTED;
3903 return LIBUSB_SUCCESS;
3906 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3908 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3909 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3910 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3911 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3912 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3913 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3916 int current_interface, config;
3918 int r = LIBUSB_ERROR_INVALID_PARAM;
3920 CHECK_HID_AVAILABLE;
3922 transfer_priv->pollable_fd = INVALID_WINFD;
3923 safe_free(transfer_priv->hid_buffer);
3924 transfer_priv->hid_dest = NULL;
3925 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3927 if (size > MAX_CTRL_BUFFER_LENGTH) {
3928 return LIBUSB_ERROR_INVALID_PARAM;
3931 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3932 if (current_interface < 0) {
3933 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3934 return LIBUSB_ERROR_NOT_FOUND;
3938 usbi_dbg("will use interface %d", current_interface);
3939 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3940 // Always use the handle returned from usbi_create_fd (wfd.handle)
3941 wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
3943 return LIBUSB_ERROR_NOT_FOUND;
3946 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3947 case LIBUSB_REQUEST_TYPE_STANDARD:
3948 switch(setup->request) {
3949 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3950 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3951 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3953 case LIBUSB_REQUEST_GET_CONFIGURATION:
3954 r = windows_get_configuration(transfer->dev_handle, &config);
3955 if (r == LIBUSB_SUCCESS) {
3957 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3958 r = LIBUSB_COMPLETED;
3961 case LIBUSB_REQUEST_SET_CONFIGURATION:
3962 if (setup->value == priv->active_config) {
3963 r = LIBUSB_COMPLETED;
3965 usbi_warn(ctx, "cannot set configuration other than the default one");
3966 r = LIBUSB_ERROR_INVALID_PARAM;
3969 case LIBUSB_REQUEST_GET_INTERFACE:
3971 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3972 r = LIBUSB_COMPLETED;
3974 case LIBUSB_REQUEST_SET_INTERFACE:
3975 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3976 if (r == LIBUSB_SUCCESS) {
3977 r = LIBUSB_COMPLETED;
3981 usbi_warn(ctx, "unsupported HID control request");
3982 r = LIBUSB_ERROR_INVALID_PARAM;
3986 case LIBUSB_REQUEST_TYPE_CLASS:
3987 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3988 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3989 &size, wfd.overlapped);
3992 usbi_warn(ctx, "unsupported HID control request");
3993 r = LIBUSB_ERROR_INVALID_PARAM;
3997 if (r == LIBUSB_COMPLETED) {
3998 // Force request to be completed synchronously. Transferred size has been set by previous call
3999 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4000 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
4001 // set InternalHigh to the number of bytes transferred
4002 wfd.overlapped->InternalHigh = (DWORD)size;
4006 if (r == LIBUSB_SUCCESS) {
4007 // Use priv_transfer to store data needed for async polling
4008 transfer_priv->pollable_fd = wfd;
4009 transfer_priv->interface_number = (uint8_t)current_interface;
4017 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4018 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4019 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4020 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4021 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4022 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4025 bool direction_in, ret;
4026 int current_interface, length;
4028 int r = LIBUSB_SUCCESS;
4030 CHECK_HID_AVAILABLE;
4032 transfer_priv->pollable_fd = INVALID_WINFD;
4033 transfer_priv->hid_dest = NULL;
4034 safe_free(transfer_priv->hid_buffer);
4036 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4037 if (current_interface < 0) {
4038 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4039 return LIBUSB_ERROR_NOT_FOUND;
4042 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
4044 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4045 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
4047 wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
4048 // Always use the handle returned from usbi_create_fd (wfd.handle)
4050 return LIBUSB_ERROR_NO_MEM;
4053 // If report IDs are not in use, an extra prefix byte must be added
4054 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4055 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4056 length = transfer->length+1;
4058 length = transfer->length;
4060 // Add a trailing byte to detect overflows on input
4061 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4062 if (transfer_priv->hid_buffer == NULL) {
4063 return LIBUSB_ERROR_NO_MEM;
4065 transfer_priv->hid_expected_size = length;
4068 transfer_priv->hid_dest = transfer->buffer;
4069 usbi_dbg("reading %d bytes (report ID: 0x00)", length);
4070 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4072 if (!priv->hid->uses_report_ids[1]) {
4073 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4075 // We could actually do without the calloc and memcpy in this case
4076 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4078 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4079 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4082 if (GetLastError() != ERROR_IO_PENDING) {
4083 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4085 safe_free(transfer_priv->hid_buffer);
4086 return LIBUSB_ERROR_IO;
4089 // Only write operations that completed synchronously need to free up
4090 // hid_buffer. For reads, copy_transfer_data() handles that process.
4091 if (!direction_in) {
4092 safe_free(transfer_priv->hid_buffer);
4095 usbi_err(ctx, "program assertion failed - no data was transferred");
4098 if (size > (size_t)length) {
4099 usbi_err(ctx, "OVERFLOW!");
4100 r = LIBUSB_ERROR_OVERFLOW;
4102 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4103 wfd.overlapped->InternalHigh = size;
4106 transfer_priv->pollable_fd = wfd;
4107 transfer_priv->interface_number = (uint8_t)current_interface;
4112 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4114 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4115 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4116 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4118 int current_interface;
4120 CHECK_HID_AVAILABLE;
4122 current_interface = transfer_priv->interface_number;
4123 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4124 CancelIo(hid_handle);
4126 return LIBUSB_SUCCESS;
4129 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4131 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4133 int current_interface;
4135 CHECK_HID_AVAILABLE;
4137 // Flushing the queues on all interfaces is the best we can achieve
4138 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4139 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4140 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4141 HidD_FlushQueue(hid_handle);
4144 return LIBUSB_SUCCESS;
4147 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4149 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4150 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4151 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4153 int current_interface;
4155 CHECK_HID_AVAILABLE;
4157 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4158 if (current_interface < 0) {
4159 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4160 return LIBUSB_ERROR_NOT_FOUND;
4163 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4164 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4166 // No endpoint selection with Microsoft's implementation, so we try to flush the
4167 // whole interface. Should be OK for most case scenarios
4168 if (!HidD_FlushQueue(hid_handle)) {
4169 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4170 // Device was probably disconnected
4171 return LIBUSB_ERROR_NO_DEVICE;
4174 return LIBUSB_SUCCESS;
4177 // This extra function is only needed for HID
4178 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4179 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4180 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4181 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4182 int r = LIBUSB_TRANSFER_COMPLETED;
4183 uint32_t corrected_size = io_size;
4185 if (transfer_priv->hid_buffer != NULL) {
4186 // If we have a valid hid_buffer, it means the transfer was async
4187 if (transfer_priv->hid_dest != NULL) { // Data readout
4188 if (corrected_size > 0) {
4189 // First, check for overflow
4190 if (corrected_size > transfer_priv->hid_expected_size) {
4191 usbi_err(ctx, "OVERFLOW!");
4192 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4193 r = LIBUSB_TRANSFER_OVERFLOW;
4196 if (transfer_priv->hid_buffer[0] == 0) {
4197 // Discard the 1 byte report ID prefix
4199 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4201 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4204 transfer_priv->hid_dest = NULL;
4206 // For write, we just need to free the hid buffer
4207 safe_free(transfer_priv->hid_buffer);
4209 itransfer->transferred += corrected_size;
4215 * Composite API functions
4217 static int composite_init(int sub_api, struct libusb_context *ctx)
4219 return LIBUSB_SUCCESS;
4222 static int composite_exit(int sub_api)
4224 return LIBUSB_SUCCESS;
4227 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4229 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4230 int r = LIBUSB_ERROR_NOT_FOUND;
4232 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4233 bool available[SUB_API_MAX+1] = {0};
4235 for (i=0; i<USB_MAXINTERFACES; i++) {
4236 switch (priv->usb_interface[i].apib->id) {
4237 case USB_API_WINUSBX:
4238 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4239 available[priv->usb_interface[i].sub_api] = true;
4242 available[SUB_API_MAX] = true;
4249 for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4251 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4252 if (r != LIBUSB_SUCCESS) {
4257 if (available[SUB_API_MAX]) { // HID driver
4258 r = hid_open(SUB_API_NOTSET, dev_handle);
4263 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4265 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4267 bool available[SUB_API_MAX];
4269 for (i = 0; i<SUB_API_MAX; i++) {
4270 available[i] = false;
4273 for (i=0; i<USB_MAXINTERFACES; i++) {
4274 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4275 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4276 available[priv->usb_interface[i].sub_api] = true;
4280 for (i=0; i<SUB_API_MAX; i++) {
4282 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4287 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4289 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4290 return priv->usb_interface[iface].apib->
4291 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4294 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4296 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4297 return priv->usb_interface[iface].apib->
4298 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4301 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4303 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4304 return priv->usb_interface[iface].apib->
4305 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4308 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4310 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4311 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4312 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4315 // Interface shouldn't matter for control, but it does in practice, with Windows'
4316 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4317 for (pass = 0; pass < 2; pass++) {
4318 for (i=0; i<USB_MAXINTERFACES; i++) {
4319 if (priv->usb_interface[i].path != NULL) {
4320 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4321 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4324 usbi_dbg("using interface %d", i);
4325 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4330 usbi_err(ctx, "no libusb supported interfaces to complete request");
4331 return LIBUSB_ERROR_NOT_FOUND;
4334 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4335 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4336 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4337 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4338 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4339 int current_interface;
4341 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4342 if (current_interface < 0) {
4343 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4344 return LIBUSB_ERROR_NOT_FOUND;
4347 return priv->usb_interface[current_interface].apib->
4348 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4350 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4351 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4352 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4353 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4354 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4355 int current_interface;
4357 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4358 if (current_interface < 0) {
4359 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4360 return LIBUSB_ERROR_NOT_FOUND;
4363 return priv->usb_interface[current_interface].apib->
4364 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4366 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4368 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4369 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4370 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4371 int current_interface;
4373 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4374 if (current_interface < 0) {
4375 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4376 return LIBUSB_ERROR_NOT_FOUND;
4379 return priv->usb_interface[current_interface].apib->
4380 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4382 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4384 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4385 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4386 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4388 return priv->usb_interface[transfer_priv->interface_number].apib->
4389 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4391 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4393 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4394 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4395 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4397 return priv->usb_interface[transfer_priv->interface_number].apib->
4398 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4400 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4402 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4405 bool available[SUB_API_MAX];
4406 for (i = 0; i<SUB_API_MAX; i++) {
4407 available[i] = false;
4409 for (i=0; i<USB_MAXINTERFACES; i++) {
4410 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4411 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4412 available[priv->usb_interface[i].sub_api] = true;
4415 for (i=0; i<SUB_API_MAX; i++) {
4417 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4418 if (r != LIBUSB_SUCCESS) {
4423 return LIBUSB_SUCCESS;
4426 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4428 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4429 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4430 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4432 return priv->usb_interface[transfer_priv->interface_number].apib->
4433 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);