libusbx 1.0.18 *FINAL RELEASE*
[libusbx.git] / libusb / os / windows_usb.c
blob5abadc1fdaa773325d676ffab23d5c18afd930c9
1 /*
2 * windows backend for libusbx 1.0
3 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4 * With contributions from Michael Plante, Orin Eman et al.
5 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
6 * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
7 * Hash table functions adapted from glibc, by Ulrich Drepper et al.
8 * Major code testing contribution by Xiaofan Chen
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <config.h>
26 #include <windows.h>
27 #include <setupapi.h>
28 #include <ctype.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <process.h>
32 #include <stdio.h>
33 #include <inttypes.h>
34 #include <objbase.h>
35 #include <winioctl.h>
37 #include "libusbi.h"
38 #include "poll_windows.h"
39 #include "windows_usb.h"
41 // The 2 macros below are used in conjunction with safe loops.
42 #define LOOP_CHECK(fcall) { r=fcall; if (r != LIBUSB_SUCCESS) continue; }
43 #define LOOP_BREAK(err) { r=err; continue; }
45 // Helper prototypes
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);
49 // Common calls
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);
68 // HID API prototypes
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);
100 // Global variables
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;
104 // Concurrency
105 static int concurrent_usage = -1;
106 usbi_mutex_t autoclaim_lock;
107 // Timer thread
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;
115 // API globals
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);
127 return false;
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]);
140 return guid_string;
142 #endif
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];
153 DWORD size;
154 ssize_t i;
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) {
165 case 0:
166 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
167 break;
168 case 0xE0000000:
169 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
170 break;
171 default:
172 break;
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);
178 if (size == 0) {
179 format_error = GetLastError();
180 if (format_error)
181 safe_sprintf(err_string, ERR_BUFFER_SIZE,
182 "Windows error code %u (FormatMessage error code %u)", error_code, format_error);
183 else
184 safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
185 } else {
186 // Remove CR/LF terminators
187 for (i=safe_strlen(err_string)-1; (i>=0) && ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
188 err_string[i] = 0;
191 return err_string;
193 #endif
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;
204 size_t add_root = 0;
206 if (path == NULL)
207 return NULL;
209 size = safe_strlen(path)+1;
210 root_size = sizeof(root_prefix)-1;
212 // Microsoft indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
213 if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
214 ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
215 add_root = root_size;
216 size += add_root;
219 if ((ret_path = (char*) calloc(size, 1)) == NULL)
220 return NULL;
222 safe_strcpy(&ret_path[add_root], size-add_root, path);
224 // Ensure consistancy with root prefix
225 for (j=0; j<root_size; j++)
226 ret_path[j] = root_prefix[j];
228 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
229 for(j=root_size; j<size; j++) {
230 ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
231 if (ret_path[j] == '\\')
232 ret_path[j] = '#';
235 return ret_path;
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
265 * Parameters:
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)
278 if (_index <= 0) {
279 *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
280 if (*dev_info == INVALID_HANDLE_VALUE) {
281 return false;
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;
293 return false;
295 return true;
299 * enumerate interfaces for a specific GUID
301 * Parameters:
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;
316 DWORD size;
318 if (_index <= 0) {
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;
331 return NULL;
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;
343 return NULL;
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));
352 goto err_exit;
354 } else {
355 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
356 goto err_exit;
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);
361 goto err_exit;
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;
373 err_exit:
374 pSetupDiDestroyDeviceInfoList(*dev_info);
375 *dev_info = INVALID_HANDLE_VALUE;
376 return NULL;
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;
384 DWORD size;
385 if (_index <= 0) {
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;
397 return NULL;
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;
408 return NULL;
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));
416 goto err_exit;
418 } else {
419 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
420 goto err_exit;
422 if ((dev_interface_details = malloc(size)) == NULL) {
423 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
424 goto err_exit;
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);
438 DWORD value_type=0;
439 LONG status;
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);
448 } else {
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;
456 err_exit:
457 pSetupDiDestroyDeviceInfoList(*dev_info);
458 *dev_info = INVALID_HANDLE_VALUE;
459 return NULL;}
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 {
465 unsigned long used;
466 char* str;
467 } 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))
482 divider += 2;
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");
497 // Create a mutex
498 usbi_mutex_init(&htab_write_mutex, NULL);
500 // Change nel to the first prime number not smaller as nel.
501 nel |= 1;
502 while(!isprime(nel))
503 nel += 2;
505 htab_size = nel;
506 usbi_dbg("using %d entries hash table", nel);
507 htab_filled = 0;
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");
513 return 0;
516 return 1;
519 /* After using the hash table it has to be destroyed. */
520 static void htab_destroy(void)
522 size_t i;
523 if (htab_table == NULL) {
524 return;
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;
547 unsigned long idx;
548 unsigned long r = 5381;
549 int c;
550 char* sz = str;
552 if (str == NULL)
553 return 0;
555 // Compute main hash value (algorithm suggested by Nokia)
556 while ((c = *sz++) != 0)
557 r = ((r << 5) + r) + c;
558 if (r == 0)
559 ++r;
561 // compute table hash: simply take the modulus
562 hval = r % htab_size;
563 if (hval == 0)
564 ++hval;
566 // Try the first index
567 idx = hval;
569 if (htab_table[idx].used) {
570 if ( (htab_table[idx].used == hval)
571 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
572 // existing hash
573 return idx;
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);
580 do {
581 // Because size is prime this guarantees to step through all available indexes
582 if (idx <= hval2) {
583 idx = htab_size + idx - hval2;
584 } else {
585 idx -= hval2;
588 // If we visited all entries leave the loop unsuccessfully
589 if (idx == hval) {
590 break;
593 // If entry is found use it.
594 if ( (htab_table[idx].used == hval)
595 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
596 return idx;
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);
607 return 0;
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);
622 return 0;
624 memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
625 ++htab_filled;
626 usbi_mutex_unlock(&htab_write_mutex);
628 return idx;
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];
641 unsigned i;
643 if (level < 1) return 0;
644 for (i = 0; i<level; i++) {
645 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
646 return 0;
648 devinst = parent_devinst;
650 if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
651 return 0;
653 // TODO: (post hotplug): try without sanitizing
654 sanitized_path = sanitize_path(path);
655 if (sanitized_path == NULL) {
656 return 0;
658 session_id = htab_hash(sanitized_path);
659 safe_free(sanitized_path);
660 return session_id;
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)
668 int i, r;
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);
677 return 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){
707 int i;
708 const char sep_str[2] = {LIST_SEPARATOR, 0};
709 char *tok, *tmp_str;
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) {
720 free(tmp_str);
721 return i;
724 tok = strtok(NULL, sep_str);
726 free (tmp_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;
742 switch(api_type) {
743 case USB_API_WINUSBX:
744 case USB_API_HID:
745 break;
746 default:
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]++;
762 break;
765 if (current_interface == USB_MAXINTERFACES) {
766 usbi_err(ctx, "could not auto-claim any interface");
767 r = LIBUSB_ERROR_NOT_FOUND;
769 } else {
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;
779 return r;
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);
789 int r;
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);
798 } else {
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: libusbx 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 libusbx'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;
818 HANDLE semaphore;
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?
839 // Detect OS version
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;
855 goto init_exit;
858 // We need a lock for proper auto-release
859 usbi_mutex_init(&autoclaim_lock, NULL);
861 // Initialize pollable file descriptors
862 init_polling();
864 // Load DLL imports
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);
883 goto init_exit;
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");
889 goto init_exit;
891 timer_mutex = CreateMutex(NULL, FALSE, NULL);
892 if (timer_mutex == NULL) {
893 usbi_err(ctx, "could not create timer mutex - aborting");
894 goto init_exit;
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");
899 goto init_exit;
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");
906 goto init_exit;
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
913 r = LIBUSB_SUCCESS;
915 init_exit: // Holds semaphore here.
916 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
917 if (timer_thread) {
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);
925 timer_thread = NULL;
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;
937 if (timer_mutex) {
938 CloseHandle(timer_mutex);
939 timer_mutex = NULL;
941 htab_destroy();
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);
949 return r;
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);
962 int vid, pid;
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;
978 } else {
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);
994 int r;
995 uint8_t i;
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))
1017 break;
1019 size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT);
1020 memset(&cd_buf_short, 0, size);
1022 cd_buf_short.req.ConnectionIndex = (ULONG)priv->port;
1023 cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1024 cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1025 cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1026 cd_buf_short.req.SetupPacket.wIndex = i;
1027 cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1029 // Dummy call to get the required data size. Initial failures are reported as info rather
1030 // than error as they can occur for non-penalizing situations, such as with some hubs.
1031 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
1032 &cd_buf_short, size, &ret_size, NULL)) {
1033 usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
1034 LOOP_BREAK(LIBUSB_ERROR_IO);
1037 if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
1038 usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
1039 LOOP_BREAK(LIBUSB_ERROR_IO);
1042 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
1043 if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
1044 usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
1045 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1047 memset(cd_buf_actual, 0, size);
1049 // Actual call
1050 cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
1051 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1052 cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1053 cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1054 cd_buf_actual->SetupPacket.wIndex = i;
1055 cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1057 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1058 cd_buf_actual, size, &ret_size, NULL)) {
1059 usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1060 LOOP_BREAK(LIBUSB_ERROR_IO);
1063 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1065 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1066 usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1067 LOOP_BREAK(LIBUSB_ERROR_IO);
1070 if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1071 usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1072 LOOP_BREAK(LIBUSB_ERROR_IO);
1075 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1076 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1078 // Cache the descriptor
1079 priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1080 if (priv->config_descriptor[i] == NULL)
1081 return LIBUSB_ERROR_NO_MEM;
1082 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1084 return LIBUSB_SUCCESS;
1088 * Populate a libusbx device structure
1090 static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1091 uint8_t port_number, char* device_id, DWORD devinst)
1093 HANDLE handle;
1094 DWORD size;
1095 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1096 struct windows_device_priv *priv, *parent_priv;
1097 struct libusb_context *ctx = DEVICE_CTX(dev);
1098 struct libusb_device* tmp_dev;
1099 unsigned i;
1101 if ((dev == NULL) || (parent_dev == NULL)) {
1102 return LIBUSB_ERROR_NOT_FOUND;
1104 priv = _device_priv(dev);
1105 parent_priv = _device_priv(parent_dev);
1106 if (parent_priv->apib->id != USB_API_HUB) {
1107 usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1108 return LIBUSB_ERROR_NOT_FOUND;
1111 // It is possible for the parent hub not to have been initialized yet
1112 // If that's the case, lookup the ancestors to set the bus number
1113 if (parent_dev->bus_number == 0) {
1114 for (i=2; ; i++) {
1115 tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
1116 if (tmp_dev == NULL) break;
1117 if (tmp_dev->bus_number != 0) {
1118 usbi_dbg("got bus number from ancestor #%d", i);
1119 parent_dev->bus_number = tmp_dev->bus_number;
1120 libusb_unref_device(tmp_dev);
1121 break;
1123 libusb_unref_device(tmp_dev);
1126 if (parent_dev->bus_number == 0) {
1127 usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1128 return LIBUSB_ERROR_NOT_FOUND;
1130 dev->bus_number = parent_dev->bus_number;
1131 priv->port = port_number;
1132 dev->port_number = port_number;
1133 priv->depth = parent_priv->depth + 1;
1134 priv->parent_dev = parent_dev;
1135 dev->parent_dev = parent_dev;
1137 // If the device address is already set, we can stop here
1138 if (dev->device_address != 0) {
1139 return LIBUSB_SUCCESS;
1141 memset(&conn_info, 0, sizeof(conn_info));
1142 if (priv->depth != 0) { // Not a HCD hub
1143 handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1144 FILE_FLAG_OVERLAPPED, NULL);
1145 if (handle == INVALID_HANDLE_VALUE) {
1146 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1147 return LIBUSB_ERROR_ACCESS;
1149 size = sizeof(conn_info);
1150 conn_info.ConnectionIndex = (ULONG)port_number;
1151 if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1152 &conn_info, size, &size, NULL)) {
1153 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1154 device_id, windows_error_str(0));
1155 safe_closehandle(handle);
1156 return LIBUSB_ERROR_NO_DEVICE;
1158 if (conn_info.ConnectionStatus == NoDeviceConnected) {
1159 usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1160 safe_closehandle(handle);
1161 return LIBUSB_ERROR_NO_DEVICE;
1163 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1164 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1165 priv->active_config = conn_info.CurrentConfigurationValue;
1166 usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1167 // If we can't read the config descriptors, just set the number of confs to zero
1168 if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1169 dev->num_configurations = 0;
1170 priv->dev_descriptor.bNumConfigurations = 0;
1172 safe_closehandle(handle);
1174 if (conn_info.DeviceAddress > UINT8_MAX) {
1175 usbi_err(ctx, "program assertion failed: device address overflow");
1177 dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1178 if (dev->device_address == 1) {
1179 usbi_err(ctx, "program assertion failed: device address collision with root hub");
1181 switch (conn_info.Speed) {
1182 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1183 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1184 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1185 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1186 default:
1187 usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1188 break;
1190 } else {
1191 dev->device_address = 1; // root hubs are set to use device number 1
1192 force_hcd_device_descriptor(dev);
1195 usbi_sanitize_device(dev);
1197 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1198 dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1200 return LIBUSB_SUCCESS;
1203 // Returns the api type, or 0 if not found/unsupported
1204 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1205 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1207 // Precedence for filter drivers vs driver is in the order of this array
1208 struct driver_lookup lookup[3] = {
1209 {"\0\0", SPDRP_SERVICE, "driver"},
1210 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1211 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1213 DWORD size, reg_type;
1214 unsigned k, l;
1215 int i, j;
1217 *api = USB_API_UNSUPPORTED;
1218 *sub_api = SUB_API_NOTSET;
1219 // Check the service & filter names to know the API we should use
1220 for (k=0; k<3; k++) {
1221 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1222 &reg_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1223 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1224 if (lookup[k].reg_prop == SPDRP_SERVICE) {
1225 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1226 lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1228 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1229 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1230 // (currently ';'), so even if an unsuported one does, it's not an issue
1231 for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1232 if (lookup[k].list[l] == 0) {
1233 lookup[k].list[l] = LIST_SEPARATOR;
1236 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1237 } else {
1238 if (GetLastError() != ERROR_INVALID_DATA) {
1239 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1241 lookup[k].list[0] = 0;
1245 for (i=1; i<USB_API_MAX; i++) {
1246 for (k=0; k<3; k++) {
1247 j = get_sub_api(lookup[k].list, i);
1248 if (j >= 0) {
1249 usbi_dbg("matched %s name against %s API",
1250 lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1251 *api = i;
1252 *sub_api = j;
1253 return;
1259 static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1260 char* dev_interface_path, char* device_id, int api, int sub_api)
1262 unsigned i;
1263 struct windows_device_priv *priv = _device_priv(dev);
1264 int interface_number;
1266 if (priv->apib->id != USB_API_COMPOSITE) {
1267 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1268 return LIBUSB_ERROR_NO_DEVICE;
1271 // Because MI_## are not necessarily in sequential order (some composite
1272 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1273 // interface number from the path's MI value
1274 interface_number = 0;
1275 for (i=0; device_id[i] != 0; ) {
1276 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1277 && (device_id[i++] == '_') ) {
1278 interface_number = (device_id[i++] - '0')*10;
1279 interface_number += device_id[i] - '0';
1280 break;
1284 if (device_id[i] == 0) {
1285 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1286 device_id, interface_number);
1289 if (priv->usb_interface[interface_number].path != NULL) {
1290 if (api == USB_API_HID) {
1291 // HID devices can have multiple collections (COL##) for each MI_## interface
1292 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1293 interface_number, device_id);
1294 return LIBUSB_ERROR_ACCESS;
1296 // In other cases, just use the latest data
1297 safe_free(priv->usb_interface[interface_number].path);
1300 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1301 priv->usb_interface[interface_number].path = dev_interface_path;
1302 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1303 priv->usb_interface[interface_number].sub_api = sub_api;
1304 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1305 priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
1306 if (priv->hid == NULL)
1307 return LIBUSB_ERROR_NO_MEM;
1310 return LIBUSB_SUCCESS;
1313 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1314 char* dev_interface_path)
1316 int i;
1317 struct windows_device_priv *priv = _device_priv(dev);
1319 if (priv->hid == NULL) {
1320 usbi_err(ctx, "program assertion failed: parent is not HID");
1321 return LIBUSB_ERROR_NO_DEVICE;
1323 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1324 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1325 return LIBUSB_ERROR_NO_DEVICE;
1327 for (i=0; i<priv->hid->nb_interfaces; i++) {
1328 if (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
1329 usbi_dbg("interface[%d] already set to %s", i, dev_interface_path);
1330 return LIBUSB_SUCCESS;
1334 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1335 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1336 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1337 priv->hid->nb_interfaces++;
1338 return LIBUSB_SUCCESS;
1342 * get_device_list: libusbx backend device enumeration function
1344 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1346 struct discovered_devs *discdevs;
1347 HDEVINFO dev_info = { 0 };
1348 const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1349 SP_DEVINFO_DATA dev_info_data = { 0 };
1350 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1351 GUID hid_guid;
1352 #define MAX_ENUM_GUIDS 64
1353 const GUID* guid[MAX_ENUM_GUIDS];
1354 #define HCD_PASS 0
1355 #define HUB_PASS 1
1356 #define GEN_PASS 2
1357 #define DEV_PASS 3
1358 #define HID_PASS 4
1359 int r = LIBUSB_SUCCESS;
1360 int api, sub_api;
1361 size_t class_index = 0;
1362 unsigned int nb_guids, pass, i, j, ancestor;
1363 char path[MAX_PATH_LENGTH];
1364 char strbuf[MAX_PATH_LENGTH];
1365 struct libusb_device *dev, *parent_dev;
1366 struct windows_device_priv *priv, *parent_priv;
1367 char* dev_interface_path = NULL;
1368 char* dev_id_path = NULL;
1369 unsigned long session_id;
1370 DWORD size, reg_type, port_nr, install_state;
1371 HKEY key;
1372 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1373 GUID* if_guid;
1374 LONG s;
1375 // Keep a list of newly allocated devs to unref
1376 libusb_device** unref_list;
1377 unsigned int unref_size = 64;
1378 unsigned int unref_cur = 0;
1380 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1381 // PASS 2 : (re)enumerate HUBS
1382 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1383 // and list additional USB device interface GUIDs to explore
1384 // PASS 4 : (re)enumerate master USB devices that have a device interface
1385 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1386 // set the device interfaces.
1388 // Init the GUID table
1389 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1390 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1391 guid[GEN_PASS] = NULL;
1392 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1393 HidD_GetHidGuid(&hid_guid);
1394 guid[HID_PASS] = &hid_guid;
1395 nb_guids = HID_PASS+1;
1397 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1398 if (unref_list == NULL) {
1399 return LIBUSB_ERROR_NO_MEM;
1402 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1403 //#define ENUM_DEBUG
1404 #ifdef ENUM_DEBUG
1405 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1406 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1407 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1408 #endif
1409 for (i = 0; ; i++) {
1410 // safe loop: free up any (unprotected) dynamic resource
1411 // NB: this is always executed before breaking the loop
1412 safe_free(dev_interface_details);
1413 safe_free(dev_interface_path);
1414 safe_free(dev_id_path);
1415 priv = parent_priv = NULL;
1416 dev = parent_dev = NULL;
1418 // Safe loop: end of loop conditions
1419 if (r != LIBUSB_SUCCESS) {
1420 break;
1422 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1423 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1424 break;
1426 if (pass != GEN_PASS) {
1427 // Except for GEN, all passes deal with device interfaces
1428 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1429 if (dev_interface_details == NULL) {
1430 break;
1431 } else {
1432 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1433 if (dev_interface_path == NULL) {
1434 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1435 continue;
1438 } else {
1439 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1440 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1441 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1442 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1443 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1444 break;
1445 i = 0;
1447 if (class_index >= ARRAYSIZE(usb_class))
1448 break;
1451 // Read the Device ID path. This is what we'll use as UID
1452 // Note that if the device is plugged in a different port or hub, the Device ID changes
1453 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1454 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1455 dev_info_data.DevInst);
1456 continue;
1458 dev_id_path = sanitize_path(path);
1459 if (dev_id_path == NULL) {
1460 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1461 dev_info_data.DevInst);
1462 continue;
1464 #ifdef ENUM_DEBUG
1465 usbi_dbg("PRO: %s", dev_id_path);
1466 #endif
1468 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1469 port_nr = 0;
1470 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1471 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1472 &reg_type, (BYTE*)&port_nr, 4, &size))
1473 || (size != 4) ) {
1474 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1475 dev_id_path, windows_error_str(0));
1476 continue;
1480 // Set API to use or get additional data from generic pass
1481 api = USB_API_UNSUPPORTED;
1482 sub_api = SUB_API_NOTSET;
1483 switch (pass) {
1484 case HCD_PASS:
1485 break;
1486 case GEN_PASS:
1487 // We use the GEN pass to detect driverless devices...
1488 size = sizeof(strbuf);
1489 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1490 &reg_type, (BYTE*)strbuf, size, &size)) {
1491 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1492 usbi_info(ctx, "libusbx will not be able to access it.");
1494 // ...and to add the additional device interface GUIDs
1495 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1496 if (key != INVALID_HANDLE_VALUE) {
1497 size = sizeof(guid_string_w);
1498 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, &reg_type,
1499 (BYTE*)guid_string_w, &size);
1500 pRegCloseKey(key);
1501 if (s == ERROR_SUCCESS) {
1502 if (nb_guids >= MAX_ENUM_GUIDS) {
1503 // If this assert is ever reported, grow a GUID table dynamically
1504 usbi_err(ctx, "program assertion failed: too many GUIDs");
1505 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1507 if_guid = (GUID*) calloc(1, sizeof(GUID));
1508 pCLSIDFromString(guid_string_w, if_guid);
1509 guid[nb_guids++] = if_guid;
1510 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1513 break;
1514 case HID_PASS:
1515 api = USB_API_HID;
1516 break;
1517 default:
1518 // Get the API type (after checking that the driver installation is OK)
1519 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1520 &reg_type, (BYTE*)&install_state, 4, &size))
1521 || (size != 4) ){
1522 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1523 dev_id_path, windows_error_str(0));
1524 } else if (install_state != 0) {
1525 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1526 dev_id_path, install_state);
1527 continue;
1529 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1530 break;
1533 // Find parent device (for the passes that need it)
1534 switch (pass) {
1535 case HCD_PASS:
1536 case DEV_PASS:
1537 case HUB_PASS:
1538 break;
1539 default:
1540 // Go through the ancestors until we see a face we recognize
1541 parent_dev = NULL;
1542 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1543 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1544 if (session_id == 0) {
1545 break;
1547 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1549 if (parent_dev == NULL) {
1550 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1551 continue;
1553 parent_priv = _device_priv(parent_dev);
1554 // virtual USB devices are also listed during GEN - don't process these yet
1555 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1556 libusb_unref_device(parent_dev);
1557 continue;
1559 break;
1562 // Create new or match existing device, using the (hashed) device_id as session id
1563 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1564 // These are the passes that create "new" devices
1565 session_id = htab_hash(dev_id_path);
1566 dev = usbi_get_device_by_session_id(ctx, session_id);
1567 if (dev == NULL) {
1568 if (pass == DEV_PASS) {
1569 // This can occur if the OS only reports a newly plugged device after we started enum
1570 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1571 " - ignoring", dev_id_path);
1572 continue;
1574 usbi_dbg("allocating new device for session [%X]", session_id);
1575 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1576 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1578 windows_device_priv_init(dev);
1579 } else {
1580 usbi_dbg("found existing device for session [%X] (%d.%d)",
1581 session_id, dev->bus_number, dev->device_address);
1583 // Keep track of devices that need unref
1584 unref_list[unref_cur++] = dev;
1585 if (unref_cur >= unref_size) {
1586 unref_size += 64;
1587 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1588 if (unref_list == NULL) {
1589 usbi_err(ctx, "could not realloc list for unref - aborting.");
1590 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1593 priv = _device_priv(dev);
1596 // Setup device
1597 switch (pass) {
1598 case HCD_PASS:
1599 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1600 dev->device_address = 0;
1601 dev->num_configurations = 0;
1602 priv->apib = &usb_api_backend[USB_API_HUB];
1603 priv->sub_api = SUB_API_NOTSET;
1604 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1605 priv->path = dev_interface_path; dev_interface_path = NULL;
1606 break;
1607 case HUB_PASS:
1608 case DEV_PASS:
1609 // If the device has already been setup, don't do it again
1610 if (priv->path != NULL)
1611 break;
1612 // Take care of API initialization
1613 priv->path = dev_interface_path; dev_interface_path = NULL;
1614 priv->apib = &usb_api_backend[api];
1615 priv->sub_api = sub_api;
1616 switch(api) {
1617 case USB_API_COMPOSITE:
1618 case USB_API_HUB:
1619 break;
1620 case USB_API_HID:
1621 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1622 if (priv->hid == NULL) {
1623 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1625 priv->hid->nb_interfaces = 0;
1626 break;
1627 default:
1628 // For other devices, the first interface is the same as the device
1629 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1630 if (priv->usb_interface[0].path != NULL) {
1631 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1632 } else {
1633 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1635 // The following is needed if we want API calls to work for both simple
1636 // and composite devices.
1637 for(j=0; j<USB_MAXINTERFACES; j++) {
1638 priv->usb_interface[j].apib = &usb_api_backend[api];
1640 break;
1642 break;
1643 case GEN_PASS:
1644 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1645 if (r == LIBUSB_SUCCESS) {
1646 // Append device to the list of discovered devices
1647 discdevs = discovered_devs_append(*_discdevs, dev);
1648 if (!discdevs) {
1649 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1651 *_discdevs = discdevs;
1652 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1653 // This can occur if the device was disconnected but Windows hasn't
1654 // refreshed its enumeration yet - in that case, we ignore the device
1655 r = LIBUSB_SUCCESS;
1657 break;
1658 default: // HID_PASS and later
1659 if (parent_priv->apib->id == USB_API_HID) {
1660 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1661 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1662 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1663 dev_interface_path = NULL;
1664 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1665 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1666 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1667 case LIBUSB_SUCCESS:
1668 dev_interface_path = NULL;
1669 break;
1670 case LIBUSB_ERROR_ACCESS:
1671 // interface has already been set => make sure dev_interface_path is freed then
1672 break;
1673 default:
1674 LOOP_BREAK(r);
1675 break;
1678 libusb_unref_device(parent_dev);
1679 break;
1684 // Free any additional GUIDs
1685 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1686 safe_free(guid[pass]);
1689 // Unref newly allocated devs
1690 for (i=0; i<unref_cur; i++) {
1691 safe_unref_device(unref_list[i]);
1693 safe_free(unref_list);
1695 return r;
1699 * exit: libusbx backend deinitialization function
1701 static void windows_exit(void)
1703 int i;
1704 HANDLE semaphore;
1705 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1707 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1708 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1709 if (semaphore == NULL) {
1710 return;
1713 // A successful wait brings our semaphore count to 0 (unsignaled)
1714 // => any concurent wait stalls until the semaphore release
1715 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1716 CloseHandle(semaphore);
1717 return;
1720 // Only works if exits and inits are balanced exactly
1721 if (--concurrent_usage < 0) { // Last exit
1722 for (i=0; i<USB_API_MAX; i++) {
1723 usb_api_backend[i].exit(SUB_API_NOTSET);
1725 exit_polling();
1727 if (timer_thread) {
1728 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1729 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1730 usbi_dbg("could not wait for timer thread to quit");
1731 TerminateThread(timer_thread, 1);
1733 CloseHandle(timer_thread);
1734 timer_thread = NULL;
1736 for (i = 0; i < 2; i++) {
1737 if (timer_request[i]) {
1738 CloseHandle(timer_request[i]);
1739 timer_request[i] = NULL;
1742 if (timer_response) {
1743 CloseHandle(timer_response);
1744 timer_response = NULL;
1746 if (timer_mutex) {
1747 CloseHandle(timer_mutex);
1748 timer_mutex = NULL;
1750 htab_destroy();
1753 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1754 CloseHandle(semaphore);
1757 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1759 struct windows_device_priv *priv = _device_priv(dev);
1761 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1762 *host_endian = 0;
1764 return LIBUSB_SUCCESS;
1767 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1769 struct windows_device_priv *priv = _device_priv(dev);
1770 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1771 size_t size;
1773 // config index is zero based
1774 if (config_index >= dev->num_configurations)
1775 return LIBUSB_ERROR_INVALID_PARAM;
1777 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1778 return LIBUSB_ERROR_NOT_FOUND;
1780 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1782 size = min(config_header->wTotalLength, len);
1783 memcpy(buffer, priv->config_descriptor[config_index], size);
1784 *host_endian = 0;
1786 return (int)size;
1790 * return the cached copy of the active config descriptor
1792 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1794 struct windows_device_priv *priv = _device_priv(dev);
1796 if (priv->active_config == 0)
1797 return LIBUSB_ERROR_NOT_FOUND;
1799 // config index is zero based
1800 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1803 static int windows_open(struct libusb_device_handle *dev_handle)
1805 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1806 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1808 if (priv->apib == NULL) {
1809 usbi_err(ctx, "program assertion failed - device is not initialized");
1810 return LIBUSB_ERROR_NO_DEVICE;
1813 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1816 static void windows_close(struct libusb_device_handle *dev_handle)
1818 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1820 priv->apib->close(SUB_API_NOTSET, dev_handle);
1823 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1825 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1827 if (priv->active_config == 0) {
1828 *config = 0;
1829 return LIBUSB_ERROR_NOT_FOUND;
1832 *config = priv->active_config;
1833 return LIBUSB_SUCCESS;
1837 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1838 * does not currently expose a service that allows higher-level drivers to set
1839 * the configuration."
1841 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1843 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1844 int r = LIBUSB_SUCCESS;
1846 if (config >= USB_MAXCONFIG)
1847 return LIBUSB_ERROR_INVALID_PARAM;
1849 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1850 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1851 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1852 0, NULL, 0, 1000);
1854 if (r == LIBUSB_SUCCESS) {
1855 priv->active_config = (uint8_t)config;
1857 return r;
1860 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1862 int r = LIBUSB_SUCCESS;
1863 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1865 if (iface >= USB_MAXINTERFACES)
1866 return LIBUSB_ERROR_INVALID_PARAM;
1868 safe_free(priv->usb_interface[iface].endpoint);
1869 priv->usb_interface[iface].nb_endpoints= 0;
1871 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1873 if (r == LIBUSB_SUCCESS) {
1874 r = windows_assign_endpoints(dev_handle, iface, 0);
1877 return r;
1880 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1882 int r = LIBUSB_SUCCESS;
1883 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1885 safe_free(priv->usb_interface[iface].endpoint);
1886 priv->usb_interface[iface].nb_endpoints= 0;
1888 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1890 if (r == LIBUSB_SUCCESS) {
1891 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1894 return r;
1897 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1899 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1901 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1904 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1906 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1907 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1910 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1912 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1913 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1916 // The 3 functions below are unlikely to ever get supported on Windows
1917 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1919 return LIBUSB_ERROR_NOT_SUPPORTED;
1922 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1924 return LIBUSB_ERROR_NOT_SUPPORTED;
1927 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1929 return LIBUSB_ERROR_NOT_SUPPORTED;
1932 static void windows_destroy_device(struct libusb_device *dev)
1934 windows_device_priv_release(dev);
1937 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1939 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1941 usbi_free_fd(&transfer_priv->pollable_fd);
1942 safe_free(transfer_priv->hid_buffer);
1943 // When auto claim is in use, attempt to release the auto-claimed interface
1944 auto_release(itransfer);
1947 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1949 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1950 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1951 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1952 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1953 int r;
1955 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1956 if (r != LIBUSB_SUCCESS) {
1957 return r;
1960 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1961 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1963 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1964 return LIBUSB_SUCCESS;
1967 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1969 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1970 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1971 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1972 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1973 int r;
1975 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1976 if (r != LIBUSB_SUCCESS) {
1977 return r;
1980 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1981 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1983 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1984 return LIBUSB_SUCCESS;
1987 static int submit_control_transfer(struct usbi_transfer *itransfer)
1989 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1990 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1991 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1992 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1993 int r;
1995 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1996 if (r != LIBUSB_SUCCESS) {
1997 return r;
2000 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
2002 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
2003 return LIBUSB_SUCCESS;
2007 static int windows_submit_transfer(struct usbi_transfer *itransfer)
2009 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2011 switch (transfer->type) {
2012 case LIBUSB_TRANSFER_TYPE_CONTROL:
2013 return submit_control_transfer(itransfer);
2014 case LIBUSB_TRANSFER_TYPE_BULK:
2015 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2016 if (IS_XFEROUT(transfer) &&
2017 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
2018 return LIBUSB_ERROR_NOT_SUPPORTED;
2019 return submit_bulk_transfer(itransfer);
2020 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2021 return submit_iso_transfer(itransfer);
2022 default:
2023 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2024 return LIBUSB_ERROR_INVALID_PARAM;
2028 static int windows_abort_control(struct usbi_transfer *itransfer)
2030 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2031 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2033 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2036 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2038 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2039 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2041 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2044 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2046 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2048 switch (transfer->type) {
2049 case LIBUSB_TRANSFER_TYPE_CONTROL:
2050 return windows_abort_control(itransfer);
2051 case LIBUSB_TRANSFER_TYPE_BULK:
2052 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2053 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2054 return windows_abort_transfers(itransfer);
2055 default:
2056 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2057 return LIBUSB_ERROR_INVALID_PARAM;
2061 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2063 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2064 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2065 int status, istatus;
2067 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
2069 switch(io_result) {
2070 case NO_ERROR:
2071 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2072 break;
2073 case ERROR_GEN_FAILURE:
2074 usbi_dbg("detected endpoint stall");
2075 status = LIBUSB_TRANSFER_STALL;
2076 break;
2077 case ERROR_SEM_TIMEOUT:
2078 usbi_dbg("detected semaphore timeout");
2079 status = LIBUSB_TRANSFER_TIMED_OUT;
2080 break;
2081 case ERROR_OPERATION_ABORTED:
2082 istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2083 if (istatus != LIBUSB_TRANSFER_COMPLETED) {
2084 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
2086 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2087 usbi_dbg("detected timeout");
2088 status = LIBUSB_TRANSFER_TIMED_OUT;
2089 } else {
2090 usbi_dbg("detected operation aborted");
2091 status = LIBUSB_TRANSFER_CANCELLED;
2093 break;
2094 default:
2095 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(io_result));
2096 status = LIBUSB_TRANSFER_ERROR;
2097 break;
2099 windows_clear_transfer_priv(itransfer); // Cancel polling
2100 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2103 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2105 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2107 switch (transfer->type) {
2108 case LIBUSB_TRANSFER_TYPE_CONTROL:
2109 case LIBUSB_TRANSFER_TYPE_BULK:
2110 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2111 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2112 windows_transfer_callback (itransfer, io_result, io_size);
2113 break;
2114 default:
2115 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2119 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2121 struct windows_transfer_priv* transfer_priv = NULL;
2122 POLL_NFDS_TYPE i = 0;
2123 bool found = false;
2124 struct usbi_transfer *transfer;
2125 DWORD io_size, io_result;
2127 usbi_mutex_lock(&ctx->open_devs_lock);
2128 for (i = 0; i < nfds && num_ready > 0; i++) {
2130 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2132 if (!fds[i].revents) {
2133 continue;
2136 num_ready--;
2138 // Because a Windows OVERLAPPED is used for poll emulation,
2139 // a pollable fd is created and stored with each transfer
2140 usbi_mutex_lock(&ctx->flying_transfers_lock);
2141 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2142 transfer_priv = usbi_transfer_get_os_priv(transfer);
2143 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2144 found = true;
2145 break;
2148 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2150 if (found) {
2151 // Handle async requests that completed synchronously first
2152 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2153 io_result = NO_ERROR;
2154 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2155 // Regular async overlapped
2156 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2157 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2158 io_result = NO_ERROR;
2159 } else {
2160 io_result = GetLastError();
2162 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2163 // let handle_callback free the event using the transfer wfd
2164 // If you don't use the transfer wfd, you run a risk of trying to free a
2165 // newly allocated wfd that took the place of the one from the transfer.
2166 windows_handle_callback(transfer, io_result, io_size);
2167 } else {
2168 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2169 return LIBUSB_ERROR_NOT_FOUND;
2173 usbi_mutex_unlock(&ctx->open_devs_lock);
2174 return LIBUSB_SUCCESS;
2178 * Monotonic and real time functions
2180 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2182 LARGE_INTEGER hires_counter, li_frequency;
2183 LONG nb_responses;
2184 int timer_index;
2186 // Init - find out if we have access to a monotonic (hires) timer
2187 if (!QueryPerformanceFrequency(&li_frequency)) {
2188 usbi_dbg("no hires timer available on this platform");
2189 hires_frequency = 0;
2190 hires_ticks_to_ps = UINT64_C(0);
2191 } else {
2192 hires_frequency = li_frequency.QuadPart;
2193 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2194 // to picoseconds to compute the tv_nsecs part in clock_gettime
2195 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2196 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2199 // Signal windows_init() that we're ready to service requests
2200 if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
2201 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2204 // Main loop - wait for requests
2205 while (1) {
2206 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2207 if ( (timer_index != 0) && (timer_index != 1) ) {
2208 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2209 continue;
2211 if (request_count[timer_index] == 0) {
2212 // Request already handled
2213 ResetEvent(timer_request[timer_index]);
2214 // There's still a possiblity that a thread sends a request between the
2215 // time we test request_count[] == 0 and we reset the event, in which case
2216 // the request would be ignored. The simple solution to that is to test
2217 // request_count again and process requests if non zero.
2218 if (request_count[timer_index] == 0)
2219 continue;
2221 switch (timer_index) {
2222 case 0:
2223 WaitForSingleObject(timer_mutex, INFINITE);
2224 // Requests to this thread are for hires always
2225 if (QueryPerformanceCounter(&hires_counter) != 0) {
2226 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2227 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2228 } else {
2229 // Fallback to real-time if we can't get monotonic value
2230 // Note that real-time clock does not wait on the mutex or this thread.
2231 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2233 ReleaseMutex(timer_mutex);
2235 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2236 if ( (nb_responses)
2237 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2238 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2240 continue;
2241 case 1: // time to quit
2242 usbi_dbg("timer thread quitting");
2243 return 0;
2248 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2250 FILETIME filetime;
2251 ULARGE_INTEGER rtime;
2252 DWORD r;
2253 switch(clk_id) {
2254 case USBI_CLOCK_MONOTONIC:
2255 if (hires_frequency != 0) {
2256 while (1) {
2257 InterlockedIncrement((LONG*)&request_count[0]);
2258 SetEvent(timer_request[0]);
2259 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2260 switch(r) {
2261 case WAIT_OBJECT_0:
2262 WaitForSingleObject(timer_mutex, INFINITE);
2263 *tp = timer_tp;
2264 ReleaseMutex(timer_mutex);
2265 return LIBUSB_SUCCESS;
2266 case WAIT_TIMEOUT:
2267 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2268 break; // Retry until successful
2269 default:
2270 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2271 return LIBUSB_ERROR_OTHER;
2275 // Fall through and return real-time if monotonic was not detected @ timer init
2276 case USBI_CLOCK_REALTIME:
2277 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2278 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2279 // Note however that our resolution is bounded by the Windows system time
2280 // functions and is at best of the order of 1 ms (or, usually, worse)
2281 GetSystemTimeAsFileTime(&filetime);
2282 rtime.LowPart = filetime.dwLowDateTime;
2283 rtime.HighPart = filetime.dwHighDateTime;
2284 rtime.QuadPart -= epoch_time;
2285 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2286 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2287 return LIBUSB_SUCCESS;
2288 default:
2289 return LIBUSB_ERROR_INVALID_PARAM;
2294 // NB: MSVC6 does not support named initializers.
2295 const struct usbi_os_backend windows_backend = {
2296 "Windows",
2297 USBI_CAP_HAS_HID_ACCESS,
2298 windows_init,
2299 windows_exit,
2301 windows_get_device_list,
2302 NULL, /* hotplug_poll */
2303 windows_open,
2304 windows_close,
2306 windows_get_device_descriptor,
2307 windows_get_active_config_descriptor,
2308 windows_get_config_descriptor,
2309 NULL, /* get_config_descriptor_by_value() */
2311 windows_get_configuration,
2312 windows_set_configuration,
2313 windows_claim_interface,
2314 windows_release_interface,
2316 windows_set_interface_altsetting,
2317 windows_clear_halt,
2318 windows_reset_device,
2320 windows_kernel_driver_active,
2321 windows_detach_kernel_driver,
2322 windows_attach_kernel_driver,
2324 windows_destroy_device,
2326 windows_submit_transfer,
2327 windows_cancel_transfer,
2328 windows_clear_transfer_priv,
2330 windows_handle_events,
2332 windows_clock_gettime,
2333 #if defined(USBI_TIMERFD_AVAILABLE)
2334 NULL,
2335 #endif
2336 sizeof(struct windows_device_priv),
2337 sizeof(struct windows_device_handle_priv),
2338 sizeof(struct windows_transfer_priv),
2344 * USB API backends
2346 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2347 return LIBUSB_SUCCESS;
2349 static int unsupported_exit(int sub_api) {
2350 return LIBUSB_SUCCESS;
2352 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2353 PRINT_UNSUPPORTED_API(open);
2355 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2356 usbi_dbg("unsupported API call for 'close'");
2358 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2359 PRINT_UNSUPPORTED_API(configure_endpoints);
2361 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2362 PRINT_UNSUPPORTED_API(claim_interface);
2364 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2365 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2367 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2368 PRINT_UNSUPPORTED_API(release_interface);
2370 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2371 PRINT_UNSUPPORTED_API(clear_halt);
2373 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2374 PRINT_UNSUPPORTED_API(reset_device);
2376 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2377 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2379 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2380 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2382 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2383 PRINT_UNSUPPORTED_API(submit_control_transfer);
2385 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2386 PRINT_UNSUPPORTED_API(abort_control);
2388 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2389 PRINT_UNSUPPORTED_API(abort_transfers);
2391 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2392 PRINT_UNSUPPORTED_API(copy_transfer_data);
2394 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2395 return LIBUSB_SUCCESS;
2397 // These names must be uppercase
2398 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB", "VUSB3HUB"};
2399 const char* composite_driver_names[] = {"USBCCGP"};
2400 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2401 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2402 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2404 USB_API_UNSUPPORTED,
2405 "Unsupported API",
2406 NULL,
2408 unsupported_init,
2409 unsupported_exit,
2410 unsupported_open,
2411 unsupported_close,
2412 unsupported_configure_endpoints,
2413 unsupported_claim_interface,
2414 unsupported_set_interface_altsetting,
2415 unsupported_release_interface,
2416 unsupported_clear_halt,
2417 unsupported_reset_device,
2418 unsupported_submit_bulk_transfer,
2419 unsupported_submit_iso_transfer,
2420 unsupported_submit_control_transfer,
2421 unsupported_abort_control,
2422 unsupported_abort_transfers,
2423 unsupported_copy_transfer_data,
2424 }, {
2425 USB_API_HUB,
2426 "HUB API",
2427 hub_driver_names,
2428 ARRAYSIZE(hub_driver_names),
2429 unsupported_init,
2430 unsupported_exit,
2431 unsupported_open,
2432 unsupported_close,
2433 unsupported_configure_endpoints,
2434 unsupported_claim_interface,
2435 unsupported_set_interface_altsetting,
2436 unsupported_release_interface,
2437 unsupported_clear_halt,
2438 unsupported_reset_device,
2439 unsupported_submit_bulk_transfer,
2440 unsupported_submit_iso_transfer,
2441 unsupported_submit_control_transfer,
2442 unsupported_abort_control,
2443 unsupported_abort_transfers,
2444 unsupported_copy_transfer_data,
2445 }, {
2446 USB_API_COMPOSITE,
2447 "Composite API",
2448 composite_driver_names,
2449 ARRAYSIZE(composite_driver_names),
2450 composite_init,
2451 composite_exit,
2452 composite_open,
2453 composite_close,
2454 common_configure_endpoints,
2455 composite_claim_interface,
2456 composite_set_interface_altsetting,
2457 composite_release_interface,
2458 composite_clear_halt,
2459 composite_reset_device,
2460 composite_submit_bulk_transfer,
2461 composite_submit_iso_transfer,
2462 composite_submit_control_transfer,
2463 composite_abort_control,
2464 composite_abort_transfers,
2465 composite_copy_transfer_data,
2466 }, {
2467 USB_API_WINUSBX,
2468 "WinUSB-like APIs",
2469 winusbx_driver_names,
2470 ARRAYSIZE(winusbx_driver_names),
2471 winusbx_init,
2472 winusbx_exit,
2473 winusbx_open,
2474 winusbx_close,
2475 winusbx_configure_endpoints,
2476 winusbx_claim_interface,
2477 winusbx_set_interface_altsetting,
2478 winusbx_release_interface,
2479 winusbx_clear_halt,
2480 winusbx_reset_device,
2481 winusbx_submit_bulk_transfer,
2482 unsupported_submit_iso_transfer,
2483 winusbx_submit_control_transfer,
2484 winusbx_abort_control,
2485 winusbx_abort_transfers,
2486 winusbx_copy_transfer_data,
2487 }, {
2488 USB_API_HID,
2489 "HID API",
2490 hid_driver_names,
2491 ARRAYSIZE(hid_driver_names),
2492 hid_init,
2493 hid_exit,
2494 hid_open,
2495 hid_close,
2496 common_configure_endpoints,
2497 hid_claim_interface,
2498 hid_set_interface_altsetting,
2499 hid_release_interface,
2500 hid_clear_halt,
2501 hid_reset_device,
2502 hid_submit_bulk_transfer,
2503 unsupported_submit_iso_transfer,
2504 hid_submit_control_transfer,
2505 hid_abort_transfers,
2506 hid_abort_transfers,
2507 hid_copy_transfer_data,
2513 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2515 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2516 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2518 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2520 HMODULE h = NULL;
2521 bool native_winusb = false;
2522 int i;
2523 KLIB_VERSION LibK_Version;
2524 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2525 LibK_GetVersion_t pLibK_GetVersion = NULL;
2527 h = GetModuleHandleA("libusbK");
2528 if (h == NULL) {
2529 h = LoadLibraryA("libusbK");
2531 if (h == NULL) {
2532 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2533 h = GetModuleHandleA("WinUSB");
2534 if (h == NULL) {
2535 h = LoadLibraryA("WinUSB");
2536 } if (h == NULL) {
2537 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2538 "you will not be able to access devices outside of enumeration");
2539 return LIBUSB_ERROR_NOT_FOUND;
2541 } else {
2542 usbi_dbg("using libusbK DLL for universal access");
2543 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2544 if (pLibK_GetVersion != NULL) {
2545 pLibK_GetVersion(&LibK_Version);
2546 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2547 LibK_Version.Micro, LibK_Version.Nano);
2549 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2550 if (pLibK_GetProcAddress == NULL) {
2551 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2552 return LIBUSB_ERROR_NOT_FOUND;
2555 native_winusb = (pLibK_GetProcAddress == NULL);
2556 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2557 WinUSBX_Set(AbortPipe);
2558 WinUSBX_Set(ControlTransfer);
2559 WinUSBX_Set(FlushPipe);
2560 WinUSBX_Set(Free);
2561 WinUSBX_Set(GetAssociatedInterface);
2562 WinUSBX_Set(GetCurrentAlternateSetting);
2563 WinUSBX_Set(GetDescriptor);
2564 WinUSBX_Set(GetOverlappedResult);
2565 WinUSBX_Set(GetPipePolicy);
2566 WinUSBX_Set(GetPowerPolicy);
2567 WinUSBX_Set(Initialize);
2568 WinUSBX_Set(QueryDeviceInformation);
2569 WinUSBX_Set(QueryInterfaceSettings);
2570 WinUSBX_Set(QueryPipe);
2571 WinUSBX_Set(ReadPipe);
2572 WinUSBX_Set(ResetPipe);
2573 WinUSBX_Set(SetCurrentAlternateSetting);
2574 WinUSBX_Set(SetPipePolicy);
2575 WinUSBX_Set(SetPowerPolicy);
2576 WinUSBX_Set(WritePipe);
2577 if (!native_winusb) {
2578 WinUSBX_Set(ResetDevice);
2580 if (WinUSBX[i].Initialize != NULL) {
2581 WinUSBX[i].initialized = true;
2582 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2583 } else {
2584 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2585 WinUSBX[i].initialized = false;
2588 return LIBUSB_SUCCESS;
2591 static int winusbx_exit(int sub_api)
2593 return LIBUSB_SUCCESS;
2596 // NB: open and close must ensure that they only handle interface of
2597 // the right API type, as these functions can be called wholesale from
2598 // composite_open(), with interfaces belonging to different APIs
2599 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2601 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2602 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2603 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2605 HANDLE file_handle;
2606 int i;
2608 CHECK_WINUSBX_AVAILABLE(sub_api);
2610 // WinUSB requires a seperate handle for each interface
2611 for (i = 0; i < USB_MAXINTERFACES; i++) {
2612 if ( (priv->usb_interface[i].path != NULL)
2613 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2614 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2615 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2616 if (file_handle == INVALID_HANDLE_VALUE) {
2617 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2618 switch(GetLastError()) {
2619 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2620 return LIBUSB_ERROR_NO_DEVICE;
2621 case ERROR_ACCESS_DENIED:
2622 return LIBUSB_ERROR_ACCESS;
2623 default:
2624 return LIBUSB_ERROR_IO;
2627 handle_priv->interface_handle[i].dev_handle = file_handle;
2631 return LIBUSB_SUCCESS;
2634 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2636 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2637 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2638 HANDLE file_handle;
2639 int i;
2641 if (sub_api == SUB_API_NOTSET)
2642 sub_api = priv->sub_api;
2643 if (!WinUSBX[sub_api].initialized)
2644 return;
2646 for (i = 0; i < USB_MAXINTERFACES; i++) {
2647 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2648 file_handle = handle_priv->interface_handle[i].dev_handle;
2649 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2650 CloseHandle(file_handle);
2656 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2658 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2659 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2660 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2661 UCHAR policy;
2662 ULONG timeout = 0;
2663 uint8_t endpoint_address;
2664 int i;
2666 CHECK_WINUSBX_AVAILABLE(sub_api);
2668 // With handle and enpoints set (in parent), we can setup the default pipe properties
2669 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2670 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2671 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2672 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2673 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2674 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2676 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2677 continue; // Other policies don't apply to control endpoint or libusb0
2679 policy = false;
2680 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2681 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2682 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2684 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2685 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2686 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2688 policy = true;
2689 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2690 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2691 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2692 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2693 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2695 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2696 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2697 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2701 return LIBUSB_SUCCESS;
2704 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2706 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2707 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2708 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2709 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2710 HANDLE file_handle, winusb_handle;
2711 DWORD err;
2712 int i;
2713 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2714 HDEVINFO dev_info = INVALID_HANDLE_VALUE;
2715 SP_DEVINFO_DATA dev_info_data;
2716 char* dev_path_no_guid = NULL;
2717 char filter_path[] = "\\\\.\\libusb0-0000";
2718 bool found_filter = false;
2720 CHECK_WINUSBX_AVAILABLE(sub_api);
2722 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2723 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2724 if ((is_using_usbccgp) || (iface == 0)) {
2725 // composite device (independent interfaces) or interface 0
2726 file_handle = handle_priv->interface_handle[iface].dev_handle;
2727 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2728 return LIBUSB_ERROR_NOT_FOUND;
2731 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2732 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2733 err = GetLastError();
2734 switch(err) {
2735 case ERROR_BAD_COMMAND:
2736 // The device was disconnected
2737 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2738 return LIBUSB_ERROR_NO_DEVICE;
2739 default:
2740 // it may be that we're using the libusb0 filter driver.
2741 // TODO: can we move this whole business into the K/0 DLL?
2742 for (i = 0; ; i++) {
2743 safe_free(dev_interface_details);
2744 safe_free(dev_path_no_guid);
2745 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2746 if ((found_filter) || (dev_interface_details == NULL)) {
2747 break;
2749 // ignore GUID part
2750 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2751 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2752 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2753 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2754 if (file_handle == INVALID_HANDLE_VALUE) {
2755 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2756 } else {
2757 WinUSBX[sub_api].Free(winusb_handle);
2758 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2759 continue;
2761 found_filter = true;
2762 break;
2766 if (!found_filter) {
2767 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2768 return LIBUSB_ERROR_ACCESS;
2772 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2773 } else {
2774 // For all other interfaces, use GetAssociatedInterface()
2775 winusb_handle = handle_priv->interface_handle[0].api_handle;
2776 // It is a requirement for multiple interface devices on Windows that, to you
2777 // must first claim the first interface before you claim the others
2778 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2779 file_handle = handle_priv->interface_handle[0].dev_handle;
2780 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2781 handle_priv->interface_handle[0].api_handle = winusb_handle;
2782 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2783 } else {
2784 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2785 return LIBUSB_ERROR_ACCESS;
2788 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2789 &handle_priv->interface_handle[iface].api_handle)) {
2790 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2791 switch(GetLastError()) {
2792 case ERROR_NO_MORE_ITEMS: // invalid iface
2793 return LIBUSB_ERROR_NOT_FOUND;
2794 case ERROR_BAD_COMMAND: // The device was disconnected
2795 return LIBUSB_ERROR_NO_DEVICE;
2796 case ERROR_ALREADY_EXISTS: // already claimed
2797 return LIBUSB_ERROR_BUSY;
2798 default:
2799 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2800 return LIBUSB_ERROR_ACCESS;
2804 usbi_dbg("claimed interface %d", iface);
2805 handle_priv->active_interface = iface;
2807 return LIBUSB_SUCCESS;
2810 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2812 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2813 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2814 HANDLE winusb_handle;
2816 CHECK_WINUSBX_AVAILABLE(sub_api);
2818 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2819 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2820 return LIBUSB_ERROR_NOT_FOUND;
2823 WinUSBX[sub_api].Free(winusb_handle);
2824 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2826 return LIBUSB_SUCCESS;
2830 * Return the first valid interface (of the same API type), for control transfers
2832 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2834 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2835 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2836 int i;
2838 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2839 usbi_dbg("unsupported API ID");
2840 return -1;
2843 for (i=0; i<USB_MAXINTERFACES; i++) {
2844 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2845 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2846 && (handle_priv->interface_handle[i].api_handle != 0)
2847 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2848 && (priv->usb_interface[i].apib->id == api_id) ) {
2849 return i;
2852 return -1;
2856 * Lookup interface by endpoint address. -1 if not found
2858 static int interface_by_endpoint(struct windows_device_priv *priv,
2859 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2861 int i, j;
2862 for (i=0; i<USB_MAXINTERFACES; i++) {
2863 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2864 continue;
2865 if (handle_priv->interface_handle[i].api_handle == 0)
2866 continue;
2867 if (priv->usb_interface[i].endpoint == NULL)
2868 continue;
2869 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2870 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2871 return i;
2875 return -1;
2878 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2880 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2881 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2882 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2883 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2884 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2885 transfer->dev_handle);
2886 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2887 ULONG size;
2888 HANDLE winusb_handle;
2889 int current_interface;
2890 struct winfd wfd;
2892 CHECK_WINUSBX_AVAILABLE(sub_api);
2894 transfer_priv->pollable_fd = INVALID_WINFD;
2895 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2897 if (size > MAX_CTRL_BUFFER_LENGTH)
2898 return LIBUSB_ERROR_INVALID_PARAM;
2900 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2901 if (current_interface < 0) {
2902 if (auto_claim(transfer, &current_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2903 return LIBUSB_ERROR_NOT_FOUND;
2907 usbi_dbg("will use interface %d", current_interface);
2908 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2910 wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
2911 // Always use the handle returned from usbi_create_fd (wfd.handle)
2912 if (wfd.fd < 0) {
2913 return LIBUSB_ERROR_NO_MEM;
2916 // Sending of set configuration control requests from WinUSB creates issues
2917 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2918 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2919 if (setup->value != priv->active_config) {
2920 usbi_warn(ctx, "cannot set configuration other than the default one");
2921 usbi_free_fd(&wfd);
2922 return LIBUSB_ERROR_INVALID_PARAM;
2924 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2925 wfd.overlapped->InternalHigh = 0;
2926 } else {
2927 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2928 if(GetLastError() != ERROR_IO_PENDING) {
2929 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2930 usbi_free_fd(&wfd);
2931 return LIBUSB_ERROR_IO;
2933 } else {
2934 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2935 wfd.overlapped->InternalHigh = (DWORD)size;
2939 // Use priv_transfer to store data needed for async polling
2940 transfer_priv->pollable_fd = wfd;
2941 transfer_priv->interface_number = (uint8_t)current_interface;
2943 return LIBUSB_SUCCESS;
2946 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2948 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2949 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2950 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2951 HANDLE winusb_handle;
2953 CHECK_WINUSBX_AVAILABLE(sub_api);
2955 if (altsetting > 255) {
2956 return LIBUSB_ERROR_INVALID_PARAM;
2959 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2960 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2961 usbi_err(ctx, "interface must be claimed first");
2962 return LIBUSB_ERROR_NOT_FOUND;
2965 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2966 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2967 return LIBUSB_ERROR_IO;
2970 return LIBUSB_SUCCESS;
2973 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2975 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2976 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2977 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2978 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2979 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2980 HANDLE winusb_handle;
2981 bool ret;
2982 int current_interface;
2983 struct winfd wfd;
2985 CHECK_WINUSBX_AVAILABLE(sub_api);
2987 transfer_priv->pollable_fd = INVALID_WINFD;
2989 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2990 if (current_interface < 0) {
2991 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2992 return LIBUSB_ERROR_NOT_FOUND;
2995 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2997 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2999 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
3000 // Always use the handle returned from usbi_create_fd (wfd.handle)
3001 if (wfd.fd < 0) {
3002 return LIBUSB_ERROR_NO_MEM;
3005 if (IS_XFERIN(transfer)) {
3006 usbi_dbg("reading %d bytes", transfer->length);
3007 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
3008 } else {
3009 usbi_dbg("writing %d bytes", transfer->length);
3010 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
3012 if (!ret) {
3013 if(GetLastError() != ERROR_IO_PENDING) {
3014 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
3015 usbi_free_fd(&wfd);
3016 return LIBUSB_ERROR_IO;
3018 } else {
3019 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3020 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
3023 transfer_priv->pollable_fd = wfd;
3024 transfer_priv->interface_number = (uint8_t)current_interface;
3026 return LIBUSB_SUCCESS;
3029 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3031 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3032 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3033 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3034 HANDLE winusb_handle;
3035 int current_interface;
3037 CHECK_WINUSBX_AVAILABLE(sub_api);
3039 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3040 if (current_interface < 0) {
3041 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3042 return LIBUSB_ERROR_NOT_FOUND;
3045 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3046 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3048 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3049 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3050 return LIBUSB_ERROR_NO_DEVICE;
3053 return LIBUSB_SUCCESS;
3057 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3058 * through testing as well):
3059 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3060 * the control transfer using CancelIo"
3062 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3064 // Cancelling of the I/O is done in the parent
3065 return LIBUSB_SUCCESS;
3068 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3070 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3071 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3072 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3073 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3074 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3075 HANDLE winusb_handle;
3076 int current_interface;
3078 CHECK_WINUSBX_AVAILABLE(sub_api);
3080 current_interface = transfer_priv->interface_number;
3081 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3082 usbi_err(ctx, "program assertion failed: invalid interface_number");
3083 return LIBUSB_ERROR_NOT_FOUND;
3085 usbi_dbg("will use interface %d", current_interface);
3087 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3089 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3090 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3091 return LIBUSB_ERROR_NO_DEVICE;
3094 return LIBUSB_SUCCESS;
3098 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3099 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3100 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3101 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3102 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3103 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3105 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3106 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3108 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3109 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3110 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3111 struct winfd wfd;
3112 HANDLE winusb_handle;
3113 int i, j;
3115 CHECK_WINUSBX_AVAILABLE(sub_api);
3117 // Reset any available pipe (except control)
3118 for (i=0; i<USB_MAXINTERFACES; i++) {
3119 winusb_handle = handle_priv->interface_handle[i].api_handle;
3120 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3122 // Cancel any pollable I/O
3123 usbi_remove_pollfd(ctx, wfd.fd);
3124 usbi_free_fd(&wfd);
3125 wfd = handle_to_winfd(winusb_handle);
3128 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3129 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3130 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3131 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3132 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3133 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3135 // FlushPipe seems to fail on OUT pipes
3136 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3137 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3138 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3139 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3141 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3142 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3143 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3149 // libusbK & libusb0 have the ability to issue an actual device reset
3150 if (WinUSBX[sub_api].ResetDevice != NULL) {
3151 winusb_handle = handle_priv->interface_handle[0].api_handle;
3152 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3153 WinUSBX[sub_api].ResetDevice(winusb_handle);
3156 return LIBUSB_SUCCESS;
3159 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3161 itransfer->transferred += io_size;
3162 return LIBUSB_TRANSFER_COMPLETED;
3166 * Internal HID Support functions (from libusb-win32)
3167 * Note that functions that complete data transfer synchronously must return
3168 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3170 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3171 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3173 static int _hid_wcslen(WCHAR *str)
3175 int i = 0;
3176 while (str[i] && (str[i] != 0x409)) {
3177 i++;
3179 return i;
3182 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3184 struct libusb_device_descriptor d;
3186 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3187 d.bDescriptorType = LIBUSB_DT_DEVICE;
3188 d.bcdUSB = 0x0200; /* 2.00 */
3189 d.bDeviceClass = 0;
3190 d.bDeviceSubClass = 0;
3191 d.bDeviceProtocol = 0;
3192 d.bMaxPacketSize0 = 64; /* fix this! */
3193 d.idVendor = (uint16_t)dev->vid;
3194 d.idProduct = (uint16_t)dev->pid;
3195 d.bcdDevice = 0x0100;
3196 d.iManufacturer = dev->string_index[0];
3197 d.iProduct = dev->string_index[1];
3198 d.iSerialNumber = dev->string_index[2];
3199 d.bNumConfigurations = 1;
3201 if (*size > LIBUSB_DT_DEVICE_SIZE)
3202 *size = LIBUSB_DT_DEVICE_SIZE;
3203 memcpy(data, &d, *size);
3204 return LIBUSB_COMPLETED;
3207 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3209 char num_endpoints = 0;
3210 size_t config_total_len = 0;
3211 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3212 struct libusb_config_descriptor *cd;
3213 struct libusb_interface_descriptor *id;
3214 struct libusb_hid_descriptor *hd;
3215 struct libusb_endpoint_descriptor *ed;
3216 size_t tmp_size;
3218 if (dev->input_report_size)
3219 num_endpoints++;
3220 if (dev->output_report_size)
3221 num_endpoints++;
3223 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3224 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3227 cd = (struct libusb_config_descriptor *)tmp;
3228 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3229 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3230 + LIBUSB_DT_INTERFACE_SIZE);
3231 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3232 + LIBUSB_DT_INTERFACE_SIZE
3233 + LIBUSB_DT_HID_SIZE);
3235 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3236 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3237 cd->wTotalLength = (uint16_t) config_total_len;
3238 cd->bNumInterfaces = 1;
3239 cd->bConfigurationValue = 1;
3240 cd->iConfiguration = 0;
3241 cd->bmAttributes = 1 << 7; /* bus powered */
3242 cd->MaxPower = 50;
3244 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3245 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3246 id->bInterfaceNumber = 0;
3247 id->bAlternateSetting = 0;
3248 id->bNumEndpoints = num_endpoints;
3249 id->bInterfaceClass = 3;
3250 id->bInterfaceSubClass = 0;
3251 id->bInterfaceProtocol = 0;
3252 id->iInterface = 0;
3254 tmp_size = LIBUSB_DT_HID_SIZE;
3255 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3257 if (dev->input_report_size) {
3258 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3259 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3260 ed->bEndpointAddress = HID_IN_EP;
3261 ed->bmAttributes = 3;
3262 ed->wMaxPacketSize = dev->input_report_size - 1;
3263 ed->bInterval = 10;
3264 ed = (struct libusb_endpoint_descriptor *)((char*)ed + LIBUSB_DT_ENDPOINT_SIZE);
3267 if (dev->output_report_size) {
3268 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3269 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3270 ed->bEndpointAddress = HID_OUT_EP;
3271 ed->bmAttributes = 3;
3272 ed->wMaxPacketSize = dev->output_report_size - 1;
3273 ed->bInterval = 10;
3276 if (*size > config_total_len)
3277 *size = config_total_len;
3278 memcpy(data, tmp, *size);
3279 return LIBUSB_COMPLETED;
3282 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3283 void *data, size_t *size)
3285 void *tmp = NULL;
3286 size_t tmp_size = 0;
3287 int i;
3289 /* language ID, EN-US */
3290 char string_langid[] = {
3291 0x09,
3292 0x04
3295 if ((*size < 2) || (*size > 255)) {
3296 return LIBUSB_ERROR_OVERFLOW;
3299 if (_index == 0) {
3300 tmp = string_langid;
3301 tmp_size = sizeof(string_langid)+2;
3302 } else {
3303 for (i=0; i<3; i++) {
3304 if (_index == (dev->string_index[i])) {
3305 tmp = dev->string[i];
3306 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3307 break;
3310 if (i == 3) { // not found
3311 return LIBUSB_ERROR_INVALID_PARAM;
3315 if(!tmp_size) {
3316 return LIBUSB_ERROR_INVALID_PARAM;
3319 if (tmp_size < *size) {
3320 *size = tmp_size;
3322 // 2 byte header
3323 ((uint8_t*)data)[0] = (uint8_t)*size;
3324 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3325 memcpy((uint8_t*)data+2, tmp, *size-2);
3326 return LIBUSB_COMPLETED;
3329 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3331 struct libusb_hid_descriptor d;
3332 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3333 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3335 _hid_get_report_descriptor(dev, tmp, &report_len);
3337 d.bLength = LIBUSB_DT_HID_SIZE;
3338 d.bDescriptorType = LIBUSB_DT_HID;
3339 d.bcdHID = 0x0110; /* 1.10 */
3340 d.bCountryCode = 0;
3341 d.bNumDescriptors = 1;
3342 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3343 d.wClassDescriptorLength = (uint16_t)report_len;
3345 if (*size > LIBUSB_DT_HID_SIZE)
3346 *size = LIBUSB_DT_HID_SIZE;
3347 memcpy(data, &d, *size);
3348 return LIBUSB_COMPLETED;
3351 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3353 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3354 size_t i = 0;
3356 /* usage page (0xFFA0 == vendor defined) */
3357 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3358 /* usage (vendor defined) */
3359 d[i++] = 0x09; d[i++] = 0x01;
3360 /* start collection (application) */
3361 d[i++] = 0xA1; d[i++] = 0x01;
3362 /* input report */
3363 if (dev->input_report_size) {
3364 /* usage (vendor defined) */
3365 d[i++] = 0x09; d[i++] = 0x01;
3366 /* logical minimum (0) */
3367 d[i++] = 0x15; d[i++] = 0x00;
3368 /* logical maximum (255) */
3369 d[i++] = 0x25; d[i++] = 0xFF;
3370 /* report size (8 bits) */
3371 d[i++] = 0x75; d[i++] = 0x08;
3372 /* report count */
3373 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3374 /* input (data, variable, absolute) */
3375 d[i++] = 0x81; d[i++] = 0x00;
3377 /* output report */
3378 if (dev->output_report_size) {
3379 /* usage (vendor defined) */
3380 d[i++] = 0x09; d[i++] = 0x02;
3381 /* logical minimum (0) */
3382 d[i++] = 0x15; d[i++] = 0x00;
3383 /* logical maximum (255) */
3384 d[i++] = 0x25; d[i++] = 0xFF;
3385 /* report size (8 bits) */
3386 d[i++] = 0x75; d[i++] = 0x08;
3387 /* report count */
3388 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3389 /* output (data, variable, absolute) */
3390 d[i++] = 0x91; d[i++] = 0x00;
3392 /* feature report */
3393 if (dev->feature_report_size) {
3394 /* usage (vendor defined) */
3395 d[i++] = 0x09; d[i++] = 0x03;
3396 /* logical minimum (0) */
3397 d[i++] = 0x15; d[i++] = 0x00;
3398 /* logical maximum (255) */
3399 d[i++] = 0x25; d[i++] = 0xFF;
3400 /* report size (8 bits) */
3401 d[i++] = 0x75; d[i++] = 0x08;
3402 /* report count */
3403 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3404 /* feature (data, variable, absolute) */
3405 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3408 /* end collection */
3409 d[i++] = 0xC0;
3411 if (*size > i)
3412 *size = i;
3413 memcpy(data, d, *size);
3414 return LIBUSB_COMPLETED;
3417 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3418 int type, int _index, void *data, size_t *size)
3420 switch(type) {
3421 case LIBUSB_DT_DEVICE:
3422 usbi_dbg("LIBUSB_DT_DEVICE");
3423 return _hid_get_device_descriptor(dev, data, size);
3424 case LIBUSB_DT_CONFIG:
3425 usbi_dbg("LIBUSB_DT_CONFIG");
3426 if (!_index)
3427 return _hid_get_config_descriptor(dev, data, size);
3428 return LIBUSB_ERROR_INVALID_PARAM;
3429 case LIBUSB_DT_STRING:
3430 usbi_dbg("LIBUSB_DT_STRING");
3431 return _hid_get_string_descriptor(dev, _index, data, size);
3432 case LIBUSB_DT_HID:
3433 usbi_dbg("LIBUSB_DT_HID");
3434 if (!_index)
3435 return _hid_get_hid_descriptor(dev, data, size);
3436 return LIBUSB_ERROR_INVALID_PARAM;
3437 case LIBUSB_DT_REPORT:
3438 usbi_dbg("LIBUSB_DT_REPORT");
3439 if (!_index)
3440 return _hid_get_report_descriptor(dev, data, size);
3441 return LIBUSB_ERROR_INVALID_PARAM;
3442 case LIBUSB_DT_PHYSICAL:
3443 usbi_dbg("LIBUSB_DT_PHYSICAL");
3444 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3445 return LIBUSB_COMPLETED;
3446 return LIBUSB_ERROR_OTHER;
3448 usbi_dbg("unsupported");
3449 return LIBUSB_ERROR_INVALID_PARAM;
3452 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3453 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3454 int report_type)
3456 uint8_t *buf;
3457 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3458 int r = LIBUSB_SUCCESS;
3460 if (tp->hid_buffer != NULL) {
3461 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3464 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3465 usbi_dbg("invalid size (%d)", *size);
3466 return LIBUSB_ERROR_INVALID_PARAM;
3469 switch (report_type) {
3470 case HID_REPORT_TYPE_INPUT:
3471 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3472 break;
3473 case HID_REPORT_TYPE_FEATURE:
3474 ioctl_code = IOCTL_HID_GET_FEATURE;
3475 break;
3476 default:
3477 usbi_dbg("unknown HID report type %d", report_type);
3478 return LIBUSB_ERROR_INVALID_PARAM;
3481 // Add a trailing byte to detect overflows
3482 buf = (uint8_t*)calloc(expected_size+1, 1);
3483 if (buf == NULL) {
3484 return LIBUSB_ERROR_NO_MEM;
3486 buf[0] = (uint8_t)id; // Must be set always
3487 usbi_dbg("report ID: 0x%02X", buf[0]);
3489 tp->hid_expected_size = expected_size;
3490 read_size = expected_size;
3492 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3493 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3494 buf, expected_size+1, &read_size, overlapped)) {
3495 if (GetLastError() != ERROR_IO_PENDING) {
3496 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3497 safe_free(buf);
3498 return LIBUSB_ERROR_IO;
3500 // Asynchronous wait
3501 tp->hid_buffer = buf;
3502 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3503 return LIBUSB_SUCCESS;
3506 // Transfer completed synchronously => copy and discard extra buffer
3507 if (read_size == 0) {
3508 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3509 *size = 0;
3510 } else {
3511 if (buf[0] != id) {
3512 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3514 if ((size_t)read_size > expected_size) {
3515 r = LIBUSB_ERROR_OVERFLOW;
3516 usbi_dbg("OVERFLOW!");
3517 } else {
3518 r = LIBUSB_COMPLETED;
3521 *size = MIN((size_t)read_size, *size);
3522 if (id == 0) {
3523 // Discard report ID
3524 memcpy(data, buf+1, *size);
3525 } else {
3526 memcpy(data, buf, *size);
3529 safe_free(buf);
3530 return r;
3533 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3534 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3535 int report_type)
3537 uint8_t *buf = NULL;
3538 DWORD ioctl_code, write_size= (DWORD)*size;
3540 if (tp->hid_buffer != NULL) {
3541 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3544 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3545 usbi_dbg("invalid size (%d)", *size);
3546 return LIBUSB_ERROR_INVALID_PARAM;
3549 switch (report_type) {
3550 case HID_REPORT_TYPE_OUTPUT:
3551 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3552 break;
3553 case HID_REPORT_TYPE_FEATURE:
3554 ioctl_code = IOCTL_HID_SET_FEATURE;
3555 break;
3556 default:
3557 usbi_dbg("unknown HID report type %d", report_type);
3558 return LIBUSB_ERROR_INVALID_PARAM;
3561 usbi_dbg("report ID: 0x%02X", id);
3562 // When report IDs are not used (i.e. when id == 0), we must add
3563 // a null report ID. Otherwise, we just use original data buffer
3564 if (id == 0) {
3565 write_size++;
3567 buf = (uint8_t*) malloc(write_size);
3568 if (buf == NULL) {
3569 return LIBUSB_ERROR_NO_MEM;
3571 if (id == 0) {
3572 buf[0] = 0;
3573 memcpy(buf + 1, data, *size);
3574 } else {
3575 // This seems like a waste, but if we don't duplicate the
3576 // data, we'll get issues when freeing hid_buffer
3577 memcpy(buf, data, *size);
3578 if (buf[0] != id) {
3579 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3583 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3584 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3585 buf, write_size, &write_size, overlapped)) {
3586 if (GetLastError() != ERROR_IO_PENDING) {
3587 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3588 safe_free(buf);
3589 return LIBUSB_ERROR_IO;
3591 tp->hid_buffer = buf;
3592 tp->hid_dest = NULL;
3593 return LIBUSB_SUCCESS;
3596 // Transfer completed synchronously
3597 *size = write_size;
3598 if (write_size == 0) {
3599 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3601 safe_free(buf);
3602 return LIBUSB_COMPLETED;
3605 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3606 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3607 size_t *size, OVERLAPPED* overlapped)
3609 int report_type = (value >> 8) & 0xFF;
3610 int report_id = value & 0xFF;
3612 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3613 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3614 return LIBUSB_ERROR_INVALID_PARAM;
3616 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3617 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3619 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3620 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3622 return LIBUSB_ERROR_INVALID_PARAM;
3627 * HID API functions
3629 static int hid_init(int sub_api, struct libusb_context *ctx)
3631 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3632 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3633 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3634 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3635 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3636 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3637 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3638 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3639 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3640 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3641 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3642 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3643 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3644 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3645 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3646 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3648 api_hid_available = true;
3649 return LIBUSB_SUCCESS;
3652 static int hid_exit(int sub_api)
3654 return LIBUSB_SUCCESS;
3657 // NB: open and close must ensure that they only handle interface of
3658 // the right API type, as these functions can be called wholesale from
3659 // composite_open(), with interfaces belonging to different APIs
3660 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3662 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3663 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3664 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3666 HIDD_ATTRIBUTES hid_attributes;
3667 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3668 HIDP_CAPS capabilities;
3669 HIDP_VALUE_CAPS *value_caps;
3671 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3672 int i, j;
3673 // report IDs handling
3674 ULONG size[3];
3675 const char* type[3] = {"input", "output", "feature"};
3676 int nb_ids[2]; // zero and nonzero report IDs
3678 CHECK_HID_AVAILABLE;
3679 if (priv->hid == NULL) {
3680 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3681 return LIBUSB_ERROR_NOT_FOUND;
3684 for (i = 0; i < USB_MAXINTERFACES; i++) {
3685 if ( (priv->usb_interface[i].path != NULL)
3686 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3687 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3688 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3690 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3691 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3692 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3693 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3694 * HidD_GetFeature (if the device supports Feature reports)."
3696 if (hid_handle == INVALID_HANDLE_VALUE) {
3697 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3698 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3699 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3700 if (hid_handle == INVALID_HANDLE_VALUE) {
3701 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3702 switch(GetLastError()) {
3703 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3704 return LIBUSB_ERROR_NO_DEVICE;
3705 case ERROR_ACCESS_DENIED:
3706 return LIBUSB_ERROR_ACCESS;
3707 default:
3708 return LIBUSB_ERROR_IO;
3711 priv->usb_interface[i].restricted_functionality = true;
3713 handle_priv->interface_handle[i].api_handle = hid_handle;
3717 hid_attributes.Size = sizeof(hid_attributes);
3718 do {
3719 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3720 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3721 break;
3724 priv->hid->vid = hid_attributes.VendorID;
3725 priv->hid->pid = hid_attributes.ProductID;
3727 // Set the maximum available input buffer size
3728 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3729 usbi_dbg("set maximum input buffer size to %d", i/2);
3731 // Get the maximum input and output report size
3732 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3733 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3734 break;
3736 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3737 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3738 break;
3741 // Find out if interrupt will need report IDs
3742 size[0] = capabilities.NumberInputValueCaps;
3743 size[1] = capabilities.NumberOutputValueCaps;
3744 size[2] = capabilities.NumberFeatureValueCaps;
3745 for (j=HidP_Input; j<=HidP_Feature; j++) {
3746 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3747 priv->hid->uses_report_ids[j] = false;
3748 if (size[j] > 0) {
3749 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3750 if ( (value_caps != NULL)
3751 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3752 && (size[j] >= 1) ) {
3753 nb_ids[0] = 0;
3754 nb_ids[1] = 0;
3755 for (i=0; i<(int)size[j]; i++) {
3756 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3757 if (value_caps[i].ReportID != 0) {
3758 nb_ids[1]++;
3759 } else {
3760 nb_ids[0]++;
3763 if (nb_ids[1] != 0) {
3764 if (nb_ids[0] != 0) {
3765 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3766 type[j]);
3768 priv->hid->uses_report_ids[j] = true;
3770 } else {
3771 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3773 safe_free(value_caps);
3777 // Set the report sizes
3778 priv->hid->input_report_size = capabilities.InputReportByteLength;
3779 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3780 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3782 // Fetch string descriptors
3783 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3784 if (priv->hid->string_index[0] != 0) {
3785 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3786 sizeof(priv->hid->string[0]));
3787 } else {
3788 priv->hid->string[0][0] = 0;
3790 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3791 if (priv->hid->string_index[1] != 0) {
3792 HidD_GetProductString(hid_handle, priv->hid->string[1],
3793 sizeof(priv->hid->string[1]));
3794 } else {
3795 priv->hid->string[1][0] = 0;
3797 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3798 if (priv->hid->string_index[2] != 0) {
3799 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3800 sizeof(priv->hid->string[2]));
3801 } else {
3802 priv->hid->string[2][0] = 0;
3804 } while(0);
3806 if (preparsed_data) {
3807 HidD_FreePreparsedData(preparsed_data);
3810 return LIBUSB_SUCCESS;
3813 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3815 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3816 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3817 HANDLE file_handle;
3818 int i;
3820 if (!api_hid_available)
3821 return;
3823 for (i = 0; i < USB_MAXINTERFACES; i++) {
3824 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3825 file_handle = handle_priv->interface_handle[i].api_handle;
3826 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3827 CloseHandle(file_handle);
3833 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3835 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3836 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3838 CHECK_HID_AVAILABLE;
3840 // NB: Disconnection detection is not possible in this function
3841 if (priv->usb_interface[iface].path == NULL) {
3842 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3845 // We use dev_handle as a flag for interface claimed
3846 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3847 return LIBUSB_ERROR_BUSY; // already claimed
3850 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3852 usbi_dbg("claimed interface %d", iface);
3853 handle_priv->active_interface = iface;
3855 return LIBUSB_SUCCESS;
3858 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3860 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3861 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3863 CHECK_HID_AVAILABLE;
3865 if (priv->usb_interface[iface].path == NULL) {
3866 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3869 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3870 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3873 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3875 return LIBUSB_SUCCESS;
3878 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3880 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3882 CHECK_HID_AVAILABLE;
3884 if (altsetting > 255) {
3885 return LIBUSB_ERROR_INVALID_PARAM;
3888 if (altsetting != 0) {
3889 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3890 return LIBUSB_ERROR_NOT_SUPPORTED;
3893 return LIBUSB_SUCCESS;
3896 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3898 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3899 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3900 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3901 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3902 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3903 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3904 HANDLE hid_handle;
3905 struct winfd wfd;
3906 int current_interface, config;
3907 size_t size;
3908 int r = LIBUSB_ERROR_INVALID_PARAM;
3910 CHECK_HID_AVAILABLE;
3912 transfer_priv->pollable_fd = INVALID_WINFD;
3913 safe_free(transfer_priv->hid_buffer);
3914 transfer_priv->hid_dest = NULL;
3915 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3917 if (size > MAX_CTRL_BUFFER_LENGTH) {
3918 return LIBUSB_ERROR_INVALID_PARAM;
3921 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3922 if (current_interface < 0) {
3923 if (auto_claim(transfer, &current_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3924 return LIBUSB_ERROR_NOT_FOUND;
3928 usbi_dbg("will use interface %d", current_interface);
3929 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3930 // Always use the handle returned from usbi_create_fd (wfd.handle)
3931 wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
3932 if (wfd.fd < 0) {
3933 return LIBUSB_ERROR_NOT_FOUND;
3936 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3937 case LIBUSB_REQUEST_TYPE_STANDARD:
3938 switch(setup->request) {
3939 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3940 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3941 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3942 break;
3943 case LIBUSB_REQUEST_GET_CONFIGURATION:
3944 r = windows_get_configuration(transfer->dev_handle, &config);
3945 if (r == LIBUSB_SUCCESS) {
3946 size = 1;
3947 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3948 r = LIBUSB_COMPLETED;
3950 break;
3951 case LIBUSB_REQUEST_SET_CONFIGURATION:
3952 if (setup->value == priv->active_config) {
3953 r = LIBUSB_COMPLETED;
3954 } else {
3955 usbi_warn(ctx, "cannot set configuration other than the default one");
3956 r = LIBUSB_ERROR_INVALID_PARAM;
3958 break;
3959 case LIBUSB_REQUEST_GET_INTERFACE:
3960 size = 1;
3961 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3962 r = LIBUSB_COMPLETED;
3963 break;
3964 case LIBUSB_REQUEST_SET_INTERFACE:
3965 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3966 if (r == LIBUSB_SUCCESS) {
3967 r = LIBUSB_COMPLETED;
3969 break;
3970 default:
3971 usbi_warn(ctx, "unsupported HID control request");
3972 r = LIBUSB_ERROR_INVALID_PARAM;
3973 break;
3975 break;
3976 case LIBUSB_REQUEST_TYPE_CLASS:
3977 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3978 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3979 &size, wfd.overlapped);
3980 break;
3981 default:
3982 usbi_warn(ctx, "unsupported HID control request");
3983 r = LIBUSB_ERROR_INVALID_PARAM;
3984 break;
3987 if (r == LIBUSB_COMPLETED) {
3988 // Force request to be completed synchronously. Transferred size has been set by previous call
3989 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3990 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3991 // set InternalHigh to the number of bytes transferred
3992 wfd.overlapped->InternalHigh = (DWORD)size;
3993 r = LIBUSB_SUCCESS;
3996 if (r == LIBUSB_SUCCESS) {
3997 // Use priv_transfer to store data needed for async polling
3998 transfer_priv->pollable_fd = wfd;
3999 transfer_priv->interface_number = (uint8_t)current_interface;
4000 } else {
4001 usbi_free_fd(&wfd);
4004 return r;
4007 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4008 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4009 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4010 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4011 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4012 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4013 struct winfd wfd;
4014 HANDLE hid_handle;
4015 bool direction_in, ret;
4016 int current_interface, length;
4017 DWORD size;
4018 int r = LIBUSB_SUCCESS;
4020 CHECK_HID_AVAILABLE;
4022 transfer_priv->pollable_fd = INVALID_WINFD;
4023 transfer_priv->hid_dest = NULL;
4024 safe_free(transfer_priv->hid_buffer);
4026 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4027 if (current_interface < 0) {
4028 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4029 return LIBUSB_ERROR_NOT_FOUND;
4032 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
4034 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4035 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
4037 wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
4038 // Always use the handle returned from usbi_create_fd (wfd.handle)
4039 if (wfd.fd < 0) {
4040 return LIBUSB_ERROR_NO_MEM;
4043 // If report IDs are not in use, an extra prefix byte must be added
4044 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4045 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4046 length = transfer->length+1;
4047 } else {
4048 length = transfer->length;
4050 // Add a trailing byte to detect overflows on input
4051 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4052 if (transfer_priv->hid_buffer == NULL) {
4053 return LIBUSB_ERROR_NO_MEM;
4055 transfer_priv->hid_expected_size = length;
4057 if (direction_in) {
4058 transfer_priv->hid_dest = transfer->buffer;
4059 usbi_dbg("reading %d bytes (report ID: 0x00)", length);
4060 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4061 } else {
4062 if (!priv->hid->uses_report_ids[1]) {
4063 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4064 } else {
4065 // We could actually do without the calloc and memcpy in this case
4066 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4068 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4069 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4071 if (!ret) {
4072 if (GetLastError() != ERROR_IO_PENDING) {
4073 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4074 usbi_free_fd(&wfd);
4075 safe_free(transfer_priv->hid_buffer);
4076 return LIBUSB_ERROR_IO;
4078 } else {
4079 // Only write operations that completed synchronously need to free up
4080 // hid_buffer. For reads, copy_transfer_data() handles that process.
4081 if (!direction_in) {
4082 safe_free(transfer_priv->hid_buffer);
4084 if (size == 0) {
4085 usbi_err(ctx, "program assertion failed - no data was transferred");
4086 size = 1;
4088 if (size > (size_t)length) {
4089 usbi_err(ctx, "OVERFLOW!");
4090 r = LIBUSB_ERROR_OVERFLOW;
4092 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4093 wfd.overlapped->InternalHigh = size;
4096 transfer_priv->pollable_fd = wfd;
4097 transfer_priv->interface_number = (uint8_t)current_interface;
4099 return r;
4102 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4104 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4105 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4106 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4107 HANDLE hid_handle;
4108 int current_interface;
4110 CHECK_HID_AVAILABLE;
4112 current_interface = transfer_priv->interface_number;
4113 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4114 CancelIo(hid_handle);
4116 return LIBUSB_SUCCESS;
4119 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4121 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4122 HANDLE hid_handle;
4123 int current_interface;
4125 CHECK_HID_AVAILABLE;
4127 // Flushing the queues on all interfaces is the best we can achieve
4128 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4129 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4130 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4131 HidD_FlushQueue(hid_handle);
4134 return LIBUSB_SUCCESS;
4137 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4139 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4140 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4141 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4142 HANDLE hid_handle;
4143 int current_interface;
4145 CHECK_HID_AVAILABLE;
4147 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4148 if (current_interface < 0) {
4149 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4150 return LIBUSB_ERROR_NOT_FOUND;
4153 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4154 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4156 // No endpoint selection with Microsoft's implementation, so we try to flush the
4157 // whole interface. Should be OK for most case scenarios
4158 if (!HidD_FlushQueue(hid_handle)) {
4159 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4160 // Device was probably disconnected
4161 return LIBUSB_ERROR_NO_DEVICE;
4164 return LIBUSB_SUCCESS;
4167 // This extra function is only needed for HID
4168 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4169 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4170 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4171 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4172 int r = LIBUSB_TRANSFER_COMPLETED;
4173 uint32_t corrected_size = io_size;
4175 if (transfer_priv->hid_buffer != NULL) {
4176 // If we have a valid hid_buffer, it means the transfer was async
4177 if (transfer_priv->hid_dest != NULL) { // Data readout
4178 if (corrected_size > 0) {
4179 // First, check for overflow
4180 if (corrected_size > transfer_priv->hid_expected_size) {
4181 usbi_err(ctx, "OVERFLOW!");
4182 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4183 r = LIBUSB_TRANSFER_OVERFLOW;
4186 if (transfer_priv->hid_buffer[0] == 0) {
4187 // Discard the 1 byte report ID prefix
4188 corrected_size--;
4189 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4190 } else {
4191 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4194 transfer_priv->hid_dest = NULL;
4196 // For write, we just need to free the hid buffer
4197 safe_free(transfer_priv->hid_buffer);
4199 itransfer->transferred += corrected_size;
4200 return r;
4205 * Composite API functions
4207 static int composite_init(int sub_api, struct libusb_context *ctx)
4209 return LIBUSB_SUCCESS;
4212 static int composite_exit(int sub_api)
4214 return LIBUSB_SUCCESS;
4217 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4219 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4220 int r = LIBUSB_ERROR_NOT_FOUND;
4221 uint8_t i;
4222 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4223 bool available[SUB_API_MAX+1] = {0};
4225 for (i=0; i<USB_MAXINTERFACES; i++) {
4226 switch (priv->usb_interface[i].apib->id) {
4227 case USB_API_WINUSBX:
4228 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4229 available[priv->usb_interface[i].sub_api] = true;
4230 break;
4231 case USB_API_HID:
4232 available[SUB_API_MAX] = true;
4233 break;
4234 default:
4235 break;
4239 for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4240 if (available[i]) {
4241 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4242 if (r != LIBUSB_SUCCESS) {
4243 return r;
4247 if (available[SUB_API_MAX]) { // HID driver
4248 r = hid_open(SUB_API_NOTSET, dev_handle);
4250 return r;
4253 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4255 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4256 uint8_t i;
4257 bool available[SUB_API_MAX];
4259 for (i = 0; i<SUB_API_MAX; i++) {
4260 available[i] = false;
4263 for (i=0; i<USB_MAXINTERFACES; i++) {
4264 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4265 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4266 available[priv->usb_interface[i].sub_api] = true;
4270 for (i=0; i<SUB_API_MAX; i++) {
4271 if (available[i]) {
4272 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4277 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4279 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4280 return priv->usb_interface[iface].apib->
4281 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4284 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4286 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4287 return priv->usb_interface[iface].apib->
4288 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4291 static int composite_release_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 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4298 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4300 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4301 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4302 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4303 int i, pass;
4305 // Interface shouldn't matter for control, but it does in practice, with Windows'
4306 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4307 for (pass = 0; pass < 2; pass++) {
4308 for (i=0; i<USB_MAXINTERFACES; i++) {
4309 if (priv->usb_interface[i].path != NULL) {
4310 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4311 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4312 continue;
4314 usbi_dbg("using interface %d", i);
4315 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4320 usbi_err(ctx, "no libusbx supported interfaces to complete request");
4321 return LIBUSB_ERROR_NOT_FOUND;
4324 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4325 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4326 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4327 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4328 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4329 int current_interface;
4331 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4332 if (current_interface < 0) {
4333 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4334 return LIBUSB_ERROR_NOT_FOUND;
4337 return priv->usb_interface[current_interface].apib->
4338 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4340 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4341 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4342 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4343 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4344 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4345 int current_interface;
4347 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4348 if (current_interface < 0) {
4349 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4350 return LIBUSB_ERROR_NOT_FOUND;
4353 return priv->usb_interface[current_interface].apib->
4354 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4356 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4358 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4359 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4360 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4361 int current_interface;
4363 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4364 if (current_interface < 0) {
4365 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4366 return LIBUSB_ERROR_NOT_FOUND;
4369 return priv->usb_interface[current_interface].apib->
4370 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4372 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4374 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4375 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4376 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4378 return priv->usb_interface[transfer_priv->interface_number].apib->
4379 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4381 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4383 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4384 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4385 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4387 return priv->usb_interface[transfer_priv->interface_number].apib->
4388 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4390 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4392 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4393 int r;
4394 uint8_t i;
4395 bool available[SUB_API_MAX];
4396 for (i = 0; i<SUB_API_MAX; i++) {
4397 available[i] = false;
4399 for (i=0; i<USB_MAXINTERFACES; i++) {
4400 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4401 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4402 available[priv->usb_interface[i].sub_api] = true;
4405 for (i=0; i<SUB_API_MAX; i++) {
4406 if (available[i]) {
4407 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4408 if (r != LIBUSB_SUCCESS) {
4409 return r;
4413 return LIBUSB_SUCCESS;
4416 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4418 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4419 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4420 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4422 return priv->usb_interface[transfer_priv->interface_number].apib->
4423 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);