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 indiscriminately 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 consistency 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 // coverity[tainted_data_argument]
1032 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
1033 &cd_buf_short, size, &ret_size, NULL)) {
1034 usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
1035 LOOP_BREAK(LIBUSB_ERROR_IO);
1038 if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
1039 usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
1040 LOOP_BREAK(LIBUSB_ERROR_IO);
1043 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
1044 if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
1045 usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
1046 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1048 memset(cd_buf_actual, 0, size);
1051 cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
1052 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1053 cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1054 cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1055 cd_buf_actual->SetupPacket.wIndex = i;
1056 cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1058 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1059 cd_buf_actual, size, &ret_size, NULL)) {
1060 usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1061 LOOP_BREAK(LIBUSB_ERROR_IO);
1064 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1066 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1067 usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1068 LOOP_BREAK(LIBUSB_ERROR_IO);
1071 if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1072 usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1073 LOOP_BREAK(LIBUSB_ERROR_IO);
1076 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1077 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1079 // Cache the descriptor
1080 priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1081 if (priv->config_descriptor[i] == NULL)
1082 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1083 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1085 return LIBUSB_SUCCESS;
1089 * Populate a libusb device structure
1091 static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1092 uint8_t port_number, char* device_id, DWORD devinst)
1096 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1097 struct windows_device_priv *priv, *parent_priv;
1098 struct libusb_context *ctx;
1099 struct libusb_device* tmp_dev;
1102 if ((dev == NULL) || (parent_dev == NULL)) {
1103 return LIBUSB_ERROR_NOT_FOUND;
1105 ctx = DEVICE_CTX(dev);
1106 priv = _device_priv(dev);
1107 parent_priv = _device_priv(parent_dev);
1108 if (parent_priv->apib->id != USB_API_HUB) {
1109 usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1110 return LIBUSB_ERROR_NOT_FOUND;
1113 // It is possible for the parent hub not to have been initialized yet
1114 // If that's the case, lookup the ancestors to set the bus number
1115 if (parent_dev->bus_number == 0) {
1117 tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
1118 if (tmp_dev == NULL) break;
1119 if (tmp_dev->bus_number != 0) {
1120 usbi_dbg("got bus number from ancestor #%d", i);
1121 parent_dev->bus_number = tmp_dev->bus_number;
1122 libusb_unref_device(tmp_dev);
1125 libusb_unref_device(tmp_dev);
1128 if (parent_dev->bus_number == 0) {
1129 usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1130 return LIBUSB_ERROR_NOT_FOUND;
1132 dev->bus_number = parent_dev->bus_number;
1133 priv->port = port_number;
1134 dev->port_number = port_number;
1135 priv->depth = parent_priv->depth + 1;
1136 priv->parent_dev = parent_dev;
1137 dev->parent_dev = parent_dev;
1139 // If the device address is already set, we can stop here
1140 if (dev->device_address != 0) {
1141 return LIBUSB_SUCCESS;
1143 memset(&conn_info, 0, sizeof(conn_info));
1144 if (priv->depth != 0) { // Not a HCD hub
1145 handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1146 FILE_FLAG_OVERLAPPED, NULL);
1147 if (handle == INVALID_HANDLE_VALUE) {
1148 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1149 return LIBUSB_ERROR_ACCESS;
1151 size = sizeof(conn_info);
1152 conn_info.ConnectionIndex = (ULONG)port_number;
1153 // coverity[tainted_data_argument]
1154 if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1155 &conn_info, size, &size, NULL)) {
1156 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1157 device_id, windows_error_str(0));
1158 safe_closehandle(handle);
1159 return LIBUSB_ERROR_NO_DEVICE;
1161 if (conn_info.ConnectionStatus == NoDeviceConnected) {
1162 usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1163 safe_closehandle(handle);
1164 return LIBUSB_ERROR_NO_DEVICE;
1166 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1167 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1168 priv->active_config = conn_info.CurrentConfigurationValue;
1169 usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1170 // If we can't read the config descriptors, just set the number of confs to zero
1171 if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1172 dev->num_configurations = 0;
1173 priv->dev_descriptor.bNumConfigurations = 0;
1175 safe_closehandle(handle);
1177 if (conn_info.DeviceAddress > UINT8_MAX) {
1178 usbi_err(ctx, "program assertion failed: device address overflow");
1180 dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1181 if (dev->device_address == 1) {
1182 usbi_err(ctx, "program assertion failed: device address collision with root hub");
1184 switch (conn_info.Speed) {
1185 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1186 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1187 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1188 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1190 usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1194 dev->device_address = 1; // root hubs are set to use device number 1
1195 force_hcd_device_descriptor(dev);
1198 usbi_sanitize_device(dev);
1200 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1201 dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1203 return LIBUSB_SUCCESS;
1206 // Returns the api type, or 0 if not found/unsupported
1207 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1208 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1210 // Precedence for filter drivers vs driver is in the order of this array
1211 struct driver_lookup lookup[3] = {
1212 {"\0\0", SPDRP_SERVICE, "driver"},
1213 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1214 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1216 DWORD size, reg_type;
1220 *api = USB_API_UNSUPPORTED;
1221 *sub_api = SUB_API_NOTSET;
1222 // Check the service & filter names to know the API we should use
1223 for (k=0; k<3; k++) {
1224 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1225 ®_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1226 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1227 if (lookup[k].reg_prop == SPDRP_SERVICE) {
1228 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1229 lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1231 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1232 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1233 // (currently ';'), so even if an unsuported one does, it's not an issue
1234 for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1235 if (lookup[k].list[l] == 0) {
1236 lookup[k].list[l] = LIST_SEPARATOR;
1239 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1241 if (GetLastError() != ERROR_INVALID_DATA) {
1242 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1244 lookup[k].list[0] = 0;
1248 for (i=1; i<USB_API_MAX; i++) {
1249 for (k=0; k<3; k++) {
1250 j = get_sub_api(lookup[k].list, i);
1252 usbi_dbg("matched %s name against %s",
1253 lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1262 static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1263 char* dev_interface_path, char* device_id, int api, int sub_api)
1266 struct windows_device_priv *priv = _device_priv(dev);
1267 int interface_number;
1269 if (priv->apib->id != USB_API_COMPOSITE) {
1270 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1271 return LIBUSB_ERROR_NO_DEVICE;
1274 // Because MI_## are not necessarily in sequential order (some composite
1275 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1276 // interface number from the path's MI value
1277 interface_number = 0;
1278 for (i=0; device_id[i] != 0; ) {
1279 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1280 && (device_id[i++] == '_') ) {
1281 interface_number = (device_id[i++] - '0')*10;
1282 interface_number += device_id[i] - '0';
1287 if (device_id[i] == 0) {
1288 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1289 device_id, interface_number);
1292 if (priv->usb_interface[interface_number].path != NULL) {
1293 if (api == USB_API_HID) {
1294 // HID devices can have multiple collections (COL##) for each MI_## interface
1295 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1296 interface_number, device_id);
1297 return LIBUSB_ERROR_ACCESS;
1299 // In other cases, just use the latest data
1300 safe_free(priv->usb_interface[interface_number].path);
1303 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1304 priv->usb_interface[interface_number].path = dev_interface_path;
1305 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1306 priv->usb_interface[interface_number].sub_api = sub_api;
1307 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1308 priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
1309 if (priv->hid == NULL)
1310 return LIBUSB_ERROR_NO_MEM;
1313 return LIBUSB_SUCCESS;
1316 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1317 char* dev_interface_path)
1320 struct windows_device_priv *priv = _device_priv(dev);
1322 if (priv->hid == NULL) {
1323 usbi_err(ctx, "program assertion failed: parent is not HID");
1324 return LIBUSB_ERROR_NO_DEVICE;
1326 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1327 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1328 return LIBUSB_ERROR_NO_DEVICE;
1330 for (i=0; i<priv->hid->nb_interfaces; i++) {
1331 if (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
1332 usbi_dbg("interface[%d] already set to %s", i, dev_interface_path);
1333 return LIBUSB_SUCCESS;
1337 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1338 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1339 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1340 priv->hid->nb_interfaces++;
1341 return LIBUSB_SUCCESS;
1345 * get_device_list: libusb backend device enumeration function
1347 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1349 struct discovered_devs *discdevs;
1350 HDEVINFO dev_info = { 0 };
1351 const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1352 SP_DEVINFO_DATA dev_info_data = { 0 };
1353 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1355 #define MAX_ENUM_GUIDS 64
1356 const GUID* guid[MAX_ENUM_GUIDS];
1362 int r = LIBUSB_SUCCESS;
1364 size_t class_index = 0;
1365 unsigned int nb_guids, pass, i, j, ancestor;
1366 char path[MAX_PATH_LENGTH];
1367 char strbuf[MAX_PATH_LENGTH];
1368 struct libusb_device *dev, *parent_dev;
1369 struct windows_device_priv *priv, *parent_priv;
1370 char* dev_interface_path = NULL;
1371 char* dev_id_path = NULL;
1372 unsigned long session_id;
1373 DWORD size, reg_type, port_nr, install_state;
1375 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1378 // Keep a list of newly allocated devs to unref
1379 libusb_device** unref_list;
1380 unsigned int unref_size = 64;
1381 unsigned int unref_cur = 0;
1383 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1384 // PASS 2 : (re)enumerate HUBS
1385 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1386 // and list additional USB device interface GUIDs to explore
1387 // PASS 4 : (re)enumerate master USB devices that have a device interface
1388 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1389 // set the device interfaces.
1391 // Init the GUID table
1392 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1393 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1394 guid[GEN_PASS] = NULL;
1395 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1396 HidD_GetHidGuid(&hid_guid);
1397 guid[HID_PASS] = &hid_guid;
1398 nb_guids = HID_PASS+1;
1400 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1401 if (unref_list == NULL) {
1402 return LIBUSB_ERROR_NO_MEM;
1405 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1406 //#define ENUM_DEBUG
1408 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1409 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1410 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1412 for (i = 0; ; i++) {
1413 // safe loop: free up any (unprotected) dynamic resource
1414 // NB: this is always executed before breaking the loop
1415 safe_free(dev_interface_details);
1416 safe_free(dev_interface_path);
1417 safe_free(dev_id_path);
1418 priv = parent_priv = NULL;
1419 dev = parent_dev = NULL;
1421 // Safe loop: end of loop conditions
1422 if (r != LIBUSB_SUCCESS) {
1425 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1426 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1429 if (pass != GEN_PASS) {
1430 // Except for GEN, all passes deal with device interfaces
1431 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1432 if (dev_interface_details == NULL) {
1435 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1436 if (dev_interface_path == NULL) {
1437 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1442 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1443 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1444 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1445 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1446 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1450 if (class_index >= ARRAYSIZE(usb_class))
1454 // Read the Device ID path. This is what we'll use as UID
1455 // Note that if the device is plugged in a different port or hub, the Device ID changes
1456 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1457 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1458 dev_info_data.DevInst);
1461 dev_id_path = sanitize_path(path);
1462 if (dev_id_path == NULL) {
1463 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1464 dev_info_data.DevInst);
1468 usbi_dbg("PRO: %s", dev_id_path);
1471 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1473 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1474 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1475 ®_type, (BYTE*)&port_nr, 4, &size))
1477 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1478 dev_id_path, windows_error_str(0));
1483 // Set API to use or get additional data from generic pass
1484 api = USB_API_UNSUPPORTED;
1485 sub_api = SUB_API_NOTSET;
1490 // We use the GEN pass to detect driverless devices...
1491 size = sizeof(strbuf);
1492 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1493 ®_type, (BYTE*)strbuf, size, &size)) {
1494 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1495 usbi_info(ctx, "libusb will not be able to access it.");
1497 // ...and to add the additional device interface GUIDs
1498 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1499 if (key != INVALID_HANDLE_VALUE) {
1500 size = sizeof(guid_string_w);
1501 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1502 (BYTE*)guid_string_w, &size);
1504 if (s == ERROR_SUCCESS) {
1505 if (nb_guids >= MAX_ENUM_GUIDS) {
1506 // If this assert is ever reported, grow a GUID table dynamically
1507 usbi_err(ctx, "program assertion failed: too many GUIDs");
1508 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1510 if_guid = (GUID*) calloc(1, sizeof(GUID));
1511 pCLSIDFromString(guid_string_w, if_guid);
1512 guid[nb_guids++] = if_guid;
1513 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1521 // Get the API type (after checking that the driver installation is OK)
1522 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1523 ®_type, (BYTE*)&install_state, 4, &size))
1525 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1526 dev_id_path, windows_error_str(0));
1527 } else if (install_state != 0) {
1528 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1529 dev_id_path, install_state);
1532 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1536 // Find parent device (for the passes that need it)
1543 // Go through the ancestors until we see a face we recognize
1545 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1546 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1547 if (session_id == 0) {
1550 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1552 if (parent_dev == NULL) {
1553 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1556 parent_priv = _device_priv(parent_dev);
1557 // virtual USB devices are also listed during GEN - don't process these yet
1558 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1559 libusb_unref_device(parent_dev);
1565 // Create new or match existing device, using the (hashed) device_id as session id
1566 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1567 // These are the passes that create "new" devices
1568 session_id = htab_hash(dev_id_path);
1569 dev = usbi_get_device_by_session_id(ctx, session_id);
1571 if (pass == DEV_PASS) {
1572 // This can occur if the OS only reports a newly plugged device after we started enum
1573 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1574 " - ignoring", dev_id_path);
1577 usbi_dbg("allocating new device for session [%X]", session_id);
1578 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1579 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1581 windows_device_priv_init(dev);
1583 usbi_dbg("found existing device for session [%X] (%d.%d)",
1584 session_id, dev->bus_number, dev->device_address);
1586 // Keep track of devices that need unref
1587 unref_list[unref_cur++] = dev;
1588 if (unref_cur >= unref_size) {
1590 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1591 if (unref_list == NULL) {
1592 usbi_err(ctx, "could not realloc list for unref - aborting.");
1593 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1596 priv = _device_priv(dev);
1602 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1603 dev->device_address = 0;
1604 dev->num_configurations = 0;
1605 priv->apib = &usb_api_backend[USB_API_HUB];
1606 priv->sub_api = SUB_API_NOTSET;
1607 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1608 priv->path = dev_interface_path; dev_interface_path = NULL;
1612 // If the device has already been setup, don't do it again
1613 if (priv->path != NULL)
1615 // Take care of API initialization
1616 priv->path = dev_interface_path; dev_interface_path = NULL;
1617 priv->apib = &usb_api_backend[api];
1618 priv->sub_api = sub_api;
1620 case USB_API_COMPOSITE:
1624 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1625 if (priv->hid == NULL) {
1626 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1628 priv->hid->nb_interfaces = 0;
1631 // For other devices, the first interface is the same as the device
1632 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1633 if (priv->usb_interface[0].path != NULL) {
1634 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1636 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1638 // The following is needed if we want API calls to work for both simple
1639 // and composite devices.
1640 for(j=0; j<USB_MAXINTERFACES; j++) {
1641 priv->usb_interface[j].apib = &usb_api_backend[api];
1647 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1648 if (r == LIBUSB_SUCCESS) {
1649 // Append device to the list of discovered devices
1650 discdevs = discovered_devs_append(*_discdevs, dev);
1652 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1654 *_discdevs = discdevs;
1655 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1656 // This can occur if the device was disconnected but Windows hasn't
1657 // refreshed its enumeration yet - in that case, we ignore the device
1661 default: // HID_PASS and later
1662 if (parent_priv->apib->id == USB_API_HID) {
1663 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1664 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1665 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1666 dev_interface_path = NULL;
1667 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1668 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1669 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1670 case LIBUSB_SUCCESS:
1671 dev_interface_path = NULL;
1673 case LIBUSB_ERROR_ACCESS:
1674 // interface has already been set => make sure dev_interface_path is freed then
1681 libusb_unref_device(parent_dev);
1687 // Free any additional GUIDs
1688 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1689 safe_free(guid[pass]);
1692 // Unref newly allocated devs
1693 if (unref_list != NULL) {
1694 for (i=0; i<unref_cur; i++) {
1695 safe_unref_device(unref_list[i]);
1704 * exit: libusb backend deinitialization function
1706 static void windows_exit(void)
1710 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1712 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1713 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1714 if (semaphore == NULL) {
1718 // A successful wait brings our semaphore count to 0 (unsignaled)
1719 // => any concurent wait stalls until the semaphore release
1720 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1721 CloseHandle(semaphore);
1725 // Only works if exits and inits are balanced exactly
1726 if (--concurrent_usage < 0) { // Last exit
1727 for (i=0; i<USB_API_MAX; i++) {
1728 usb_api_backend[i].exit(SUB_API_NOTSET);
1733 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1734 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1735 usbi_dbg("could not wait for timer thread to quit");
1736 TerminateThread(timer_thread, 1);
1738 CloseHandle(timer_thread);
1739 timer_thread = NULL;
1741 for (i = 0; i < 2; i++) {
1742 if (timer_request[i]) {
1743 CloseHandle(timer_request[i]);
1744 timer_request[i] = NULL;
1747 if (timer_response) {
1748 CloseHandle(timer_response);
1749 timer_response = NULL;
1752 CloseHandle(timer_mutex);
1758 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1759 CloseHandle(semaphore);
1762 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1764 struct windows_device_priv *priv = _device_priv(dev);
1766 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1769 return LIBUSB_SUCCESS;
1772 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1774 struct windows_device_priv *priv = _device_priv(dev);
1775 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1778 // config index is zero based
1779 if (config_index >= dev->num_configurations)
1780 return LIBUSB_ERROR_INVALID_PARAM;
1782 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1783 return LIBUSB_ERROR_NOT_FOUND;
1785 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1787 size = min(config_header->wTotalLength, len);
1788 memcpy(buffer, priv->config_descriptor[config_index], size);
1795 * return the cached copy of the active config descriptor
1797 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1799 struct windows_device_priv *priv = _device_priv(dev);
1801 if (priv->active_config == 0)
1802 return LIBUSB_ERROR_NOT_FOUND;
1804 // config index is zero based
1805 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1808 static int windows_open(struct libusb_device_handle *dev_handle)
1810 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1811 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1813 if (priv->apib == NULL) {
1814 usbi_err(ctx, "program assertion failed - device is not initialized");
1815 return LIBUSB_ERROR_NO_DEVICE;
1818 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1821 static void windows_close(struct libusb_device_handle *dev_handle)
1823 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1825 priv->apib->close(SUB_API_NOTSET, dev_handle);
1828 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1830 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1832 if (priv->active_config == 0) {
1834 return LIBUSB_ERROR_NOT_FOUND;
1837 *config = priv->active_config;
1838 return LIBUSB_SUCCESS;
1842 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1843 * does not currently expose a service that allows higher-level drivers to set
1844 * the configuration."
1846 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1848 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1849 int r = LIBUSB_SUCCESS;
1851 if (config >= USB_MAXCONFIG)
1852 return LIBUSB_ERROR_INVALID_PARAM;
1854 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1855 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1856 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1859 if (r == LIBUSB_SUCCESS) {
1860 priv->active_config = (uint8_t)config;
1865 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1867 int r = LIBUSB_SUCCESS;
1868 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1870 if (iface >= USB_MAXINTERFACES)
1871 return LIBUSB_ERROR_INVALID_PARAM;
1873 safe_free(priv->usb_interface[iface].endpoint);
1874 priv->usb_interface[iface].nb_endpoints= 0;
1876 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1878 if (r == LIBUSB_SUCCESS) {
1879 r = windows_assign_endpoints(dev_handle, iface, 0);
1885 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1887 int r = LIBUSB_SUCCESS;
1888 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1890 safe_free(priv->usb_interface[iface].endpoint);
1891 priv->usb_interface[iface].nb_endpoints= 0;
1893 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1895 if (r == LIBUSB_SUCCESS) {
1896 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1902 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1904 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1906 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1909 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1911 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1912 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1915 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1917 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1918 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1921 // The 3 functions below are unlikely to ever get supported on Windows
1922 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1924 return LIBUSB_ERROR_NOT_SUPPORTED;
1927 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1929 return LIBUSB_ERROR_NOT_SUPPORTED;
1932 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1934 return LIBUSB_ERROR_NOT_SUPPORTED;
1937 static void windows_destroy_device(struct libusb_device *dev)
1939 windows_device_priv_release(dev);
1942 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1944 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1946 usbi_free_fd(&transfer_priv->pollable_fd);
1947 safe_free(transfer_priv->hid_buffer);
1948 // When auto claim is in use, attempt to release the auto-claimed interface
1949 auto_release(itransfer);
1952 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1954 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1955 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1956 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1957 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1960 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1961 if (r != LIBUSB_SUCCESS) {
1965 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1966 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1968 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1969 return LIBUSB_SUCCESS;
1972 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1974 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1975 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1976 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1977 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1980 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1981 if (r != LIBUSB_SUCCESS) {
1985 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1986 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1988 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1989 return LIBUSB_SUCCESS;
1992 static int submit_control_transfer(struct usbi_transfer *itransfer)
1994 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1995 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1996 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1997 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2000 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
2001 if (r != LIBUSB_SUCCESS) {
2005 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
2007 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
2008 return LIBUSB_SUCCESS;
2012 static int windows_submit_transfer(struct usbi_transfer *itransfer)
2014 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2016 switch (transfer->type) {
2017 case LIBUSB_TRANSFER_TYPE_CONTROL:
2018 return submit_control_transfer(itransfer);
2019 case LIBUSB_TRANSFER_TYPE_BULK:
2020 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2021 if (IS_XFEROUT(transfer) &&
2022 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
2023 return LIBUSB_ERROR_NOT_SUPPORTED;
2024 return submit_bulk_transfer(itransfer);
2025 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2026 return submit_iso_transfer(itransfer);
2027 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2028 return LIBUSB_ERROR_NOT_SUPPORTED;
2030 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2031 return LIBUSB_ERROR_INVALID_PARAM;
2035 static int windows_abort_control(struct usbi_transfer *itransfer)
2037 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2038 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2040 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2043 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2045 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2046 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2048 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2051 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2053 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2055 switch (transfer->type) {
2056 case LIBUSB_TRANSFER_TYPE_CONTROL:
2057 return windows_abort_control(itransfer);
2058 case LIBUSB_TRANSFER_TYPE_BULK:
2059 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2060 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2061 return windows_abort_transfers(itransfer);
2062 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2063 return LIBUSB_ERROR_NOT_SUPPORTED;
2065 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2066 return LIBUSB_ERROR_INVALID_PARAM;
2070 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2072 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2073 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2074 int status, istatus;
2076 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
2080 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2082 case ERROR_GEN_FAILURE:
2083 usbi_dbg("detected endpoint stall");
2084 status = LIBUSB_TRANSFER_STALL;
2086 case ERROR_SEM_TIMEOUT:
2087 usbi_dbg("detected semaphore timeout");
2088 status = LIBUSB_TRANSFER_TIMED_OUT;
2090 case ERROR_OPERATION_ABORTED:
2091 istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2092 if (istatus != LIBUSB_TRANSFER_COMPLETED) {
2093 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
2095 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2096 usbi_dbg("detected timeout");
2097 status = LIBUSB_TRANSFER_TIMED_OUT;
2099 usbi_dbg("detected operation aborted");
2100 status = LIBUSB_TRANSFER_CANCELLED;
2104 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(io_result));
2105 status = LIBUSB_TRANSFER_ERROR;
2108 windows_clear_transfer_priv(itransfer); // Cancel polling
2109 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2112 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2114 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2116 switch (transfer->type) {
2117 case LIBUSB_TRANSFER_TYPE_CONTROL:
2118 case LIBUSB_TRANSFER_TYPE_BULK:
2119 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2120 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2121 windows_transfer_callback (itransfer, io_result, io_size);
2123 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2124 usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
2127 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2131 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2133 struct windows_transfer_priv* transfer_priv = NULL;
2134 POLL_NFDS_TYPE i = 0;
2136 struct usbi_transfer *transfer;
2137 DWORD io_size, io_result;
2139 usbi_mutex_lock(&ctx->open_devs_lock);
2140 for (i = 0; i < nfds && num_ready > 0; i++) {
2142 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2144 if (!fds[i].revents) {
2150 // Because a Windows OVERLAPPED is used for poll emulation,
2151 // a pollable fd is created and stored with each transfer
2152 usbi_mutex_lock(&ctx->flying_transfers_lock);
2153 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2154 transfer_priv = usbi_transfer_get_os_priv(transfer);
2155 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2160 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2163 // Handle async requests that completed synchronously first
2164 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2165 io_result = NO_ERROR;
2166 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2167 // Regular async overlapped
2168 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2169 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2170 io_result = NO_ERROR;
2172 io_result = GetLastError();
2174 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2175 // let handle_callback free the event using the transfer wfd
2176 // If you don't use the transfer wfd, you run a risk of trying to free a
2177 // newly allocated wfd that took the place of the one from the transfer.
2178 windows_handle_callback(transfer, io_result, io_size);
2180 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2181 return LIBUSB_ERROR_NOT_FOUND;
2185 usbi_mutex_unlock(&ctx->open_devs_lock);
2186 return LIBUSB_SUCCESS;
2190 * Monotonic and real time functions
2192 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2194 LARGE_INTEGER hires_counter, li_frequency;
2198 // Init - find out if we have access to a monotonic (hires) timer
2199 if (!QueryPerformanceFrequency(&li_frequency)) {
2200 usbi_dbg("no hires timer available on this platform");
2201 hires_frequency = 0;
2202 hires_ticks_to_ps = UINT64_C(0);
2204 hires_frequency = li_frequency.QuadPart;
2205 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2206 // to picoseconds to compute the tv_nsecs part in clock_gettime
2207 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2208 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2211 // Signal windows_init() that we're ready to service requests
2212 if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
2213 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2216 // Main loop - wait for requests
2218 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2219 if ( (timer_index != 0) && (timer_index != 1) ) {
2220 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2223 if (request_count[timer_index] == 0) {
2224 // Request already handled
2225 ResetEvent(timer_request[timer_index]);
2226 // There's still a possiblity that a thread sends a request between the
2227 // time we test request_count[] == 0 and we reset the event, in which case
2228 // the request would be ignored. The simple solution to that is to test
2229 // request_count again and process requests if non zero.
2230 if (request_count[timer_index] == 0)
2233 switch (timer_index) {
2235 WaitForSingleObject(timer_mutex, INFINITE);
2236 // Requests to this thread are for hires always
2237 if ((QueryPerformanceCounter(&hires_counter) != 0) && (hires_frequency != 0)) {
2238 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2239 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2241 // Fallback to real-time if we can't get monotonic value
2242 // Note that real-time clock does not wait on the mutex or this thread.
2243 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2245 ReleaseMutex(timer_mutex);
2247 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2249 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2250 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2253 case 1: // time to quit
2254 usbi_dbg("timer thread quitting");
2260 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2263 ULARGE_INTEGER rtime;
2266 case USBI_CLOCK_MONOTONIC:
2267 if (hires_frequency != 0) {
2269 InterlockedIncrement((LONG*)&request_count[0]);
2270 SetEvent(timer_request[0]);
2271 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2274 WaitForSingleObject(timer_mutex, INFINITE);
2276 ReleaseMutex(timer_mutex);
2277 return LIBUSB_SUCCESS;
2279 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2280 break; // Retry until successful
2282 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2283 return LIBUSB_ERROR_OTHER;
2287 // Fall through and return real-time if monotonic was not detected @ timer init
2288 case USBI_CLOCK_REALTIME:
2289 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2290 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2291 // Note however that our resolution is bounded by the Windows system time
2292 // functions and is at best of the order of 1 ms (or, usually, worse)
2293 GetSystemTimeAsFileTime(&filetime);
2294 rtime.LowPart = filetime.dwLowDateTime;
2295 rtime.HighPart = filetime.dwHighDateTime;
2296 rtime.QuadPart -= epoch_time;
2297 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2298 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2299 return LIBUSB_SUCCESS;
2301 return LIBUSB_ERROR_INVALID_PARAM;
2306 // NB: MSVC6 does not support named initializers.
2307 const struct usbi_os_backend windows_backend = {
2309 USBI_CAP_HAS_HID_ACCESS,
2313 windows_get_device_list,
2314 NULL, /* hotplug_poll */
2318 windows_get_device_descriptor,
2319 windows_get_active_config_descriptor,
2320 windows_get_config_descriptor,
2321 NULL, /* get_config_descriptor_by_value() */
2323 windows_get_configuration,
2324 windows_set_configuration,
2325 windows_claim_interface,
2326 windows_release_interface,
2328 windows_set_interface_altsetting,
2330 windows_reset_device,
2332 NULL, /* alloc_streams */
2333 NULL, /* free_streams */
2335 windows_kernel_driver_active,
2336 windows_detach_kernel_driver,
2337 windows_attach_kernel_driver,
2339 windows_destroy_device,
2341 windows_submit_transfer,
2342 windows_cancel_transfer,
2343 windows_clear_transfer_priv,
2345 windows_handle_events,
2347 windows_clock_gettime,
2348 #if defined(USBI_TIMERFD_AVAILABLE)
2351 sizeof(struct windows_device_priv),
2352 sizeof(struct windows_device_handle_priv),
2353 sizeof(struct windows_transfer_priv),
2361 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2362 return LIBUSB_SUCCESS;
2364 static int unsupported_exit(int sub_api) {
2365 return LIBUSB_SUCCESS;
2367 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2368 PRINT_UNSUPPORTED_API(open);
2370 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2371 usbi_dbg("unsupported API call for 'close'");
2373 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2374 PRINT_UNSUPPORTED_API(configure_endpoints);
2376 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2377 PRINT_UNSUPPORTED_API(claim_interface);
2379 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2380 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2382 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2383 PRINT_UNSUPPORTED_API(release_interface);
2385 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2386 PRINT_UNSUPPORTED_API(clear_halt);
2388 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2389 PRINT_UNSUPPORTED_API(reset_device);
2391 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2392 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2394 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2395 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2397 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2398 PRINT_UNSUPPORTED_API(submit_control_transfer);
2400 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2401 PRINT_UNSUPPORTED_API(abort_control);
2403 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2404 PRINT_UNSUPPORTED_API(abort_transfers);
2406 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2407 PRINT_UNSUPPORTED_API(copy_transfer_data);
2409 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2410 return LIBUSB_SUCCESS;
2412 // These names must be uppercase
2413 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "USB3HUB", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB", "VUSB3HUB", "AMDHUB30"};
2414 const char* composite_driver_names[] = {"USBCCGP"};
2415 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2416 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2417 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2419 USB_API_UNSUPPORTED,
2427 unsupported_configure_endpoints,
2428 unsupported_claim_interface,
2429 unsupported_set_interface_altsetting,
2430 unsupported_release_interface,
2431 unsupported_clear_halt,
2432 unsupported_reset_device,
2433 unsupported_submit_bulk_transfer,
2434 unsupported_submit_iso_transfer,
2435 unsupported_submit_control_transfer,
2436 unsupported_abort_control,
2437 unsupported_abort_transfers,
2438 unsupported_copy_transfer_data,
2443 ARRAYSIZE(hub_driver_names),
2448 unsupported_configure_endpoints,
2449 unsupported_claim_interface,
2450 unsupported_set_interface_altsetting,
2451 unsupported_release_interface,
2452 unsupported_clear_halt,
2453 unsupported_reset_device,
2454 unsupported_submit_bulk_transfer,
2455 unsupported_submit_iso_transfer,
2456 unsupported_submit_control_transfer,
2457 unsupported_abort_control,
2458 unsupported_abort_transfers,
2459 unsupported_copy_transfer_data,
2463 composite_driver_names,
2464 ARRAYSIZE(composite_driver_names),
2469 common_configure_endpoints,
2470 composite_claim_interface,
2471 composite_set_interface_altsetting,
2472 composite_release_interface,
2473 composite_clear_halt,
2474 composite_reset_device,
2475 composite_submit_bulk_transfer,
2476 composite_submit_iso_transfer,
2477 composite_submit_control_transfer,
2478 composite_abort_control,
2479 composite_abort_transfers,
2480 composite_copy_transfer_data,
2484 winusbx_driver_names,
2485 ARRAYSIZE(winusbx_driver_names),
2490 winusbx_configure_endpoints,
2491 winusbx_claim_interface,
2492 winusbx_set_interface_altsetting,
2493 winusbx_release_interface,
2495 winusbx_reset_device,
2496 winusbx_submit_bulk_transfer,
2497 unsupported_submit_iso_transfer,
2498 winusbx_submit_control_transfer,
2499 winusbx_abort_control,
2500 winusbx_abort_transfers,
2501 winusbx_copy_transfer_data,
2506 ARRAYSIZE(hid_driver_names),
2511 common_configure_endpoints,
2512 hid_claim_interface,
2513 hid_set_interface_altsetting,
2514 hid_release_interface,
2517 hid_submit_bulk_transfer,
2518 unsupported_submit_iso_transfer,
2519 hid_submit_control_transfer,
2520 hid_abort_transfers,
2521 hid_abort_transfers,
2522 hid_copy_transfer_data,
2528 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2530 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2531 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2533 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2536 bool native_winusb = false;
2538 KLIB_VERSION LibK_Version;
2539 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2540 LibK_GetVersion_t pLibK_GetVersion = NULL;
2542 h = GetModuleHandleA("libusbK");
2544 h = LoadLibraryA("libusbK");
2547 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2548 h = GetModuleHandleA("WinUSB");
2550 h = LoadLibraryA("WinUSB");
2552 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2553 "you will not be able to access devices outside of enumeration");
2554 return LIBUSB_ERROR_NOT_FOUND;
2557 usbi_dbg("using libusbK DLL for universal access");
2558 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2559 if (pLibK_GetVersion != NULL) {
2560 pLibK_GetVersion(&LibK_Version);
2561 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2562 LibK_Version.Micro, LibK_Version.Nano);
2564 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2565 if (pLibK_GetProcAddress == NULL) {
2566 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2567 return LIBUSB_ERROR_NOT_FOUND;
2570 native_winusb = (pLibK_GetProcAddress == NULL);
2571 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2572 WinUSBX_Set(AbortPipe);
2573 WinUSBX_Set(ControlTransfer);
2574 WinUSBX_Set(FlushPipe);
2576 WinUSBX_Set(GetAssociatedInterface);
2577 WinUSBX_Set(GetCurrentAlternateSetting);
2578 WinUSBX_Set(GetDescriptor);
2579 WinUSBX_Set(GetOverlappedResult);
2580 WinUSBX_Set(GetPipePolicy);
2581 WinUSBX_Set(GetPowerPolicy);
2582 WinUSBX_Set(Initialize);
2583 WinUSBX_Set(QueryDeviceInformation);
2584 WinUSBX_Set(QueryInterfaceSettings);
2585 WinUSBX_Set(QueryPipe);
2586 WinUSBX_Set(ReadPipe);
2587 WinUSBX_Set(ResetPipe);
2588 WinUSBX_Set(SetCurrentAlternateSetting);
2589 WinUSBX_Set(SetPipePolicy);
2590 WinUSBX_Set(SetPowerPolicy);
2591 WinUSBX_Set(WritePipe);
2592 if (!native_winusb) {
2593 WinUSBX_Set(ResetDevice);
2595 if (WinUSBX[i].Initialize != NULL) {
2596 WinUSBX[i].initialized = true;
2597 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2599 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2600 WinUSBX[i].initialized = false;
2603 return LIBUSB_SUCCESS;
2606 static int winusbx_exit(int sub_api)
2608 return LIBUSB_SUCCESS;
2611 // NB: open and close must ensure that they only handle interface of
2612 // the right API type, as these functions can be called wholesale from
2613 // composite_open(), with interfaces belonging to different APIs
2614 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2616 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2617 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2618 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2623 CHECK_WINUSBX_AVAILABLE(sub_api);
2625 // WinUSB requires a seperate handle for each interface
2626 for (i = 0; i < USB_MAXINTERFACES; i++) {
2627 if ( (priv->usb_interface[i].path != NULL)
2628 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2629 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2630 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2631 if (file_handle == INVALID_HANDLE_VALUE) {
2632 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2633 switch(GetLastError()) {
2634 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2635 return LIBUSB_ERROR_NO_DEVICE;
2636 case ERROR_ACCESS_DENIED:
2637 return LIBUSB_ERROR_ACCESS;
2639 return LIBUSB_ERROR_IO;
2642 handle_priv->interface_handle[i].dev_handle = file_handle;
2646 return LIBUSB_SUCCESS;
2649 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2651 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2652 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2656 if (sub_api == SUB_API_NOTSET)
2657 sub_api = priv->sub_api;
2658 if (!WinUSBX[sub_api].initialized)
2661 for (i = 0; i < USB_MAXINTERFACES; i++) {
2662 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2663 file_handle = handle_priv->interface_handle[i].dev_handle;
2664 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2665 CloseHandle(file_handle);
2671 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2673 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2674 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2675 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2678 uint8_t endpoint_address;
2681 CHECK_WINUSBX_AVAILABLE(sub_api);
2683 // With handle and enpoints set (in parent), we can setup the default pipe properties
2684 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2685 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2686 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2687 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2688 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2689 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2691 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2692 continue; // Other policies don't apply to control endpoint or libusb0
2695 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2696 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2697 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2699 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2700 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2701 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2704 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2705 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2706 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2707 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2708 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2710 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2711 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2712 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2716 return LIBUSB_SUCCESS;
2719 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2721 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2722 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2723 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2724 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2725 HANDLE file_handle, winusb_handle;
2728 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2729 HDEVINFO dev_info = INVALID_HANDLE_VALUE;
2730 SP_DEVINFO_DATA dev_info_data;
2731 char* dev_path_no_guid = NULL;
2732 char filter_path[] = "\\\\.\\libusb0-0000";
2733 bool found_filter = false;
2735 CHECK_WINUSBX_AVAILABLE(sub_api);
2737 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2738 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2739 if ((is_using_usbccgp) || (iface == 0)) {
2740 // composite device (independent interfaces) or interface 0
2741 file_handle = handle_priv->interface_handle[iface].dev_handle;
2742 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2743 return LIBUSB_ERROR_NOT_FOUND;
2746 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2747 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2748 err = GetLastError();
2750 case ERROR_BAD_COMMAND:
2751 // The device was disconnected
2752 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2753 return LIBUSB_ERROR_NO_DEVICE;
2755 // it may be that we're using the libusb0 filter driver.
2756 // TODO: can we move this whole business into the K/0 DLL?
2757 for (i = 0; ; i++) {
2758 safe_free(dev_interface_details);
2759 safe_free(dev_path_no_guid);
2760 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2761 if ((found_filter) || (dev_interface_details == NULL)) {
2765 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2766 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2767 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2768 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2769 if (file_handle == INVALID_HANDLE_VALUE) {
2770 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2772 WinUSBX[sub_api].Free(winusb_handle);
2773 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle))
2774 found_filter = true;
2776 usbi_err(ctx, "could not initialize filter driver for %s", filter_path);
2780 if (!found_filter) {
2781 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2782 return LIBUSB_ERROR_ACCESS;
2786 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2788 // For all other interfaces, use GetAssociatedInterface()
2789 winusb_handle = handle_priv->interface_handle[0].api_handle;
2790 // It is a requirement for multiple interface devices on Windows that, to you
2791 // must first claim the first interface before you claim the others
2792 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2793 file_handle = handle_priv->interface_handle[0].dev_handle;
2794 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2795 handle_priv->interface_handle[0].api_handle = winusb_handle;
2796 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2798 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2799 return LIBUSB_ERROR_ACCESS;
2802 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2803 &handle_priv->interface_handle[iface].api_handle)) {
2804 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2805 switch(GetLastError()) {
2806 case ERROR_NO_MORE_ITEMS: // invalid iface
2807 return LIBUSB_ERROR_NOT_FOUND;
2808 case ERROR_BAD_COMMAND: // The device was disconnected
2809 return LIBUSB_ERROR_NO_DEVICE;
2810 case ERROR_ALREADY_EXISTS: // already claimed
2811 return LIBUSB_ERROR_BUSY;
2813 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2814 return LIBUSB_ERROR_ACCESS;
2818 usbi_dbg("claimed interface %d", iface);
2819 handle_priv->active_interface = iface;
2821 return LIBUSB_SUCCESS;
2824 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2826 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2827 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2828 HANDLE winusb_handle;
2830 CHECK_WINUSBX_AVAILABLE(sub_api);
2832 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2833 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2834 return LIBUSB_ERROR_NOT_FOUND;
2837 WinUSBX[sub_api].Free(winusb_handle);
2838 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2840 return LIBUSB_SUCCESS;
2844 * Return the first valid interface (of the same API type), for control transfers
2846 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2848 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2849 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2852 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2853 usbi_dbg("unsupported API ID");
2857 for (i=0; i<USB_MAXINTERFACES; i++) {
2858 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2859 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2860 && (handle_priv->interface_handle[i].api_handle != 0)
2861 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2862 && (priv->usb_interface[i].apib->id == api_id) ) {
2870 * Lookup interface by endpoint address. -1 if not found
2872 static int interface_by_endpoint(struct windows_device_priv *priv,
2873 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2876 for (i=0; i<USB_MAXINTERFACES; i++) {
2877 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2879 if (handle_priv->interface_handle[i].api_handle == 0)
2881 if (priv->usb_interface[i].endpoint == NULL)
2883 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2884 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2892 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2894 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2895 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2896 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2897 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2898 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2899 transfer->dev_handle);
2900 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2902 HANDLE winusb_handle;
2903 int current_interface;
2906 CHECK_WINUSBX_AVAILABLE(sub_api);
2908 transfer_priv->pollable_fd = INVALID_WINFD;
2909 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2911 if (size > MAX_CTRL_BUFFER_LENGTH)
2912 return LIBUSB_ERROR_INVALID_PARAM;
2914 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2915 if (current_interface < 0) {
2916 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2917 return LIBUSB_ERROR_NOT_FOUND;
2921 usbi_dbg("will use interface %d", current_interface);
2922 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2924 wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
2925 // Always use the handle returned from usbi_create_fd (wfd.handle)
2927 return LIBUSB_ERROR_NO_MEM;
2930 // Sending of set configuration control requests from WinUSB creates issues
2931 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2932 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2933 if (setup->value != priv->active_config) {
2934 usbi_warn(ctx, "cannot set configuration other than the default one");
2936 return LIBUSB_ERROR_INVALID_PARAM;
2938 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2939 wfd.overlapped->InternalHigh = 0;
2941 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2942 if(GetLastError() != ERROR_IO_PENDING) {
2943 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2945 return LIBUSB_ERROR_IO;
2948 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2949 wfd.overlapped->InternalHigh = (DWORD)size;
2953 // Use priv_transfer to store data needed for async polling
2954 transfer_priv->pollable_fd = wfd;
2955 transfer_priv->interface_number = (uint8_t)current_interface;
2957 return LIBUSB_SUCCESS;
2960 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2962 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2963 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2964 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2965 HANDLE winusb_handle;
2967 CHECK_WINUSBX_AVAILABLE(sub_api);
2969 if (altsetting > 255) {
2970 return LIBUSB_ERROR_INVALID_PARAM;
2973 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2974 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2975 usbi_err(ctx, "interface must be claimed first");
2976 return LIBUSB_ERROR_NOT_FOUND;
2979 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2980 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2981 return LIBUSB_ERROR_IO;
2984 return LIBUSB_SUCCESS;
2987 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2989 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2990 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2991 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2992 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2993 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2994 HANDLE winusb_handle;
2996 int current_interface;
2999 CHECK_WINUSBX_AVAILABLE(sub_api);
3001 transfer_priv->pollable_fd = INVALID_WINFD;
3003 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3004 if (current_interface < 0) {
3005 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3006 return LIBUSB_ERROR_NOT_FOUND;
3009 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3011 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3013 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
3014 // Always use the handle returned from usbi_create_fd (wfd.handle)
3016 return LIBUSB_ERROR_NO_MEM;
3019 if (IS_XFERIN(transfer)) {
3020 usbi_dbg("reading %d bytes", transfer->length);
3021 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
3023 usbi_dbg("writing %d bytes", transfer->length);
3024 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
3027 if(GetLastError() != ERROR_IO_PENDING) {
3028 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
3030 return LIBUSB_ERROR_IO;
3033 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3034 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
3037 transfer_priv->pollable_fd = wfd;
3038 transfer_priv->interface_number = (uint8_t)current_interface;
3040 return LIBUSB_SUCCESS;
3043 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3045 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3046 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3047 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3048 HANDLE winusb_handle;
3049 int current_interface;
3051 CHECK_WINUSBX_AVAILABLE(sub_api);
3053 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3054 if (current_interface < 0) {
3055 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3056 return LIBUSB_ERROR_NOT_FOUND;
3059 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3060 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3062 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3063 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3064 return LIBUSB_ERROR_NO_DEVICE;
3067 return LIBUSB_SUCCESS;
3071 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3072 * through testing as well):
3073 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3074 * the control transfer using CancelIo"
3076 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3078 // Cancelling of the I/O is done in the parent
3079 return LIBUSB_SUCCESS;
3082 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3084 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3085 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3086 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3087 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3088 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3089 HANDLE winusb_handle;
3090 int current_interface;
3092 CHECK_WINUSBX_AVAILABLE(sub_api);
3094 current_interface = transfer_priv->interface_number;
3095 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3096 usbi_err(ctx, "program assertion failed: invalid interface_number");
3097 return LIBUSB_ERROR_NOT_FOUND;
3099 usbi_dbg("will use interface %d", current_interface);
3101 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3103 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3104 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3105 return LIBUSB_ERROR_NO_DEVICE;
3108 return LIBUSB_SUCCESS;
3112 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3113 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3114 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3115 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3116 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3117 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3119 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3120 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3122 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3123 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3124 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3126 HANDLE winusb_handle;
3129 CHECK_WINUSBX_AVAILABLE(sub_api);
3131 // Reset any available pipe (except control)
3132 for (i=0; i<USB_MAXINTERFACES; i++) {
3133 winusb_handle = handle_priv->interface_handle[i].api_handle;
3134 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3136 // Cancel any pollable I/O
3137 usbi_remove_pollfd(ctx, wfd.fd);
3139 wfd = handle_to_winfd(winusb_handle);
3142 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3143 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3144 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3145 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3146 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3147 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3149 // FlushPipe seems to fail on OUT pipes
3150 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3151 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3152 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3153 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3155 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3156 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3157 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3163 // libusbK & libusb0 have the ability to issue an actual device reset
3164 if (WinUSBX[sub_api].ResetDevice != NULL) {
3165 winusb_handle = handle_priv->interface_handle[0].api_handle;
3166 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3167 WinUSBX[sub_api].ResetDevice(winusb_handle);
3170 return LIBUSB_SUCCESS;
3173 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3175 itransfer->transferred += io_size;
3176 return LIBUSB_TRANSFER_COMPLETED;
3180 * Internal HID Support functions (from libusb-win32)
3181 * Note that functions that complete data transfer synchronously must return
3182 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3184 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3185 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3187 static int _hid_wcslen(WCHAR *str)
3190 while (str[i] && (str[i] != 0x409)) {
3196 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3198 struct libusb_device_descriptor d;
3200 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3201 d.bDescriptorType = LIBUSB_DT_DEVICE;
3202 d.bcdUSB = 0x0200; /* 2.00 */
3204 d.bDeviceSubClass = 0;
3205 d.bDeviceProtocol = 0;
3206 d.bMaxPacketSize0 = 64; /* fix this! */
3207 d.idVendor = (uint16_t)dev->vid;
3208 d.idProduct = (uint16_t)dev->pid;
3209 d.bcdDevice = 0x0100;
3210 d.iManufacturer = dev->string_index[0];
3211 d.iProduct = dev->string_index[1];
3212 d.iSerialNumber = dev->string_index[2];
3213 d.bNumConfigurations = 1;
3215 if (*size > LIBUSB_DT_DEVICE_SIZE)
3216 *size = LIBUSB_DT_DEVICE_SIZE;
3217 memcpy(data, &d, *size);
3218 return LIBUSB_COMPLETED;
3221 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3223 char num_endpoints = 0;
3224 size_t config_total_len = 0;
3225 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3226 struct libusb_config_descriptor *cd;
3227 struct libusb_interface_descriptor *id;
3228 struct libusb_hid_descriptor *hd;
3229 struct libusb_endpoint_descriptor *ed;
3232 if (dev->input_report_size)
3234 if (dev->output_report_size)
3237 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3238 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3241 cd = (struct libusb_config_descriptor *)tmp;
3242 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3243 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3244 + LIBUSB_DT_INTERFACE_SIZE);
3245 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3246 + LIBUSB_DT_INTERFACE_SIZE
3247 + LIBUSB_DT_HID_SIZE);
3249 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3250 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3251 cd->wTotalLength = (uint16_t) config_total_len;
3252 cd->bNumInterfaces = 1;
3253 cd->bConfigurationValue = 1;
3254 cd->iConfiguration = 0;
3255 cd->bmAttributes = 1 << 7; /* bus powered */
3258 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3259 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3260 id->bInterfaceNumber = 0;
3261 id->bAlternateSetting = 0;
3262 id->bNumEndpoints = num_endpoints;
3263 id->bInterfaceClass = 3;
3264 id->bInterfaceSubClass = 0;
3265 id->bInterfaceProtocol = 0;
3268 tmp_size = LIBUSB_DT_HID_SIZE;
3269 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3271 if (dev->input_report_size) {
3272 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3273 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3274 ed->bEndpointAddress = HID_IN_EP;
3275 ed->bmAttributes = 3;
3276 ed->wMaxPacketSize = dev->input_report_size - 1;
3278 ed = (struct libusb_endpoint_descriptor *)((char*)ed + LIBUSB_DT_ENDPOINT_SIZE);
3281 if (dev->output_report_size) {
3282 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3283 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3284 ed->bEndpointAddress = HID_OUT_EP;
3285 ed->bmAttributes = 3;
3286 ed->wMaxPacketSize = dev->output_report_size - 1;
3290 if (*size > config_total_len)
3291 *size = config_total_len;
3292 memcpy(data, tmp, *size);
3293 return LIBUSB_COMPLETED;
3296 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3297 void *data, size_t *size)
3300 size_t tmp_size = 0;
3303 /* language ID, EN-US */
3304 char string_langid[] = {
3309 if ((*size < 2) || (*size > 255)) {
3310 return LIBUSB_ERROR_OVERFLOW;
3314 tmp = string_langid;
3315 tmp_size = sizeof(string_langid)+2;
3317 for (i=0; i<3; i++) {
3318 if (_index == (dev->string_index[i])) {
3319 tmp = dev->string[i];
3320 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3324 if (i == 3) { // not found
3325 return LIBUSB_ERROR_INVALID_PARAM;
3330 return LIBUSB_ERROR_INVALID_PARAM;
3333 if (tmp_size < *size) {
3337 ((uint8_t*)data)[0] = (uint8_t)*size;
3338 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3339 memcpy((uint8_t*)data+2, tmp, *size-2);
3340 return LIBUSB_COMPLETED;
3343 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3345 struct libusb_hid_descriptor d;
3346 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3347 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3349 _hid_get_report_descriptor(dev, tmp, &report_len);
3351 d.bLength = LIBUSB_DT_HID_SIZE;
3352 d.bDescriptorType = LIBUSB_DT_HID;
3353 d.bcdHID = 0x0110; /* 1.10 */
3355 d.bNumDescriptors = 1;
3356 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3357 d.wClassDescriptorLength = (uint16_t)report_len;
3359 if (*size > LIBUSB_DT_HID_SIZE)
3360 *size = LIBUSB_DT_HID_SIZE;
3361 memcpy(data, &d, *size);
3362 return LIBUSB_COMPLETED;
3365 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3367 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3370 /* usage page (0xFFA0 == vendor defined) */
3371 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3372 /* usage (vendor defined) */
3373 d[i++] = 0x09; d[i++] = 0x01;
3374 /* start collection (application) */
3375 d[i++] = 0xA1; d[i++] = 0x01;
3377 if (dev->input_report_size) {
3378 /* usage (vendor defined) */
3379 d[i++] = 0x09; d[i++] = 0x01;
3380 /* logical minimum (0) */
3381 d[i++] = 0x15; d[i++] = 0x00;
3382 /* logical maximum (255) */
3383 d[i++] = 0x25; d[i++] = 0xFF;
3384 /* report size (8 bits) */
3385 d[i++] = 0x75; d[i++] = 0x08;
3387 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3388 /* input (data, variable, absolute) */
3389 d[i++] = 0x81; d[i++] = 0x00;
3392 if (dev->output_report_size) {
3393 /* usage (vendor defined) */
3394 d[i++] = 0x09; d[i++] = 0x02;
3395 /* logical minimum (0) */
3396 d[i++] = 0x15; d[i++] = 0x00;
3397 /* logical maximum (255) */
3398 d[i++] = 0x25; d[i++] = 0xFF;
3399 /* report size (8 bits) */
3400 d[i++] = 0x75; d[i++] = 0x08;
3402 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3403 /* output (data, variable, absolute) */
3404 d[i++] = 0x91; d[i++] = 0x00;
3406 /* feature report */
3407 if (dev->feature_report_size) {
3408 /* usage (vendor defined) */
3409 d[i++] = 0x09; d[i++] = 0x03;
3410 /* logical minimum (0) */
3411 d[i++] = 0x15; d[i++] = 0x00;
3412 /* logical maximum (255) */
3413 d[i++] = 0x25; d[i++] = 0xFF;
3414 /* report size (8 bits) */
3415 d[i++] = 0x75; d[i++] = 0x08;
3417 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3418 /* feature (data, variable, absolute) */
3419 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3422 /* end collection */
3427 memcpy(data, d, *size);
3428 return LIBUSB_COMPLETED;
3431 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3432 int type, int _index, void *data, size_t *size)
3435 case LIBUSB_DT_DEVICE:
3436 usbi_dbg("LIBUSB_DT_DEVICE");
3437 return _hid_get_device_descriptor(dev, data, size);
3438 case LIBUSB_DT_CONFIG:
3439 usbi_dbg("LIBUSB_DT_CONFIG");
3441 return _hid_get_config_descriptor(dev, data, size);
3442 return LIBUSB_ERROR_INVALID_PARAM;
3443 case LIBUSB_DT_STRING:
3444 usbi_dbg("LIBUSB_DT_STRING");
3445 return _hid_get_string_descriptor(dev, _index, data, size);
3447 usbi_dbg("LIBUSB_DT_HID");
3449 return _hid_get_hid_descriptor(dev, data, size);
3450 return LIBUSB_ERROR_INVALID_PARAM;
3451 case LIBUSB_DT_REPORT:
3452 usbi_dbg("LIBUSB_DT_REPORT");
3454 return _hid_get_report_descriptor(dev, data, size);
3455 return LIBUSB_ERROR_INVALID_PARAM;
3456 case LIBUSB_DT_PHYSICAL:
3457 usbi_dbg("LIBUSB_DT_PHYSICAL");
3458 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3459 return LIBUSB_COMPLETED;
3460 return LIBUSB_ERROR_OTHER;
3462 usbi_dbg("unsupported");
3463 return LIBUSB_ERROR_INVALID_PARAM;
3466 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3467 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3471 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3472 int r = LIBUSB_SUCCESS;
3474 if (tp->hid_buffer != NULL) {
3475 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3478 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3479 usbi_dbg("invalid size (%d)", *size);
3480 return LIBUSB_ERROR_INVALID_PARAM;
3483 switch (report_type) {
3484 case HID_REPORT_TYPE_INPUT:
3485 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3487 case HID_REPORT_TYPE_FEATURE:
3488 ioctl_code = IOCTL_HID_GET_FEATURE;
3491 usbi_dbg("unknown HID report type %d", report_type);
3492 return LIBUSB_ERROR_INVALID_PARAM;
3495 // Add a trailing byte to detect overflows
3496 buf = (uint8_t*)calloc(expected_size+1, 1);
3498 return LIBUSB_ERROR_NO_MEM;
3500 buf[0] = (uint8_t)id; // Must be set always
3501 usbi_dbg("report ID: 0x%02X", buf[0]);
3503 tp->hid_expected_size = expected_size;
3504 read_size = expected_size;
3506 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3507 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3508 buf, expected_size+1, &read_size, overlapped)) {
3509 if (GetLastError() != ERROR_IO_PENDING) {
3510 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3512 return LIBUSB_ERROR_IO;
3514 // Asynchronous wait
3515 tp->hid_buffer = buf;
3516 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3517 return LIBUSB_SUCCESS;
3520 // Transfer completed synchronously => copy and discard extra buffer
3521 if (read_size == 0) {
3522 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3526 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3528 if ((size_t)read_size > expected_size) {
3529 r = LIBUSB_ERROR_OVERFLOW;
3530 usbi_dbg("OVERFLOW!");
3532 r = LIBUSB_COMPLETED;
3535 *size = MIN((size_t)read_size, *size);
3537 // Discard report ID
3538 memcpy(data, buf+1, *size);
3540 memcpy(data, buf, *size);
3547 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3548 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3551 uint8_t *buf = NULL;
3552 DWORD ioctl_code, write_size= (DWORD)*size;
3554 if (tp->hid_buffer != NULL) {
3555 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3558 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3559 usbi_dbg("invalid size (%d)", *size);
3560 return LIBUSB_ERROR_INVALID_PARAM;
3563 switch (report_type) {
3564 case HID_REPORT_TYPE_OUTPUT:
3565 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3567 case HID_REPORT_TYPE_FEATURE:
3568 ioctl_code = IOCTL_HID_SET_FEATURE;
3571 usbi_dbg("unknown HID report type %d", report_type);
3572 return LIBUSB_ERROR_INVALID_PARAM;
3575 usbi_dbg("report ID: 0x%02X", id);
3576 // When report IDs are not used (i.e. when id == 0), we must add
3577 // a null report ID. Otherwise, we just use original data buffer
3581 buf = (uint8_t*) malloc(write_size);
3583 return LIBUSB_ERROR_NO_MEM;
3587 memcpy(buf + 1, data, *size);
3589 // This seems like a waste, but if we don't duplicate the
3590 // data, we'll get issues when freeing hid_buffer
3591 memcpy(buf, data, *size);
3593 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3597 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3598 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3599 buf, write_size, &write_size, overlapped)) {
3600 if (GetLastError() != ERROR_IO_PENDING) {
3601 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3603 return LIBUSB_ERROR_IO;
3605 tp->hid_buffer = buf;
3606 tp->hid_dest = NULL;
3607 return LIBUSB_SUCCESS;
3610 // Transfer completed synchronously
3612 if (write_size == 0) {
3613 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3616 return LIBUSB_COMPLETED;
3619 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3620 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3621 size_t *size, OVERLAPPED* overlapped)
3623 int report_type = (value >> 8) & 0xFF;
3624 int report_id = value & 0xFF;
3626 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3627 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3628 return LIBUSB_ERROR_INVALID_PARAM;
3630 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3631 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3633 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3634 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3636 return LIBUSB_ERROR_INVALID_PARAM;
3643 static int hid_init(int sub_api, struct libusb_context *ctx)
3645 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3646 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3647 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3648 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3649 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3650 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3651 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3652 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3653 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3654 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3655 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3656 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3657 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3658 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3659 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3660 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3662 api_hid_available = true;
3663 return LIBUSB_SUCCESS;
3666 static int hid_exit(int sub_api)
3668 return LIBUSB_SUCCESS;
3671 // NB: open and close must ensure that they only handle interface of
3672 // the right API type, as these functions can be called wholesale from
3673 // composite_open(), with interfaces belonging to different APIs
3674 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3676 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3677 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3678 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3680 HIDD_ATTRIBUTES hid_attributes;
3681 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3682 HIDP_CAPS capabilities;
3683 HIDP_VALUE_CAPS *value_caps;
3685 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3687 // report IDs handling
3689 const char* type[3] = {"input", "output", "feature"};
3690 int nb_ids[2]; // zero and nonzero report IDs
3692 CHECK_HID_AVAILABLE;
3693 if (priv->hid == NULL) {
3694 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3695 return LIBUSB_ERROR_NOT_FOUND;
3698 for (i = 0; i < USB_MAXINTERFACES; i++) {
3699 if ( (priv->usb_interface[i].path != NULL)
3700 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3701 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3702 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3704 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3705 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3706 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3707 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3708 * HidD_GetFeature (if the device supports Feature reports)."
3710 if (hid_handle == INVALID_HANDLE_VALUE) {
3711 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3712 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3713 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3714 if (hid_handle == INVALID_HANDLE_VALUE) {
3715 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3716 switch(GetLastError()) {
3717 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3718 return LIBUSB_ERROR_NO_DEVICE;
3719 case ERROR_ACCESS_DENIED:
3720 return LIBUSB_ERROR_ACCESS;
3722 return LIBUSB_ERROR_IO;
3725 priv->usb_interface[i].restricted_functionality = true;
3727 handle_priv->interface_handle[i].api_handle = hid_handle;
3731 hid_attributes.Size = sizeof(hid_attributes);
3733 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3734 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3738 priv->hid->vid = hid_attributes.VendorID;
3739 priv->hid->pid = hid_attributes.ProductID;
3741 // Set the maximum available input buffer size
3742 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3743 usbi_dbg("set maximum input buffer size to %d", i/2);
3745 // Get the maximum input and output report size
3746 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3747 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3750 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3751 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3755 // Find out if interrupt will need report IDs
3756 size[0] = capabilities.NumberInputValueCaps;
3757 size[1] = capabilities.NumberOutputValueCaps;
3758 size[2] = capabilities.NumberFeatureValueCaps;
3759 for (j=HidP_Input; j<=HidP_Feature; j++) {
3760 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3761 priv->hid->uses_report_ids[j] = false;
3763 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3764 if ( (value_caps != NULL)
3765 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3766 && (size[j] >= 1) ) {
3769 for (i=0; i<(int)size[j]; i++) {
3770 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3771 if (value_caps[i].ReportID != 0) {
3777 if (nb_ids[1] != 0) {
3778 if (nb_ids[0] != 0) {
3779 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3782 priv->hid->uses_report_ids[j] = true;
3785 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3787 safe_free(value_caps);
3791 // Set the report sizes
3792 priv->hid->input_report_size = capabilities.InputReportByteLength;
3793 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3794 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3796 // Fetch string descriptors
3797 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3798 if (priv->hid->string_index[0] != 0) {
3799 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3800 sizeof(priv->hid->string[0]));
3802 priv->hid->string[0][0] = 0;
3804 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3805 if (priv->hid->string_index[1] != 0) {
3806 HidD_GetProductString(hid_handle, priv->hid->string[1],
3807 sizeof(priv->hid->string[1]));
3809 priv->hid->string[1][0] = 0;
3811 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3812 if (priv->hid->string_index[2] != 0) {
3813 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3814 sizeof(priv->hid->string[2]));
3816 priv->hid->string[2][0] = 0;
3820 if (preparsed_data) {
3821 HidD_FreePreparsedData(preparsed_data);
3824 return LIBUSB_SUCCESS;
3827 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3829 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3830 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3834 if (!api_hid_available)
3837 for (i = 0; i < USB_MAXINTERFACES; i++) {
3838 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3839 file_handle = handle_priv->interface_handle[i].api_handle;
3840 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3841 CloseHandle(file_handle);
3847 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3849 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3850 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3852 CHECK_HID_AVAILABLE;
3854 // NB: Disconnection detection is not possible in this function
3855 if (priv->usb_interface[iface].path == NULL) {
3856 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3859 // We use dev_handle as a flag for interface claimed
3860 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3861 return LIBUSB_ERROR_BUSY; // already claimed
3864 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3866 usbi_dbg("claimed interface %d", iface);
3867 handle_priv->active_interface = iface;
3869 return LIBUSB_SUCCESS;
3872 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3874 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3875 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3877 CHECK_HID_AVAILABLE;
3879 if (priv->usb_interface[iface].path == NULL) {
3880 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3883 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3884 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3887 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3889 return LIBUSB_SUCCESS;
3892 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3894 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3896 CHECK_HID_AVAILABLE;
3898 if (altsetting > 255) {
3899 return LIBUSB_ERROR_INVALID_PARAM;
3902 if (altsetting != 0) {
3903 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3904 return LIBUSB_ERROR_NOT_SUPPORTED;
3907 return LIBUSB_SUCCESS;
3910 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3912 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3913 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3914 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3915 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3916 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3917 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3920 int current_interface, config;
3922 int r = LIBUSB_ERROR_INVALID_PARAM;
3924 CHECK_HID_AVAILABLE;
3926 transfer_priv->pollable_fd = INVALID_WINFD;
3927 safe_free(transfer_priv->hid_buffer);
3928 transfer_priv->hid_dest = NULL;
3929 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3931 if (size > MAX_CTRL_BUFFER_LENGTH) {
3932 return LIBUSB_ERROR_INVALID_PARAM;
3935 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3936 if (current_interface < 0) {
3937 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3938 return LIBUSB_ERROR_NOT_FOUND;
3942 usbi_dbg("will use interface %d", current_interface);
3943 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3944 // Always use the handle returned from usbi_create_fd (wfd.handle)
3945 wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
3947 return LIBUSB_ERROR_NOT_FOUND;
3950 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3951 case LIBUSB_REQUEST_TYPE_STANDARD:
3952 switch(setup->request) {
3953 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3954 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3955 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3957 case LIBUSB_REQUEST_GET_CONFIGURATION:
3958 r = windows_get_configuration(transfer->dev_handle, &config);
3959 if (r == LIBUSB_SUCCESS) {
3961 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3962 r = LIBUSB_COMPLETED;
3965 case LIBUSB_REQUEST_SET_CONFIGURATION:
3966 if (setup->value == priv->active_config) {
3967 r = LIBUSB_COMPLETED;
3969 usbi_warn(ctx, "cannot set configuration other than the default one");
3970 r = LIBUSB_ERROR_INVALID_PARAM;
3973 case LIBUSB_REQUEST_GET_INTERFACE:
3975 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3976 r = LIBUSB_COMPLETED;
3978 case LIBUSB_REQUEST_SET_INTERFACE:
3979 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3980 if (r == LIBUSB_SUCCESS) {
3981 r = LIBUSB_COMPLETED;
3985 usbi_warn(ctx, "unsupported HID control request");
3986 r = LIBUSB_ERROR_INVALID_PARAM;
3990 case LIBUSB_REQUEST_TYPE_CLASS:
3991 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3992 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3993 &size, wfd.overlapped);
3996 usbi_warn(ctx, "unsupported HID control request");
3997 r = LIBUSB_ERROR_INVALID_PARAM;
4001 if (r == LIBUSB_COMPLETED) {
4002 // Force request to be completed synchronously. Transferred size has been set by previous call
4003 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4004 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
4005 // set InternalHigh to the number of bytes transferred
4006 wfd.overlapped->InternalHigh = (DWORD)size;
4010 if (r == LIBUSB_SUCCESS) {
4011 // Use priv_transfer to store data needed for async polling
4012 transfer_priv->pollable_fd = wfd;
4013 transfer_priv->interface_number = (uint8_t)current_interface;
4021 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4022 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4023 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4024 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4025 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4026 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4029 bool direction_in, ret;
4030 int current_interface, length;
4032 int r = LIBUSB_SUCCESS;
4034 CHECK_HID_AVAILABLE;
4036 transfer_priv->pollable_fd = INVALID_WINFD;
4037 transfer_priv->hid_dest = NULL;
4038 safe_free(transfer_priv->hid_buffer);
4040 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4041 if (current_interface < 0) {
4042 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4043 return LIBUSB_ERROR_NOT_FOUND;
4046 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
4048 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4049 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
4051 wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
4052 // Always use the handle returned from usbi_create_fd (wfd.handle)
4054 return LIBUSB_ERROR_NO_MEM;
4057 // If report IDs are not in use, an extra prefix byte must be added
4058 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4059 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4060 length = transfer->length+1;
4062 length = transfer->length;
4064 // Add a trailing byte to detect overflows on input
4065 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4066 if (transfer_priv->hid_buffer == NULL) {
4067 return LIBUSB_ERROR_NO_MEM;
4069 transfer_priv->hid_expected_size = length;
4072 transfer_priv->hid_dest = transfer->buffer;
4073 usbi_dbg("reading %d bytes (report ID: 0x00)", length);
4074 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4076 if (!priv->hid->uses_report_ids[1]) {
4077 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4079 // We could actually do without the calloc and memcpy in this case
4080 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4082 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4083 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4086 if (GetLastError() != ERROR_IO_PENDING) {
4087 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4089 safe_free(transfer_priv->hid_buffer);
4090 return LIBUSB_ERROR_IO;
4093 // Only write operations that completed synchronously need to free up
4094 // hid_buffer. For reads, copy_transfer_data() handles that process.
4095 if (!direction_in) {
4096 safe_free(transfer_priv->hid_buffer);
4099 usbi_err(ctx, "program assertion failed - no data was transferred");
4102 if (size > (size_t)length) {
4103 usbi_err(ctx, "OVERFLOW!");
4104 r = LIBUSB_ERROR_OVERFLOW;
4106 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4107 wfd.overlapped->InternalHigh = size;
4110 transfer_priv->pollable_fd = wfd;
4111 transfer_priv->interface_number = (uint8_t)current_interface;
4116 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4118 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4119 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4120 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4122 int current_interface;
4124 CHECK_HID_AVAILABLE;
4126 current_interface = transfer_priv->interface_number;
4127 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4128 CancelIo(hid_handle);
4130 return LIBUSB_SUCCESS;
4133 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4135 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4137 int current_interface;
4139 CHECK_HID_AVAILABLE;
4141 // Flushing the queues on all interfaces is the best we can achieve
4142 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4143 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4144 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4145 HidD_FlushQueue(hid_handle);
4148 return LIBUSB_SUCCESS;
4151 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4153 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4154 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4155 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4157 int current_interface;
4159 CHECK_HID_AVAILABLE;
4161 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4162 if (current_interface < 0) {
4163 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4164 return LIBUSB_ERROR_NOT_FOUND;
4167 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4168 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4170 // No endpoint selection with Microsoft's implementation, so we try to flush the
4171 // whole interface. Should be OK for most case scenarios
4172 if (!HidD_FlushQueue(hid_handle)) {
4173 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4174 // Device was probably disconnected
4175 return LIBUSB_ERROR_NO_DEVICE;
4178 return LIBUSB_SUCCESS;
4181 // This extra function is only needed for HID
4182 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4183 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4184 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4185 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4186 int r = LIBUSB_TRANSFER_COMPLETED;
4187 uint32_t corrected_size = io_size;
4189 if (transfer_priv->hid_buffer != NULL) {
4190 // If we have a valid hid_buffer, it means the transfer was async
4191 if (transfer_priv->hid_dest != NULL) { // Data readout
4192 if (corrected_size > 0) {
4193 // First, check for overflow
4194 if (corrected_size > transfer_priv->hid_expected_size) {
4195 usbi_err(ctx, "OVERFLOW!");
4196 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4197 r = LIBUSB_TRANSFER_OVERFLOW;
4200 if (transfer_priv->hid_buffer[0] == 0) {
4201 // Discard the 1 byte report ID prefix
4203 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4205 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4208 transfer_priv->hid_dest = NULL;
4210 // For write, we just need to free the hid buffer
4211 safe_free(transfer_priv->hid_buffer);
4213 itransfer->transferred += corrected_size;
4219 * Composite API functions
4221 static int composite_init(int sub_api, struct libusb_context *ctx)
4223 return LIBUSB_SUCCESS;
4226 static int composite_exit(int sub_api)
4228 return LIBUSB_SUCCESS;
4231 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4233 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4234 int r = LIBUSB_ERROR_NOT_FOUND;
4236 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4237 bool available[SUB_API_MAX+1] = {0};
4239 for (i=0; i<USB_MAXINTERFACES; i++) {
4240 switch (priv->usb_interface[i].apib->id) {
4241 case USB_API_WINUSBX:
4242 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4243 available[priv->usb_interface[i].sub_api] = true;
4246 available[SUB_API_MAX] = true;
4253 for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4255 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4256 if (r != LIBUSB_SUCCESS) {
4261 if (available[SUB_API_MAX]) { // HID driver
4262 r = hid_open(SUB_API_NOTSET, dev_handle);
4267 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4269 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4271 bool available[SUB_API_MAX];
4273 for (i = 0; i<SUB_API_MAX; i++) {
4274 available[i] = false;
4277 for (i=0; i<USB_MAXINTERFACES; i++) {
4278 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4279 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4280 available[priv->usb_interface[i].sub_api] = true;
4284 for (i=0; i<SUB_API_MAX; i++) {
4286 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4291 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4293 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4294 return priv->usb_interface[iface].apib->
4295 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4298 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4300 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4301 return priv->usb_interface[iface].apib->
4302 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4305 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4307 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4308 return priv->usb_interface[iface].apib->
4309 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4312 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4314 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4315 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4316 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4319 // Interface shouldn't matter for control, but it does in practice, with Windows'
4320 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4321 for (pass = 0; pass < 2; pass++) {
4322 for (i=0; i<USB_MAXINTERFACES; i++) {
4323 if (priv->usb_interface[i].path != NULL) {
4324 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4325 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4328 usbi_dbg("using interface %d", i);
4329 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4334 usbi_err(ctx, "no libusb supported interfaces to complete request");
4335 return LIBUSB_ERROR_NOT_FOUND;
4338 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4339 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4340 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4341 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4342 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4343 int current_interface;
4345 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4346 if (current_interface < 0) {
4347 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4348 return LIBUSB_ERROR_NOT_FOUND;
4351 return priv->usb_interface[current_interface].apib->
4352 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4354 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4355 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4356 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4357 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4358 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4359 int current_interface;
4361 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4362 if (current_interface < 0) {
4363 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4364 return LIBUSB_ERROR_NOT_FOUND;
4367 return priv->usb_interface[current_interface].apib->
4368 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4370 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4372 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4373 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4374 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4375 int current_interface;
4377 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4378 if (current_interface < 0) {
4379 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4380 return LIBUSB_ERROR_NOT_FOUND;
4383 return priv->usb_interface[current_interface].apib->
4384 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4386 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4388 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4389 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4390 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4392 return priv->usb_interface[transfer_priv->interface_number].apib->
4393 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4395 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4397 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4398 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4399 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4401 return priv->usb_interface[transfer_priv->interface_number].apib->
4402 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4404 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4406 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4409 bool available[SUB_API_MAX];
4410 for (i = 0; i<SUB_API_MAX; i++) {
4411 available[i] = false;
4413 for (i=0; i<USB_MAXINTERFACES; i++) {
4414 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4415 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4416 available[priv->usb_interface[i].sub_api] = true;
4419 for (i=0; i<SUB_API_MAX; i++) {
4421 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4422 if (r != LIBUSB_SUCCESS) {
4427 return LIBUSB_SUCCESS;
4430 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4432 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4433 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4434 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4436 return priv->usb_interface[transfer_priv->interface_number].apib->
4437 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);