Make usbi_get_device_by_session_id return a ref to the found device
[libusbx.git] / libusb / os / windows_usb.c
blobfdc60c7210f4c9c1ad6be4ed96691cbd6de0ba77
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 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
162 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
163 ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
164 if (size == 0) {
165 format_error = GetLastError();
166 if (format_error)
167 safe_sprintf(err_string, ERR_BUFFER_SIZE,
168 "Windows error code %u (FormatMessage error code %u)", error_code, format_error);
169 else
170 safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
171 } else {
172 // Remove CR/LF terminators
173 for (i=safe_strlen(err_string)-1; (i>=0) && ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
174 err_string[i] = 0;
177 return err_string;
179 #endif
182 * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
183 * Return an allocated sanitized string or NULL on error.
185 static char* sanitize_path(const char* path)
187 const char root_prefix[] = "\\\\.\\";
188 size_t j, size, root_size;
189 char* ret_path = NULL;
190 size_t add_root = 0;
192 if (path == NULL)
193 return NULL;
195 size = safe_strlen(path)+1;
196 root_size = sizeof(root_prefix)-1;
198 // Microsoft indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
199 if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
200 ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
201 add_root = root_size;
202 size += add_root;
205 if ((ret_path = (char*) calloc(size, 1)) == NULL)
206 return NULL;
208 safe_strcpy(&ret_path[add_root], size-add_root, path);
210 // Ensure consistancy with root prefix
211 for (j=0; j<root_size; j++)
212 ret_path[j] = root_prefix[j];
214 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
215 for(j=root_size; j<size; j++) {
216 ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
217 if (ret_path[j] == '\\')
218 ret_path[j] = '#';
221 return ret_path;
225 * Cfgmgr32, OLE32 and SetupAPI DLL functions
227 static int init_dlls(void)
229 DLL_LOAD(Cfgmgr32.dll, CM_Get_Parent, TRUE);
230 DLL_LOAD(Cfgmgr32.dll, CM_Get_Child, TRUE);
231 DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE);
232 DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE);
233 // Prefixed to avoid conflict with header files
234 DLL_LOAD_PREFIXED(OLE32.dll, p, CLSIDFromString, TRUE);
235 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE);
236 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE);
237 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE);
238 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
239 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
240 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
241 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
242 DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
243 DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
244 DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
245 return LIBUSB_SUCCESS;
249 * enumerate interfaces for the whole USB class
251 * Parameters:
252 * dev_info: a pointer to a dev_info list
253 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
254 * usb_class: the generic USB class for which to retrieve interface details
255 * index: zero based index of the interface in the device info list
257 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
258 * structure returned and call this function repeatedly using the same guid (with an
259 * incremented index starting at zero) until all interfaces have been returned.
261 static bool get_devinfo_data(struct libusb_context *ctx,
262 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char* usb_class, unsigned _index)
264 if (_index <= 0) {
265 *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
266 if (*dev_info == INVALID_HANDLE_VALUE) {
267 return false;
271 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
272 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
273 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
274 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
275 _index, windows_error_str(0));
277 pSetupDiDestroyDeviceInfoList(*dev_info);
278 *dev_info = INVALID_HANDLE_VALUE;
279 return false;
281 return true;
285 * enumerate interfaces for a specific GUID
287 * Parameters:
288 * dev_info: a pointer to a dev_info list
289 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
290 * guid: the GUID for which to retrieve interface details
291 * index: zero based index of the interface in the device info list
293 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
294 * structure returned and call this function repeatedly using the same guid (with an
295 * incremented index starting at zero) until all interfaces have been returned.
297 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details(struct libusb_context *ctx,
298 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index)
300 SP_DEVICE_INTERFACE_DATA dev_interface_data;
301 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
302 DWORD size;
304 if (_index <= 0) {
305 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
308 if (dev_info_data != NULL) {
309 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
310 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
311 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
312 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
313 _index, windows_error_str(0));
315 pSetupDiDestroyDeviceInfoList(*dev_info);
316 *dev_info = INVALID_HANDLE_VALUE;
317 return NULL;
321 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
322 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
323 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
324 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
325 _index, windows_error_str(0));
327 pSetupDiDestroyDeviceInfoList(*dev_info);
328 *dev_info = INVALID_HANDLE_VALUE;
329 return NULL;
332 // Read interface data (dummy + actual) to access the device path
333 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
334 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
335 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
336 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
337 _index, windows_error_str(0));
338 goto err_exit;
340 } else {
341 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
342 goto err_exit;
345 if ((dev_interface_details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) calloc(size, 1)) == NULL) {
346 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
347 goto err_exit;
350 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
351 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
352 dev_interface_details, size, &size, NULL)) {
353 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
354 _index, windows_error_str(0));
357 return dev_interface_details;
359 err_exit:
360 pSetupDiDestroyDeviceInfoList(*dev_info);
361 *dev_info = INVALID_HANDLE_VALUE;
362 return NULL;
365 /* For libusb0 filter */
366 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
367 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index, char* filter_path){
368 SP_DEVICE_INTERFACE_DATA dev_interface_data;
369 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
370 DWORD size;
371 if (_index <= 0) {
372 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
374 if (dev_info_data != NULL) {
375 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
376 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
377 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
378 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
379 _index, windows_error_str(0));
381 pSetupDiDestroyDeviceInfoList(*dev_info);
382 *dev_info = INVALID_HANDLE_VALUE;
383 return NULL;
386 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
387 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
388 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
389 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
390 _index, windows_error_str(0));
392 pSetupDiDestroyDeviceInfoList(*dev_info);
393 *dev_info = INVALID_HANDLE_VALUE;
394 return NULL;
396 // Read interface data (dummy + actual) to access the device path
397 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
398 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
399 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
400 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
401 _index, windows_error_str(0));
402 goto err_exit;
404 } else {
405 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
406 goto err_exit;
408 if ((dev_interface_details = malloc(size)) == NULL) {
409 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
410 goto err_exit;
412 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
413 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
414 dev_interface_details, size, &size, NULL)) {
415 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
416 _index, windows_error_str(0));
418 // [trobinso] lookup the libusb0 symbolic index.
419 if (dev_interface_details) {
420 HKEY hkey_device_interface=pSetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ);
421 if (hkey_device_interface != INVALID_HANDLE_VALUE) {
422 DWORD libusb0_symboliclink_index=0;
423 DWORD value_length=sizeof(DWORD);
424 DWORD value_type=0;
425 LONG status;
426 status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type,
427 (LPBYTE) &libusb0_symboliclink_index, &value_length);
428 if (status == ERROR_SUCCESS) {
429 if (libusb0_symboliclink_index < 256) {
430 // libusb0.sys is connected to this device instance.
431 // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
432 safe_sprintf(filter_path, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index);
433 usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
434 } else {
435 // libusb0.sys was connected to this device instance at one time; but not anymore.
438 pRegCloseKey(hkey_device_interface);
441 return dev_interface_details;
442 err_exit:
443 pSetupDiDestroyDeviceInfoList(*dev_info);
444 *dev_info = INVALID_HANDLE_VALUE;
445 return NULL;}
447 /* Hash table functions - modified From glibc 2.3.2:
448 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
449 [Knuth] The Art of Computer Programming, part 3 (6.4) */
450 typedef struct htab_entry {
451 unsigned long used;
452 char* str;
453 } htab_entry;
454 htab_entry* htab_table = NULL;
455 usbi_mutex_t htab_write_mutex = NULL;
456 unsigned long htab_size, htab_filled;
458 /* For the used double hash method the table size has to be a prime. To
459 correct the user given table size we need a prime test. This trivial
460 algorithm is adequate because the code is called only during init and
461 the number is likely to be small */
462 static int isprime(unsigned long number)
464 // no even number will be passed
465 unsigned int divider = 3;
467 while((divider * divider < number) && (number % divider != 0))
468 divider += 2;
470 return (number % divider != 0);
473 /* Before using the hash table we must allocate memory for it.
474 We allocate one element more as the found prime number says.
475 This is done for more effective indexing as explained in the
476 comment for the hash function. */
477 static int htab_create(struct libusb_context *ctx, unsigned long nel)
479 if (htab_table != NULL) {
480 usbi_err(ctx, "hash table already allocated");
483 // Create a mutex
484 usbi_mutex_init(&htab_write_mutex, NULL);
486 // Change nel to the first prime number not smaller as nel.
487 nel |= 1;
488 while(!isprime(nel))
489 nel += 2;
491 htab_size = nel;
492 usbi_dbg("using %d entries hash table", nel);
493 htab_filled = 0;
495 // allocate memory and zero out.
496 htab_table = (htab_entry*) calloc(htab_size + 1, sizeof(htab_entry));
497 if (htab_table == NULL) {
498 usbi_err(ctx, "could not allocate space for hash table");
499 return 0;
502 return 1;
505 /* After using the hash table it has to be destroyed. */
506 static void htab_destroy(void)
508 size_t i;
509 if (htab_table == NULL) {
510 return;
513 for (i=0; i<htab_size; i++) {
514 if (htab_table[i].used) {
515 safe_free(htab_table[i].str);
518 usbi_mutex_destroy(&htab_write_mutex);
519 safe_free(htab_table);
522 /* This is the search function. It uses double hashing with open addressing.
523 We use an trick to speed up the lookup. The table is created with one
524 more element available. This enables us to use the index zero special.
525 This index will never be used because we store the first hash index in
526 the field used where zero means not used. Every other value means used.
527 The used field can be used as a first fast comparison for equality of
528 the stored and the parameter value. This helps to prevent unnecessary
529 expensive calls of strcmp. */
530 static unsigned long htab_hash(char* str)
532 unsigned long hval, hval2;
533 unsigned long idx;
534 unsigned long r = 5381;
535 int c;
536 char* sz = str;
538 if (str == NULL)
539 return 0;
541 // Compute main hash value (algorithm suggested by Nokia)
542 while ((c = *sz++) != 0)
543 r = ((r << 5) + r) + c;
544 if (r == 0)
545 ++r;
547 // compute table hash: simply take the modulus
548 hval = r % htab_size;
549 if (hval == 0)
550 ++hval;
552 // Try the first index
553 idx = hval;
555 if (htab_table[idx].used) {
556 if ( (htab_table[idx].used == hval)
557 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
558 // existing hash
559 return idx;
561 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
563 // Second hash function, as suggested in [Knuth]
564 hval2 = 1 + hval % (htab_size - 2);
566 do {
567 // Because size is prime this guarantees to step through all available indexes
568 if (idx <= hval2) {
569 idx = htab_size + idx - hval2;
570 } else {
571 idx -= hval2;
574 // If we visited all entries leave the loop unsuccessfully
575 if (idx == hval) {
576 break;
579 // If entry is found use it.
580 if ( (htab_table[idx].used == hval)
581 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
582 return idx;
585 while (htab_table[idx].used);
588 // Not found => New entry
590 // If the table is full return an error
591 if (htab_filled >= htab_size) {
592 usbi_err(NULL, "hash table is full (%d entries)", htab_size);
593 return 0;
596 // Concurrent threads might be storing the same entry at the same time
597 // (eg. "simultaneous" enums from different threads) => use a mutex
598 usbi_mutex_lock(&htab_write_mutex);
599 // Just free any previously allocated string (which should be the same as
600 // new one). The possibility of concurrent threads storing a collision
601 // string (same hash, different string) at the same time is extremely low
602 safe_free(htab_table[idx].str);
603 htab_table[idx].used = hval;
604 htab_table[idx].str = (char*) malloc(safe_strlen(str)+1);
605 if (htab_table[idx].str == NULL) {
606 usbi_err(NULL, "could not duplicate string for hash table");
607 usbi_mutex_unlock(&htab_write_mutex);
608 return 0;
610 memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
611 ++htab_filled;
612 usbi_mutex_unlock(&htab_write_mutex);
614 return idx;
618 * Returns the session ID of a device's nth level ancestor
619 * If there's no device at the nth level, return 0
621 static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
623 DWORD parent_devinst;
624 unsigned long session_id = 0;
625 char* sanitized_path = NULL;
626 char path[MAX_PATH_LENGTH];
627 unsigned i;
629 if (level < 1) return 0;
630 for (i = 0; i<level; i++) {
631 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
632 return 0;
634 devinst = parent_devinst;
636 if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
637 return 0;
639 // TODO: (post hotplug): try without sanitizing
640 sanitized_path = sanitize_path(path);
641 if (sanitized_path == NULL) {
642 return 0;
644 session_id = htab_hash(sanitized_path);
645 safe_free(sanitized_path);
646 return session_id;
650 * Populate the endpoints addresses of the device_priv interface helper structs
652 static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
654 int i, r;
655 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
656 struct libusb_config_descriptor *conf_desc;
657 const struct libusb_interface_descriptor *if_desc;
658 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
660 r = libusb_get_config_descriptor(dev_handle->dev, 0, &conf_desc);
661 if (r != LIBUSB_SUCCESS) {
662 usbi_warn(ctx, "could not read config descriptor: error %d", r);
663 return r;
666 if_desc = &conf_desc->interface[iface].altsetting[altsetting];
667 safe_free(priv->usb_interface[iface].endpoint);
669 if (if_desc->bNumEndpoints == 0) {
670 usbi_dbg("no endpoints found for interface %d", iface);
671 return LIBUSB_SUCCESS;
674 priv->usb_interface[iface].endpoint = (uint8_t*) malloc(if_desc->bNumEndpoints);
675 if (priv->usb_interface[iface].endpoint == NULL) {
676 return LIBUSB_ERROR_NO_MEM;
679 priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
680 for (i=0; i<if_desc->bNumEndpoints; i++) {
681 priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
682 usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface);
684 libusb_free_config_descriptor(conf_desc);
686 // Extra init may be required to configure endpoints
687 return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
690 // Lookup for a match in the list of API driver names
691 // return -1 if not found, driver match number otherwise
692 static int get_sub_api(char* driver, int api){
693 int i;
694 const char sep_str[2] = {LIST_SEPARATOR, 0};
695 char *tok, *tmp_str;
696 size_t len = safe_strlen(driver);
698 if (len == 0) return SUB_API_NOTSET;
699 tmp_str = (char*) calloc(len+1, 1);
700 if (tmp_str == NULL) return SUB_API_NOTSET;
701 memcpy(tmp_str, driver, len+1);
702 tok = strtok(tmp_str, sep_str);
703 while (tok != NULL) {
704 for (i=0; i<usb_api_backend[api].nb_driver_names; i++) {
705 if (safe_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
706 free(tmp_str);
707 return i;
710 tok = strtok(NULL, sep_str);
712 free (tmp_str);
713 return SUB_API_NOTSET;
717 * auto-claiming and auto-release helper functions
719 static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
721 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
722 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
723 transfer->dev_handle);
724 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
725 int current_interface = *interface_number;
726 int r = LIBUSB_SUCCESS;
728 switch(api_type) {
729 case USB_API_WINUSBX:
730 case USB_API_HID:
731 break;
732 default:
733 return LIBUSB_ERROR_INVALID_PARAM;
736 usbi_mutex_lock(&autoclaim_lock);
737 if (current_interface < 0) // No serviceable interface was found
739 for (current_interface=0; current_interface<USB_MAXINTERFACES; current_interface++) {
740 // Must claim an interface of the same API type
741 if ( (priv->usb_interface[current_interface].apib->id == api_type)
742 && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS) ) {
743 usbi_dbg("auto-claimed interface %d for control request", current_interface);
744 if (handle_priv->autoclaim_count[current_interface] != 0) {
745 usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero");
747 handle_priv->autoclaim_count[current_interface]++;
748 break;
751 if (current_interface == USB_MAXINTERFACES) {
752 usbi_err(ctx, "could not auto-claim any interface");
753 r = LIBUSB_ERROR_NOT_FOUND;
755 } else {
756 // If we have a valid interface that was autoclaimed, we must increment
757 // its autoclaim count so that we can prevent an early release.
758 if (handle_priv->autoclaim_count[current_interface] != 0) {
759 handle_priv->autoclaim_count[current_interface]++;
762 usbi_mutex_unlock(&autoclaim_lock);
764 *interface_number = current_interface;
765 return r;
769 static void auto_release(struct usbi_transfer *itransfer)
771 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
772 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
773 libusb_device_handle *dev_handle = transfer->dev_handle;
774 struct windows_device_handle_priv* handle_priv = _device_handle_priv(dev_handle);
775 int r;
777 usbi_mutex_lock(&autoclaim_lock);
778 if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
779 handle_priv->autoclaim_count[transfer_priv->interface_number]--;
780 if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
781 r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
782 if (r == LIBUSB_SUCCESS) {
783 usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
784 } else {
785 usbi_dbg("failed to auto-release interface %d (%s)",
786 transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
790 usbi_mutex_unlock(&autoclaim_lock);
794 * init: libusbx backend init function
796 * This function enumerates the HCDs (Host Controller Drivers) and populates our private HCD list
797 * In our implementation, we equate Windows' "HCD" to libusbx's "bus". Note that bus is zero indexed.
798 * HCDs are not expected to change after init (might not hold true for hot pluggable USB PCI card?)
800 static int windows_init(struct libusb_context *ctx)
802 int i, r = LIBUSB_ERROR_OTHER;
803 OSVERSIONINFO os_version;
804 HANDLE semaphore;
805 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
807 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
808 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
809 if (semaphore == NULL) {
810 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
811 return LIBUSB_ERROR_NO_MEM;
814 // A successful wait brings our semaphore count to 0 (unsignaled)
815 // => any concurent wait stalls until the semaphore's release
816 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
817 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
818 CloseHandle(semaphore);
819 return LIBUSB_ERROR_NO_MEM;
822 // NB: concurrent usage supposes that init calls are equally balanced with
823 // exit calls. If init is called more than exit, we will not exit properly
824 if ( ++concurrent_usage == 0 ) { // First init?
825 // Detect OS version
826 memset(&os_version, 0, sizeof(OSVERSIONINFO));
827 os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
828 windows_version = WINDOWS_UNSUPPORTED;
829 if ((GetVersionEx(&os_version) != 0) && (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
830 if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 1)) {
831 windows_version = WINDOWS_XP;
832 } else if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 2)) {
833 windows_version = WINDOWS_2003; // also includes XP 64
834 } else if (os_version.dwMajorVersion >= 6) {
835 windows_version = WINDOWS_VISTA_AND_LATER;
838 if (windows_version == WINDOWS_UNSUPPORTED) {
839 usbi_err(ctx, "This version of Windows is NOT supported");
840 r = LIBUSB_ERROR_NOT_SUPPORTED;
841 goto init_exit;
844 // We need a lock for proper auto-release
845 usbi_mutex_init(&autoclaim_lock, NULL);
847 // Initialize pollable file descriptors
848 init_polling();
850 // Load DLL imports
851 if (init_dlls() != LIBUSB_SUCCESS) {
852 usbi_err(ctx, "could not resolve DLL functions");
853 return LIBUSB_ERROR_NOT_FOUND;
856 // Initialize the low level APIs (we don't care about errors at this stage)
857 for (i=0; i<USB_API_MAX; i++) {
858 usb_api_backend[i].init(SUB_API_NOTSET, ctx);
861 // Because QueryPerformanceCounter might report different values when
862 // running on different cores, we create a separate thread for the timer
863 // calls, which we glue to the first core always to prevent timing discrepancies.
864 r = LIBUSB_ERROR_NO_MEM;
865 for (i = 0; i < 2; i++) {
866 timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
867 if (timer_request[i] == NULL) {
868 usbi_err(ctx, "could not create timer request event %d - aborting", i);
869 goto init_exit;
872 timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
873 if (timer_response == NULL) {
874 usbi_err(ctx, "could not create timer response semaphore - aborting");
875 goto init_exit;
877 timer_mutex = CreateMutex(NULL, FALSE, NULL);
878 if (timer_mutex == NULL) {
879 usbi_err(ctx, "could not create timer mutex - aborting");
880 goto init_exit;
882 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, NULL, 0, NULL);
883 if (timer_thread == NULL) {
884 usbi_err(ctx, "Unable to create timer thread - aborting");
885 goto init_exit;
887 SetThreadAffinityMask(timer_thread, 0);
889 // Wait for timer thread to init before continuing.
890 if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
891 usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
892 goto init_exit;
895 // Create a hash table to store session ids. Second parameter is better if prime
896 htab_create(ctx, HTAB_SIZE);
898 // At this stage, either we went through full init successfully, or didn't need to
899 r = LIBUSB_SUCCESS;
901 init_exit: // Holds semaphore here.
902 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
903 if (timer_thread) {
904 SetEvent(timer_request[1]); // actually the signal to quit the thread.
905 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
906 usbi_warn(ctx, "could not wait for timer thread to quit");
907 TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
908 // all objects it might have held anyway.
910 CloseHandle(timer_thread);
911 timer_thread = NULL;
913 for (i = 0; i < 2; i++) {
914 if (timer_request[i]) {
915 CloseHandle(timer_request[i]);
916 timer_request[i] = NULL;
919 if (timer_response) {
920 CloseHandle(timer_response);
921 timer_response = NULL;
923 if (timer_mutex) {
924 CloseHandle(timer_mutex);
925 timer_mutex = NULL;
927 htab_destroy();
930 if (r != LIBUSB_SUCCESS)
931 --concurrent_usage; // Not expected to call libusb_exit if we failed.
933 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
934 CloseHandle(semaphore);
935 return r;
939 * HCD (root) hubs need to have their device descriptor manually populated
941 * Note that, like Microsoft does in the device manager, we populate the
942 * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device.
944 static int force_hcd_device_descriptor(struct libusb_device *dev)
946 struct windows_device_priv *parent_priv, *priv = _device_priv(dev);
947 struct libusb_context *ctx = DEVICE_CTX(dev);
948 int vid, pid;
950 dev->num_configurations = 1;
951 priv->dev_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
952 priv->dev_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
953 priv->dev_descriptor.bNumConfigurations = 1;
954 priv->active_config = 1;
956 if (priv->parent_dev == NULL) {
957 usbi_err(ctx, "program assertion failed - HCD hub has no parent");
958 return LIBUSB_ERROR_NO_DEVICE;
960 parent_priv = _device_priv(priv->parent_dev);
961 if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) {
962 priv->dev_descriptor.idVendor = (uint16_t)vid;
963 priv->dev_descriptor.idProduct = (uint16_t)pid;
964 } else {
965 usbi_warn(ctx, "could not infer VID/PID of HCD hub from '%s'", parent_priv->path);
966 priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub
967 priv->dev_descriptor.idProduct = 1;
969 return LIBUSB_SUCCESS;
973 * fetch and cache all the config descriptors through I/O
975 static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char* device_id)
977 DWORD size, ret_size;
978 struct libusb_context *ctx = DEVICE_CTX(dev);
979 struct windows_device_priv *priv = _device_priv(dev);
980 int r;
981 uint8_t i;
983 USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
984 PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
985 PUSB_CONFIGURATION_DESCRIPTOR cd_data = NULL;
987 if (dev->num_configurations == 0)
988 return LIBUSB_ERROR_INVALID_PARAM;
990 priv->config_descriptor = (unsigned char**) calloc(dev->num_configurations, sizeof(unsigned char*));
991 if (priv->config_descriptor == NULL)
992 return LIBUSB_ERROR_NO_MEM;
993 for (i=0; i<dev->num_configurations; i++)
994 priv->config_descriptor[i] = NULL;
996 for (i=0, r=LIBUSB_SUCCESS; ; i++)
998 // safe loop: release all dynamic resources
999 safe_free(cd_buf_actual);
1001 // safe loop: end of loop condition
1002 if ((i >= dev->num_configurations) || (r != LIBUSB_SUCCESS))
1003 break;
1005 size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT);
1006 memset(&cd_buf_short, 0, size);
1008 cd_buf_short.req.ConnectionIndex = (ULONG)priv->port;
1009 cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1010 cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1011 cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1012 cd_buf_short.req.SetupPacket.wIndex = i;
1013 cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1015 // Dummy call to get the required data size. Initial failures are reported as info rather
1016 // than error as they can occur for non-penalizing situations, such as with some hubs.
1017 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
1018 &cd_buf_short, size, &ret_size, NULL)) {
1019 usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
1020 LOOP_BREAK(LIBUSB_ERROR_IO);
1023 if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
1024 usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
1025 LOOP_BREAK(LIBUSB_ERROR_IO);
1028 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
1029 if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
1030 usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
1031 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1033 memset(cd_buf_actual, 0, size);
1035 // Actual call
1036 cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
1037 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1038 cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1039 cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1040 cd_buf_actual->SetupPacket.wIndex = i;
1041 cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1043 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1044 cd_buf_actual, size, &ret_size, NULL)) {
1045 usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1046 LOOP_BREAK(LIBUSB_ERROR_IO);
1049 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1051 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1052 usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1053 LOOP_BREAK(LIBUSB_ERROR_IO);
1056 if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1057 usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1058 LOOP_BREAK(LIBUSB_ERROR_IO);
1061 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1062 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1064 // Cache the descriptor
1065 priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1066 if (priv->config_descriptor[i] == NULL)
1067 return LIBUSB_ERROR_NO_MEM;
1068 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1070 return LIBUSB_SUCCESS;
1074 * Populate a libusbx device structure
1076 static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1077 uint8_t port_number, char* device_id, DWORD devinst)
1079 HANDLE handle;
1080 DWORD size;
1081 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1082 struct windows_device_priv *priv, *parent_priv;
1083 struct libusb_context *ctx = DEVICE_CTX(dev);
1084 struct libusb_device* tmp_dev;
1085 unsigned i;
1087 if ((dev == NULL) || (parent_dev == NULL)) {
1088 return LIBUSB_ERROR_NOT_FOUND;
1090 priv = _device_priv(dev);
1091 parent_priv = _device_priv(parent_dev);
1092 if (parent_priv->apib->id != USB_API_HUB) {
1093 usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1094 return LIBUSB_ERROR_NOT_FOUND;
1097 // It is possible for the parent hub not to have been initialized yet
1098 // If that's the case, lookup the ancestors to set the bus number
1099 if (parent_dev->bus_number == 0) {
1100 for (i=2; ; i++) {
1101 tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
1102 if (tmp_dev == NULL) break;
1103 if (tmp_dev->bus_number != 0) {
1104 usbi_dbg("got bus number from ancestor #%d", i);
1105 parent_dev->bus_number = tmp_dev->bus_number;
1106 libusb_unref_device(tmp_dev);
1107 break;
1109 libusb_unref_device(tmp_dev);
1112 if (parent_dev->bus_number == 0) {
1113 usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1114 return LIBUSB_ERROR_NOT_FOUND;
1116 dev->bus_number = parent_dev->bus_number;
1117 priv->port = port_number;
1118 dev->port_number = port_number;
1119 priv->depth = parent_priv->depth + 1;
1120 priv->parent_dev = parent_dev;
1121 dev->parent_dev = parent_dev;
1123 // If the device address is already set, we can stop here
1124 if (dev->device_address != 0) {
1125 return LIBUSB_SUCCESS;
1127 memset(&conn_info, 0, sizeof(conn_info));
1128 if (priv->depth != 0) { // Not a HCD hub
1129 handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1130 FILE_FLAG_OVERLAPPED, NULL);
1131 if (handle == INVALID_HANDLE_VALUE) {
1132 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1133 return LIBUSB_ERROR_ACCESS;
1135 size = sizeof(conn_info);
1136 conn_info.ConnectionIndex = (ULONG)port_number;
1137 if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1138 &conn_info, size, &size, NULL)) {
1139 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1140 device_id, windows_error_str(0));
1141 safe_closehandle(handle);
1142 return LIBUSB_ERROR_NO_DEVICE;
1144 if (conn_info.ConnectionStatus == NoDeviceConnected) {
1145 usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1146 safe_closehandle(handle);
1147 return LIBUSB_ERROR_NO_DEVICE;
1149 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1150 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1151 priv->active_config = conn_info.CurrentConfigurationValue;
1152 usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1153 // If we can't read the config descriptors, just set the number of confs to zero
1154 if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1155 dev->num_configurations = 0;
1156 priv->dev_descriptor.bNumConfigurations = 0;
1158 safe_closehandle(handle);
1160 if (conn_info.DeviceAddress > UINT8_MAX) {
1161 usbi_err(ctx, "program assertion failed: device address overflow");
1163 dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1164 if (dev->device_address == 1) {
1165 usbi_err(ctx, "program assertion failed: device address collision with root hub");
1167 switch (conn_info.Speed) {
1168 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1169 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1170 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1171 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1172 default:
1173 usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1174 break;
1176 } else {
1177 dev->device_address = 1; // root hubs are set to use device number 1
1178 force_hcd_device_descriptor(dev);
1181 usbi_sanitize_device(dev);
1183 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1184 dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1186 return LIBUSB_SUCCESS;
1189 // Returns the api type, or 0 if not found/unsupported
1190 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1191 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1193 // Precedence for filter drivers vs driver is in the order of this array
1194 struct driver_lookup lookup[3] = {
1195 {"\0\0", SPDRP_SERVICE, "driver"},
1196 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1197 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1199 DWORD size, reg_type;
1200 unsigned k, l;
1201 int i, j;
1203 *api = USB_API_UNSUPPORTED;
1204 *sub_api = SUB_API_NOTSET;
1205 // Check the service & filter names to know the API we should use
1206 for (k=0; k<3; k++) {
1207 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1208 &reg_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1209 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1210 if (lookup[k].reg_prop == SPDRP_SERVICE) {
1211 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1212 lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1214 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1215 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1216 // (currently ';'), so even if an unsuported one does, it's not an issue
1217 for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1218 if (lookup[k].list[l] == 0) {
1219 lookup[k].list[l] = LIST_SEPARATOR;
1222 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1223 } else {
1224 if (GetLastError() != ERROR_INVALID_DATA) {
1225 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1227 lookup[k].list[0] = 0;
1231 for (i=1; i<USB_API_MAX; i++) {
1232 for (k=0; k<3; k++) {
1233 j = get_sub_api(lookup[k].list, i);
1234 if (j >= 0) {
1235 usbi_dbg("matched %s name against %s API",
1236 lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1237 *api = i;
1238 *sub_api = j;
1239 return;
1245 static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1246 char* dev_interface_path, char* device_id, int api, int sub_api)
1248 unsigned i;
1249 struct windows_device_priv *priv = _device_priv(dev);
1250 int interface_number;
1252 if (priv->apib->id != USB_API_COMPOSITE) {
1253 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1254 return LIBUSB_ERROR_NO_DEVICE;
1257 // Because MI_## are not necessarily in sequential order (some composite
1258 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1259 // interface number from the path's MI value
1260 interface_number = 0;
1261 for (i=0; device_id[i] != 0; ) {
1262 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1263 && (device_id[i++] == '_') ) {
1264 interface_number = (device_id[i++] - '0')*10;
1265 interface_number += device_id[i] - '0';
1266 break;
1270 if (device_id[i] == 0) {
1271 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1272 device_id, interface_number);
1275 if (priv->usb_interface[interface_number].path != NULL) {
1276 if (api == USB_API_HID) {
1277 // HID devices can have multiple collections (COL##) for each MI_## interface
1278 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1279 interface_number, device_id);
1280 return LIBUSB_ERROR_ACCESS;
1282 // In other cases, just use the latest data
1283 safe_free(priv->usb_interface[interface_number].path);
1286 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1287 priv->usb_interface[interface_number].path = dev_interface_path;
1288 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1289 priv->usb_interface[interface_number].sub_api = sub_api;
1290 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1291 priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
1292 if (priv->hid == NULL)
1293 return LIBUSB_ERROR_NO_MEM;
1296 return LIBUSB_SUCCESS;
1299 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1300 char* dev_interface_path)
1302 int i;
1303 struct windows_device_priv *priv = _device_priv(dev);
1305 if (priv->hid == NULL) {
1306 usbi_err(ctx, "program assertion failed: parent is not HID");
1307 return LIBUSB_ERROR_NO_DEVICE;
1309 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1310 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1311 return LIBUSB_ERROR_NO_DEVICE;
1313 for (i=0; i<priv->hid->nb_interfaces; i++) {
1314 if (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
1315 usbi_dbg("interface[%d] already set to %s", i, dev_interface_path);
1316 return LIBUSB_SUCCESS;
1320 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1321 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1322 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1323 priv->hid->nb_interfaces++;
1324 return LIBUSB_SUCCESS;
1328 * get_device_list: libusbx backend device enumeration function
1330 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1332 struct discovered_devs *discdevs;
1333 HDEVINFO dev_info = { 0 };
1334 const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1335 SP_DEVINFO_DATA dev_info_data = { 0 };
1336 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1337 GUID hid_guid;
1338 #define MAX_ENUM_GUIDS 64
1339 const GUID* guid[MAX_ENUM_GUIDS];
1340 #define HCD_PASS 0
1341 #define HUB_PASS 1
1342 #define GEN_PASS 2
1343 #define DEV_PASS 3
1344 #define HID_PASS 4
1345 int r = LIBUSB_SUCCESS;
1346 int api, sub_api;
1347 size_t class_index = 0;
1348 unsigned int nb_guids, pass, i, j, ancestor;
1349 char path[MAX_PATH_LENGTH];
1350 char strbuf[MAX_PATH_LENGTH];
1351 struct libusb_device *dev, *parent_dev;
1352 struct windows_device_priv *priv, *parent_priv;
1353 char* dev_interface_path = NULL;
1354 char* dev_id_path = NULL;
1355 unsigned long session_id;
1356 DWORD size, reg_type, port_nr, install_state;
1357 HKEY key;
1358 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1359 GUID* if_guid;
1360 LONG s;
1361 // Keep a list of newly allocated devs to unref
1362 libusb_device** unref_list;
1363 unsigned int unref_size = 64;
1364 unsigned int unref_cur = 0;
1366 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1367 // PASS 2 : (re)enumerate HUBS
1368 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1369 // and list additional USB device interface GUIDs to explore
1370 // PASS 4 : (re)enumerate master USB devices that have a device interface
1371 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1372 // set the device interfaces.
1374 // Init the GUID table
1375 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1376 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1377 guid[GEN_PASS] = NULL;
1378 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1379 HidD_GetHidGuid(&hid_guid);
1380 guid[HID_PASS] = &hid_guid;
1381 nb_guids = HID_PASS+1;
1383 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1384 if (unref_list == NULL) {
1385 return LIBUSB_ERROR_NO_MEM;
1388 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1389 //#define ENUM_DEBUG
1390 #ifdef ENUM_DEBUG
1391 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1392 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1393 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1394 #endif
1395 for (i = 0; ; i++) {
1396 // safe loop: free up any (unprotected) dynamic resource
1397 // NB: this is always executed before breaking the loop
1398 safe_free(dev_interface_details);
1399 safe_free(dev_interface_path);
1400 safe_free(dev_id_path);
1401 priv = parent_priv = NULL;
1402 dev = parent_dev = NULL;
1404 // Safe loop: end of loop conditions
1405 if (r != LIBUSB_SUCCESS) {
1406 break;
1408 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1409 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1410 break;
1412 if (pass != GEN_PASS) {
1413 // Except for GEN, all passes deal with device interfaces
1414 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1415 if (dev_interface_details == NULL) {
1416 break;
1417 } else {
1418 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1419 if (dev_interface_path == NULL) {
1420 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1421 continue;
1424 } else {
1425 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1426 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1427 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1428 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1429 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1430 break;
1431 i = 0;
1433 if (class_index >= ARRAYSIZE(usb_class))
1434 break;
1437 // Read the Device ID path. This is what we'll use as UID
1438 // Note that if the device is plugged in a different port or hub, the Device ID changes
1439 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1440 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1441 dev_info_data.DevInst);
1442 continue;
1444 dev_id_path = sanitize_path(path);
1445 if (dev_id_path == NULL) {
1446 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1447 dev_info_data.DevInst);
1448 continue;
1450 #ifdef ENUM_DEBUG
1451 usbi_dbg("PRO: %s", dev_id_path);
1452 #endif
1454 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1455 port_nr = 0;
1456 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1457 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1458 &reg_type, (BYTE*)&port_nr, 4, &size))
1459 || (size != 4) ) {
1460 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1461 dev_id_path, windows_error_str(0));
1462 continue;
1466 // Set API to use or get additional data from generic pass
1467 api = USB_API_UNSUPPORTED;
1468 sub_api = SUB_API_NOTSET;
1469 switch (pass) {
1470 case HCD_PASS:
1471 break;
1472 case GEN_PASS:
1473 // We use the GEN pass to detect driverless devices...
1474 size = sizeof(strbuf);
1475 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1476 &reg_type, (BYTE*)strbuf, size, &size)) {
1477 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1478 usbi_info(ctx, "libusbx will not be able to access it.");
1480 // ...and to add the additional device interface GUIDs
1481 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1482 if (key != INVALID_HANDLE_VALUE) {
1483 size = sizeof(guid_string_w);
1484 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, &reg_type,
1485 (BYTE*)guid_string_w, &size);
1486 pRegCloseKey(key);
1487 if (s == ERROR_SUCCESS) {
1488 if (nb_guids >= MAX_ENUM_GUIDS) {
1489 // If this assert is ever reported, grow a GUID table dynamically
1490 usbi_err(ctx, "program assertion failed: too many GUIDs");
1491 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1493 if_guid = (GUID*) calloc(1, sizeof(GUID));
1494 pCLSIDFromString(guid_string_w, if_guid);
1495 guid[nb_guids++] = if_guid;
1496 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1499 break;
1500 case HID_PASS:
1501 api = USB_API_HID;
1502 break;
1503 default:
1504 // Get the API type (after checking that the driver installation is OK)
1505 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1506 &reg_type, (BYTE*)&install_state, 4, &size))
1507 || (size != 4) ){
1508 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1509 dev_id_path, windows_error_str(0));
1510 } else if (install_state != 0) {
1511 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1512 dev_id_path, install_state);
1513 continue;
1515 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1516 break;
1519 // Find parent device (for the passes that need it)
1520 switch (pass) {
1521 case HCD_PASS:
1522 case DEV_PASS:
1523 case HUB_PASS:
1524 break;
1525 default:
1526 // Go through the ancestors until we see a face we recognize
1527 parent_dev = NULL;
1528 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1529 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1530 if (session_id == 0) {
1531 break;
1533 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1535 if (parent_dev == NULL) {
1536 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1537 continue;
1539 parent_priv = _device_priv(parent_dev);
1540 // virtual USB devices are also listed during GEN - don't process these yet
1541 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1542 libusb_unref_device(parent_dev);
1543 continue;
1545 break;
1548 // Create new or match existing device, using the (hashed) device_id as session id
1549 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1550 // These are the passes that create "new" devices
1551 session_id = htab_hash(dev_id_path);
1552 dev = usbi_get_device_by_session_id(ctx, session_id);
1553 if (dev == NULL) {
1554 if (pass == DEV_PASS) {
1555 // This can occur if the OS only reports a newly plugged device after we started enum
1556 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1557 " - ignoring", dev_id_path);
1558 continue;
1560 usbi_dbg("allocating new device for session [%X]", session_id);
1561 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1562 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1564 windows_device_priv_init(dev);
1565 } else {
1566 usbi_dbg("found existing device for session [%X] (%d.%d)",
1567 session_id, dev->bus_number, dev->device_address);
1569 // Keep track of devices that need unref
1570 unref_list[unref_cur++] = dev;
1571 if (unref_cur >= unref_size) {
1572 unref_size += 64;
1573 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1574 if (unref_list == NULL) {
1575 usbi_err(ctx, "could not realloc list for unref - aborting.");
1576 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1579 priv = _device_priv(dev);
1582 // Setup device
1583 switch (pass) {
1584 case HCD_PASS:
1585 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1586 dev->device_address = 0;
1587 dev->num_configurations = 0;
1588 priv->apib = &usb_api_backend[USB_API_HUB];
1589 priv->sub_api = SUB_API_NOTSET;
1590 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1591 priv->path = dev_interface_path; dev_interface_path = NULL;
1592 break;
1593 case HUB_PASS:
1594 case DEV_PASS:
1595 // If the device has already been setup, don't do it again
1596 if (priv->path != NULL)
1597 break;
1598 // Take care of API initialization
1599 priv->path = dev_interface_path; dev_interface_path = NULL;
1600 priv->apib = &usb_api_backend[api];
1601 priv->sub_api = sub_api;
1602 switch(api) {
1603 case USB_API_COMPOSITE:
1604 case USB_API_HUB:
1605 break;
1606 case USB_API_HID:
1607 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1608 if (priv->hid == NULL) {
1609 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1611 priv->hid->nb_interfaces = 0;
1612 break;
1613 default:
1614 // For other devices, the first interface is the same as the device
1615 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1616 if (priv->usb_interface[0].path != NULL) {
1617 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1618 } else {
1619 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1621 // The following is needed if we want API calls to work for both simple
1622 // and composite devices.
1623 for(j=0; j<USB_MAXINTERFACES; j++) {
1624 priv->usb_interface[j].apib = &usb_api_backend[api];
1626 break;
1628 break;
1629 case GEN_PASS:
1630 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1631 if (r == LIBUSB_SUCCESS) {
1632 // Append device to the list of discovered devices
1633 discdevs = discovered_devs_append(*_discdevs, dev);
1634 if (!discdevs) {
1635 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1637 *_discdevs = discdevs;
1638 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1639 // This can occur if the device was disconnected but Windows hasn't
1640 // refreshed its enumeration yet - in that case, we ignore the device
1641 r = LIBUSB_SUCCESS;
1643 break;
1644 default: // HID_PASS and later
1645 if (parent_priv->apib->id == USB_API_HID) {
1646 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1647 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1648 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1649 dev_interface_path = NULL;
1650 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1651 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1652 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1653 case LIBUSB_SUCCESS:
1654 dev_interface_path = NULL;
1655 break;
1656 case LIBUSB_ERROR_ACCESS:
1657 // interface has already been set => make sure dev_interface_path is freed then
1658 break;
1659 default:
1660 LOOP_BREAK(r);
1661 break;
1664 libusb_unref_device(parent_dev);
1665 break;
1670 // Free any additional GUIDs
1671 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1672 safe_free(guid[pass]);
1675 // Unref newly allocated devs
1676 for (i=0; i<unref_cur; i++) {
1677 safe_unref_device(unref_list[i]);
1679 safe_free(unref_list);
1681 return r;
1685 * exit: libusbx backend deinitialization function
1687 static void windows_exit(void)
1689 int i;
1690 HANDLE semaphore;
1691 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1693 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1694 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1695 if (semaphore == NULL) {
1696 return;
1699 // A successful wait brings our semaphore count to 0 (unsignaled)
1700 // => any concurent wait stalls until the semaphore release
1701 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1702 CloseHandle(semaphore);
1703 return;
1706 // Only works if exits and inits are balanced exactly
1707 if (--concurrent_usage < 0) { // Last exit
1708 for (i=0; i<USB_API_MAX; i++) {
1709 usb_api_backend[i].exit(SUB_API_NOTSET);
1711 exit_polling();
1713 if (timer_thread) {
1714 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1715 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1716 usbi_dbg("could not wait for timer thread to quit");
1717 TerminateThread(timer_thread, 1);
1719 CloseHandle(timer_thread);
1720 timer_thread = NULL;
1722 for (i = 0; i < 2; i++) {
1723 if (timer_request[i]) {
1724 CloseHandle(timer_request[i]);
1725 timer_request[i] = NULL;
1728 if (timer_response) {
1729 CloseHandle(timer_response);
1730 timer_response = NULL;
1732 if (timer_mutex) {
1733 CloseHandle(timer_mutex);
1734 timer_mutex = NULL;
1736 htab_destroy();
1739 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1740 CloseHandle(semaphore);
1743 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1745 struct windows_device_priv *priv = _device_priv(dev);
1747 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1748 *host_endian = 0;
1750 return LIBUSB_SUCCESS;
1753 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1755 struct windows_device_priv *priv = _device_priv(dev);
1756 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1757 size_t size;
1759 // config index is zero based
1760 if (config_index >= dev->num_configurations)
1761 return LIBUSB_ERROR_INVALID_PARAM;
1763 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1764 return LIBUSB_ERROR_NOT_FOUND;
1766 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1768 size = min(config_header->wTotalLength, len);
1769 memcpy(buffer, priv->config_descriptor[config_index], size);
1770 *host_endian = 0;
1772 return (int)size;
1776 * return the cached copy of the active config descriptor
1778 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1780 struct windows_device_priv *priv = _device_priv(dev);
1782 if (priv->active_config == 0)
1783 return LIBUSB_ERROR_NOT_FOUND;
1785 // config index is zero based
1786 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1789 static int windows_open(struct libusb_device_handle *dev_handle)
1791 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1792 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1794 if (priv->apib == NULL) {
1795 usbi_err(ctx, "program assertion failed - device is not initialized");
1796 return LIBUSB_ERROR_NO_DEVICE;
1799 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1802 static void windows_close(struct libusb_device_handle *dev_handle)
1804 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1806 priv->apib->close(SUB_API_NOTSET, dev_handle);
1809 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1811 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1813 if (priv->active_config == 0) {
1814 *config = 0;
1815 return LIBUSB_ERROR_NOT_FOUND;
1818 *config = priv->active_config;
1819 return LIBUSB_SUCCESS;
1823 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1824 * does not currently expose a service that allows higher-level drivers to set
1825 * the configuration."
1827 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1829 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1830 int r = LIBUSB_SUCCESS;
1832 if (config >= USB_MAXCONFIG)
1833 return LIBUSB_ERROR_INVALID_PARAM;
1835 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1836 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1837 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1838 0, NULL, 0, 1000);
1840 if (r == LIBUSB_SUCCESS) {
1841 priv->active_config = (uint8_t)config;
1843 return r;
1846 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1848 int r = LIBUSB_SUCCESS;
1849 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1851 if (iface >= USB_MAXINTERFACES)
1852 return LIBUSB_ERROR_INVALID_PARAM;
1854 safe_free(priv->usb_interface[iface].endpoint);
1855 priv->usb_interface[iface].nb_endpoints= 0;
1857 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1859 if (r == LIBUSB_SUCCESS) {
1860 r = windows_assign_endpoints(dev_handle, iface, 0);
1863 return r;
1866 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1868 int r = LIBUSB_SUCCESS;
1869 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1871 safe_free(priv->usb_interface[iface].endpoint);
1872 priv->usb_interface[iface].nb_endpoints= 0;
1874 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1876 if (r == LIBUSB_SUCCESS) {
1877 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1880 return r;
1883 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1885 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1887 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1890 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1892 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1893 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1896 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1898 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1899 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1902 // The 3 functions below are unlikely to ever get supported on Windows
1903 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1905 return LIBUSB_ERROR_NOT_SUPPORTED;
1908 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1910 return LIBUSB_ERROR_NOT_SUPPORTED;
1913 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1915 return LIBUSB_ERROR_NOT_SUPPORTED;
1918 static void windows_destroy_device(struct libusb_device *dev)
1920 windows_device_priv_release(dev);
1923 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1925 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1927 usbi_free_fd(&transfer_priv->pollable_fd);
1928 safe_free(transfer_priv->hid_buffer);
1929 // When auto claim is in use, attempt to release the auto-claimed interface
1930 auto_release(itransfer);
1933 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1935 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1936 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1937 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1938 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1939 int r;
1941 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1942 if (r != LIBUSB_SUCCESS) {
1943 return r;
1946 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1947 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1949 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1950 return LIBUSB_SUCCESS;
1953 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1955 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1956 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1957 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1958 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1959 int r;
1961 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1962 if (r != LIBUSB_SUCCESS) {
1963 return r;
1966 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1967 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1969 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1970 return LIBUSB_SUCCESS;
1973 static int submit_control_transfer(struct usbi_transfer *itransfer)
1975 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1976 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1977 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1978 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1979 int r;
1981 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1982 if (r != LIBUSB_SUCCESS) {
1983 return r;
1986 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
1988 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1989 return LIBUSB_SUCCESS;
1993 static int windows_submit_transfer(struct usbi_transfer *itransfer)
1995 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1997 switch (transfer->type) {
1998 case LIBUSB_TRANSFER_TYPE_CONTROL:
1999 return submit_control_transfer(itransfer);
2000 case LIBUSB_TRANSFER_TYPE_BULK:
2001 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2002 if (IS_XFEROUT(transfer) &&
2003 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
2004 return LIBUSB_ERROR_NOT_SUPPORTED;
2005 return submit_bulk_transfer(itransfer);
2006 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2007 return submit_iso_transfer(itransfer);
2008 default:
2009 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2010 return LIBUSB_ERROR_INVALID_PARAM;
2014 static int windows_abort_control(struct usbi_transfer *itransfer)
2016 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2017 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2019 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2022 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2024 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2025 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2027 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2030 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2032 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2034 switch (transfer->type) {
2035 case LIBUSB_TRANSFER_TYPE_CONTROL:
2036 return windows_abort_control(itransfer);
2037 case LIBUSB_TRANSFER_TYPE_BULK:
2038 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2039 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2040 return windows_abort_transfers(itransfer);
2041 default:
2042 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2043 return LIBUSB_ERROR_INVALID_PARAM;
2047 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2049 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2050 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2051 int status, istatus;
2053 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
2055 switch(io_result) {
2056 case NO_ERROR:
2057 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2058 break;
2059 case ERROR_GEN_FAILURE:
2060 usbi_dbg("detected endpoint stall");
2061 status = LIBUSB_TRANSFER_STALL;
2062 break;
2063 case ERROR_SEM_TIMEOUT:
2064 usbi_dbg("detected semaphore timeout");
2065 status = LIBUSB_TRANSFER_TIMED_OUT;
2066 break;
2067 case ERROR_OPERATION_ABORTED:
2068 istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2069 if (istatus != LIBUSB_TRANSFER_COMPLETED) {
2070 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
2072 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2073 usbi_dbg("detected timeout");
2074 status = LIBUSB_TRANSFER_TIMED_OUT;
2075 } else {
2076 usbi_dbg("detected operation aborted");
2077 status = LIBUSB_TRANSFER_CANCELLED;
2079 break;
2080 default:
2081 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(0));
2082 status = LIBUSB_TRANSFER_ERROR;
2083 break;
2085 windows_clear_transfer_priv(itransfer); // Cancel polling
2086 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2089 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2091 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2093 switch (transfer->type) {
2094 case LIBUSB_TRANSFER_TYPE_CONTROL:
2095 case LIBUSB_TRANSFER_TYPE_BULK:
2096 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2097 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2098 windows_transfer_callback (itransfer, io_result, io_size);
2099 break;
2100 default:
2101 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2105 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2107 struct windows_transfer_priv* transfer_priv = NULL;
2108 POLL_NFDS_TYPE i = 0;
2109 bool found = false;
2110 struct usbi_transfer *transfer;
2111 DWORD io_size, io_result;
2113 usbi_mutex_lock(&ctx->open_devs_lock);
2114 for (i = 0; i < nfds && num_ready > 0; i++) {
2116 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2118 if (!fds[i].revents) {
2119 continue;
2122 num_ready--;
2124 // Because a Windows OVERLAPPED is used for poll emulation,
2125 // a pollable fd is created and stored with each transfer
2126 usbi_mutex_lock(&ctx->flying_transfers_lock);
2127 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2128 transfer_priv = usbi_transfer_get_os_priv(transfer);
2129 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2130 found = true;
2131 break;
2134 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2136 if (found) {
2137 // Handle async requests that completed synchronously first
2138 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2139 io_result = NO_ERROR;
2140 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2141 // Regular async overlapped
2142 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2143 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2144 io_result = NO_ERROR;
2145 } else {
2146 io_result = GetLastError();
2148 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2149 // let handle_callback free the event using the transfer wfd
2150 // If you don't use the transfer wfd, you run a risk of trying to free a
2151 // newly allocated wfd that took the place of the one from the transfer.
2152 windows_handle_callback(transfer, io_result, io_size);
2153 } else {
2154 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2155 return LIBUSB_ERROR_NOT_FOUND;
2159 usbi_mutex_unlock(&ctx->open_devs_lock);
2160 return LIBUSB_SUCCESS;
2164 * Monotonic and real time functions
2166 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2168 LARGE_INTEGER hires_counter, li_frequency;
2169 LONG nb_responses;
2170 int timer_index;
2172 // Init - find out if we have access to a monotonic (hires) timer
2173 if (!QueryPerformanceFrequency(&li_frequency)) {
2174 usbi_dbg("no hires timer available on this platform");
2175 hires_frequency = 0;
2176 hires_ticks_to_ps = UINT64_C(0);
2177 } else {
2178 hires_frequency = li_frequency.QuadPart;
2179 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2180 // to picoseconds to compute the tv_nsecs part in clock_gettime
2181 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2182 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2185 // Signal windows_init() that we're ready to service requests
2186 if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
2187 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2190 // Main loop - wait for requests
2191 while (1) {
2192 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2193 if ( (timer_index != 0) && (timer_index != 1) ) {
2194 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2195 continue;
2197 if (request_count[timer_index] == 0) {
2198 // Request already handled
2199 ResetEvent(timer_request[timer_index]);
2200 // There's still a possiblity that a thread sends a request between the
2201 // time we test request_count[] == 0 and we reset the event, in which case
2202 // the request would be ignored. The simple solution to that is to test
2203 // request_count again and process requests if non zero.
2204 if (request_count[timer_index] == 0)
2205 continue;
2207 switch (timer_index) {
2208 case 0:
2209 WaitForSingleObject(timer_mutex, INFINITE);
2210 // Requests to this thread are for hires always
2211 if (QueryPerformanceCounter(&hires_counter) != 0) {
2212 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2213 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2214 } else {
2215 // Fallback to real-time if we can't get monotonic value
2216 // Note that real-time clock does not wait on the mutex or this thread.
2217 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2219 ReleaseMutex(timer_mutex);
2221 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2222 if ( (nb_responses)
2223 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2224 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2226 continue;
2227 case 1: // time to quit
2228 usbi_dbg("timer thread quitting");
2229 return 0;
2234 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2236 FILETIME filetime;
2237 ULARGE_INTEGER rtime;
2238 DWORD r;
2239 switch(clk_id) {
2240 case USBI_CLOCK_MONOTONIC:
2241 if (hires_frequency != 0) {
2242 while (1) {
2243 InterlockedIncrement((LONG*)&request_count[0]);
2244 SetEvent(timer_request[0]);
2245 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2246 switch(r) {
2247 case WAIT_OBJECT_0:
2248 WaitForSingleObject(timer_mutex, INFINITE);
2249 *tp = timer_tp;
2250 ReleaseMutex(timer_mutex);
2251 return LIBUSB_SUCCESS;
2252 case WAIT_TIMEOUT:
2253 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2254 break; // Retry until successful
2255 default:
2256 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2257 return LIBUSB_ERROR_OTHER;
2261 // Fall through and return real-time if monotonic was not detected @ timer init
2262 case USBI_CLOCK_REALTIME:
2263 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2264 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2265 // Note however that our resolution is bounded by the Windows system time
2266 // functions and is at best of the order of 1 ms (or, usually, worse)
2267 GetSystemTimeAsFileTime(&filetime);
2268 rtime.LowPart = filetime.dwLowDateTime;
2269 rtime.HighPart = filetime.dwHighDateTime;
2270 rtime.QuadPart -= epoch_time;
2271 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2272 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2273 return LIBUSB_SUCCESS;
2274 default:
2275 return LIBUSB_ERROR_INVALID_PARAM;
2280 // NB: MSVC6 does not support named initializers.
2281 const struct usbi_os_backend windows_backend = {
2282 "Windows",
2283 USBI_CAP_HAS_HID_ACCESS,
2284 windows_init,
2285 windows_exit,
2287 windows_get_device_list,
2288 NULL, /* hotplug_poll */
2289 windows_open,
2290 windows_close,
2292 windows_get_device_descriptor,
2293 windows_get_active_config_descriptor,
2294 windows_get_config_descriptor,
2295 NULL, /* get_config_descriptor_by_value() */
2297 windows_get_configuration,
2298 windows_set_configuration,
2299 windows_claim_interface,
2300 windows_release_interface,
2302 windows_set_interface_altsetting,
2303 windows_clear_halt,
2304 windows_reset_device,
2306 windows_kernel_driver_active,
2307 windows_detach_kernel_driver,
2308 windows_attach_kernel_driver,
2310 windows_destroy_device,
2312 windows_submit_transfer,
2313 windows_cancel_transfer,
2314 windows_clear_transfer_priv,
2316 windows_handle_events,
2318 windows_clock_gettime,
2319 #if defined(USBI_TIMERFD_AVAILABLE)
2320 NULL,
2321 #endif
2322 sizeof(struct windows_device_priv),
2323 sizeof(struct windows_device_handle_priv),
2324 sizeof(struct windows_transfer_priv),
2330 * USB API backends
2332 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2333 return LIBUSB_SUCCESS;
2335 static int unsupported_exit(int sub_api) {
2336 return LIBUSB_SUCCESS;
2338 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2339 PRINT_UNSUPPORTED_API(open);
2341 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2342 usbi_dbg("unsupported API call for 'close'");
2344 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2345 PRINT_UNSUPPORTED_API(configure_endpoints);
2347 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2348 PRINT_UNSUPPORTED_API(claim_interface);
2350 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2351 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2353 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2354 PRINT_UNSUPPORTED_API(release_interface);
2356 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2357 PRINT_UNSUPPORTED_API(clear_halt);
2359 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2360 PRINT_UNSUPPORTED_API(reset_device);
2362 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2363 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2365 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2366 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2368 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2369 PRINT_UNSUPPORTED_API(submit_control_transfer);
2371 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2372 PRINT_UNSUPPORTED_API(abort_control);
2374 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2375 PRINT_UNSUPPORTED_API(abort_transfers);
2377 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2378 PRINT_UNSUPPORTED_API(copy_transfer_data);
2380 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2381 return LIBUSB_SUCCESS;
2383 // These names must be uppercase
2384 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2385 const char* composite_driver_names[] = {"USBCCGP"};
2386 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2387 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2388 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2390 USB_API_UNSUPPORTED,
2391 "Unsupported API",
2392 NULL,
2394 unsupported_init,
2395 unsupported_exit,
2396 unsupported_open,
2397 unsupported_close,
2398 unsupported_configure_endpoints,
2399 unsupported_claim_interface,
2400 unsupported_set_interface_altsetting,
2401 unsupported_release_interface,
2402 unsupported_clear_halt,
2403 unsupported_reset_device,
2404 unsupported_submit_bulk_transfer,
2405 unsupported_submit_iso_transfer,
2406 unsupported_submit_control_transfer,
2407 unsupported_abort_control,
2408 unsupported_abort_transfers,
2409 unsupported_copy_transfer_data,
2410 }, {
2411 USB_API_HUB,
2412 "HUB API",
2413 hub_driver_names,
2414 ARRAYSIZE(hub_driver_names),
2415 unsupported_init,
2416 unsupported_exit,
2417 unsupported_open,
2418 unsupported_close,
2419 unsupported_configure_endpoints,
2420 unsupported_claim_interface,
2421 unsupported_set_interface_altsetting,
2422 unsupported_release_interface,
2423 unsupported_clear_halt,
2424 unsupported_reset_device,
2425 unsupported_submit_bulk_transfer,
2426 unsupported_submit_iso_transfer,
2427 unsupported_submit_control_transfer,
2428 unsupported_abort_control,
2429 unsupported_abort_transfers,
2430 unsupported_copy_transfer_data,
2431 }, {
2432 USB_API_COMPOSITE,
2433 "Composite API",
2434 composite_driver_names,
2435 ARRAYSIZE(composite_driver_names),
2436 composite_init,
2437 composite_exit,
2438 composite_open,
2439 composite_close,
2440 common_configure_endpoints,
2441 composite_claim_interface,
2442 composite_set_interface_altsetting,
2443 composite_release_interface,
2444 composite_clear_halt,
2445 composite_reset_device,
2446 composite_submit_bulk_transfer,
2447 composite_submit_iso_transfer,
2448 composite_submit_control_transfer,
2449 composite_abort_control,
2450 composite_abort_transfers,
2451 composite_copy_transfer_data,
2452 }, {
2453 USB_API_WINUSBX,
2454 "WinUSB-like APIs",
2455 winusbx_driver_names,
2456 ARRAYSIZE(winusbx_driver_names),
2457 winusbx_init,
2458 winusbx_exit,
2459 winusbx_open,
2460 winusbx_close,
2461 winusbx_configure_endpoints,
2462 winusbx_claim_interface,
2463 winusbx_set_interface_altsetting,
2464 winusbx_release_interface,
2465 winusbx_clear_halt,
2466 winusbx_reset_device,
2467 winusbx_submit_bulk_transfer,
2468 unsupported_submit_iso_transfer,
2469 winusbx_submit_control_transfer,
2470 winusbx_abort_control,
2471 winusbx_abort_transfers,
2472 winusbx_copy_transfer_data,
2473 }, {
2474 USB_API_HID,
2475 "HID API",
2476 hid_driver_names,
2477 ARRAYSIZE(hid_driver_names),
2478 hid_init,
2479 hid_exit,
2480 hid_open,
2481 hid_close,
2482 common_configure_endpoints,
2483 hid_claim_interface,
2484 hid_set_interface_altsetting,
2485 hid_release_interface,
2486 hid_clear_halt,
2487 hid_reset_device,
2488 hid_submit_bulk_transfer,
2489 unsupported_submit_iso_transfer,
2490 hid_submit_control_transfer,
2491 hid_abort_transfers,
2492 hid_abort_transfers,
2493 hid_copy_transfer_data,
2499 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2501 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2502 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2504 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2506 HMODULE h = NULL;
2507 bool native_winusb = false;
2508 int i;
2509 KLIB_VERSION LibK_Version;
2510 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2511 LibK_GetVersion_t pLibK_GetVersion = NULL;
2513 h = GetModuleHandleA("libusbK");
2514 if (h == NULL) {
2515 h = LoadLibraryA("libusbK");
2517 if (h == NULL) {
2518 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2519 h = GetModuleHandleA("WinUSB");
2520 if (h == NULL) {
2521 h = LoadLibraryA("WinUSB");
2522 } if (h == NULL) {
2523 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2524 "you will not be able to access devices outside of enumeration");
2525 return LIBUSB_ERROR_NOT_FOUND;
2527 } else {
2528 usbi_dbg("using libusbK DLL for universal access");
2529 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2530 if (pLibK_GetVersion != NULL) {
2531 pLibK_GetVersion(&LibK_Version);
2532 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2533 LibK_Version.Micro, LibK_Version.Nano);
2535 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2536 if (pLibK_GetProcAddress == NULL) {
2537 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2538 return LIBUSB_ERROR_NOT_FOUND;
2541 native_winusb = (pLibK_GetProcAddress == NULL);
2542 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2543 WinUSBX_Set(AbortPipe);
2544 WinUSBX_Set(ControlTransfer);
2545 WinUSBX_Set(FlushPipe);
2546 WinUSBX_Set(Free);
2547 WinUSBX_Set(GetAssociatedInterface);
2548 WinUSBX_Set(GetCurrentAlternateSetting);
2549 WinUSBX_Set(GetDescriptor);
2550 WinUSBX_Set(GetOverlappedResult);
2551 WinUSBX_Set(GetPipePolicy);
2552 WinUSBX_Set(GetPowerPolicy);
2553 WinUSBX_Set(Initialize);
2554 WinUSBX_Set(QueryDeviceInformation);
2555 WinUSBX_Set(QueryInterfaceSettings);
2556 WinUSBX_Set(QueryPipe);
2557 WinUSBX_Set(ReadPipe);
2558 WinUSBX_Set(ResetPipe);
2559 WinUSBX_Set(SetCurrentAlternateSetting);
2560 WinUSBX_Set(SetPipePolicy);
2561 WinUSBX_Set(SetPowerPolicy);
2562 WinUSBX_Set(WritePipe);
2563 if (!native_winusb) {
2564 WinUSBX_Set(ResetDevice);
2566 if (WinUSBX[i].Initialize != NULL) {
2567 WinUSBX[i].initialized = true;
2568 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2569 } else {
2570 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2571 WinUSBX[i].initialized = false;
2574 return LIBUSB_SUCCESS;
2577 static int winusbx_exit(int sub_api)
2579 return LIBUSB_SUCCESS;
2582 // NB: open and close must ensure that they only handle interface of
2583 // the right API type, as these functions can be called wholesale from
2584 // composite_open(), with interfaces belonging to different APIs
2585 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2587 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2588 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2589 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2591 HANDLE file_handle;
2592 int i;
2594 CHECK_WINUSBX_AVAILABLE(sub_api);
2596 // WinUSB requires a seperate handle for each interface
2597 for (i = 0; i < USB_MAXINTERFACES; i++) {
2598 if ( (priv->usb_interface[i].path != NULL)
2599 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2600 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2601 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2602 if (file_handle == INVALID_HANDLE_VALUE) {
2603 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2604 switch(GetLastError()) {
2605 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2606 return LIBUSB_ERROR_NO_DEVICE;
2607 case ERROR_ACCESS_DENIED:
2608 return LIBUSB_ERROR_ACCESS;
2609 default:
2610 return LIBUSB_ERROR_IO;
2613 handle_priv->interface_handle[i].dev_handle = file_handle;
2617 return LIBUSB_SUCCESS;
2620 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2622 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2623 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2624 HANDLE file_handle;
2625 int i;
2627 if (sub_api == SUB_API_NOTSET)
2628 sub_api = priv->sub_api;
2629 if (!WinUSBX[sub_api].initialized)
2630 return;
2632 for (i = 0; i < USB_MAXINTERFACES; i++) {
2633 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2634 file_handle = handle_priv->interface_handle[i].dev_handle;
2635 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2636 CloseHandle(file_handle);
2642 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2644 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2645 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2646 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2647 UCHAR policy;
2648 ULONG timeout = 0;
2649 uint8_t endpoint_address;
2650 int i;
2652 CHECK_WINUSBX_AVAILABLE(sub_api);
2654 // With handle and enpoints set (in parent), we can setup the default pipe properties
2655 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2656 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2657 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2658 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2659 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2660 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2662 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2663 continue; // Other policies don't apply to control endpoint or libusb0
2665 policy = false;
2666 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2667 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2668 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2670 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2671 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2672 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2674 policy = true;
2675 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2676 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2677 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2678 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2679 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2681 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2682 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2683 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2687 return LIBUSB_SUCCESS;
2690 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2692 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2693 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2694 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2695 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2696 HANDLE file_handle, winusb_handle;
2697 DWORD err;
2698 int i;
2699 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2700 HDEVINFO dev_info = INVALID_HANDLE_VALUE;
2701 SP_DEVINFO_DATA dev_info_data;
2702 char* dev_path_no_guid = NULL;
2703 char filter_path[] = "\\\\.\\libusb0-0000";
2704 bool found_filter = false;
2706 CHECK_WINUSBX_AVAILABLE(sub_api);
2708 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2709 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2710 if ((is_using_usbccgp) || (iface == 0)) {
2711 // composite device (independent interfaces) or interface 0
2712 file_handle = handle_priv->interface_handle[iface].dev_handle;
2713 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2714 return LIBUSB_ERROR_NOT_FOUND;
2717 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2718 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2719 err = GetLastError();
2720 switch(err) {
2721 case ERROR_BAD_COMMAND:
2722 // The device was disconnected
2723 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2724 return LIBUSB_ERROR_NO_DEVICE;
2725 default:
2726 // it may be that we're using the libusb0 filter driver.
2727 // TODO: can we move this whole business into the K/0 DLL?
2728 for (i = 0; ; i++) {
2729 safe_free(dev_interface_details);
2730 safe_free(dev_path_no_guid);
2731 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2732 if ((found_filter) || (dev_interface_details == NULL)) {
2733 break;
2735 // ignore GUID part
2736 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2737 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2738 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2739 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2740 if (file_handle == INVALID_HANDLE_VALUE) {
2741 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2742 } else {
2743 WinUSBX[sub_api].Free(winusb_handle);
2744 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2745 continue;
2747 found_filter = true;
2748 break;
2752 if (!found_filter) {
2753 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2754 return LIBUSB_ERROR_ACCESS;
2758 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2759 } else {
2760 // For all other interfaces, use GetAssociatedInterface()
2761 winusb_handle = handle_priv->interface_handle[0].api_handle;
2762 // It is a requirement for multiple interface devices on Windows that, to you
2763 // must first claim the first interface before you claim the others
2764 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2765 file_handle = handle_priv->interface_handle[0].dev_handle;
2766 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2767 handle_priv->interface_handle[0].api_handle = winusb_handle;
2768 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2769 } else {
2770 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2771 return LIBUSB_ERROR_ACCESS;
2774 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2775 &handle_priv->interface_handle[iface].api_handle)) {
2776 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2777 switch(GetLastError()) {
2778 case ERROR_NO_MORE_ITEMS: // invalid iface
2779 return LIBUSB_ERROR_NOT_FOUND;
2780 case ERROR_BAD_COMMAND: // The device was disconnected
2781 return LIBUSB_ERROR_NO_DEVICE;
2782 case ERROR_ALREADY_EXISTS: // already claimed
2783 return LIBUSB_ERROR_BUSY;
2784 default:
2785 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2786 return LIBUSB_ERROR_ACCESS;
2790 usbi_dbg("claimed interface %d", iface);
2791 handle_priv->active_interface = iface;
2793 return LIBUSB_SUCCESS;
2796 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2798 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2799 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2800 HANDLE winusb_handle;
2802 CHECK_WINUSBX_AVAILABLE(sub_api);
2804 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2805 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2806 return LIBUSB_ERROR_NOT_FOUND;
2809 WinUSBX[sub_api].Free(winusb_handle);
2810 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2812 return LIBUSB_SUCCESS;
2816 * Return the first valid interface (of the same API type), for control transfers
2818 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2820 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2821 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2822 int i;
2824 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2825 usbi_dbg("unsupported API ID");
2826 return -1;
2829 for (i=0; i<USB_MAXINTERFACES; i++) {
2830 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2831 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2832 && (handle_priv->interface_handle[i].api_handle != 0)
2833 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2834 && (priv->usb_interface[i].apib->id == api_id) ) {
2835 return i;
2838 return -1;
2842 * Lookup interface by endpoint address. -1 if not found
2844 static int interface_by_endpoint(struct windows_device_priv *priv,
2845 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2847 int i, j;
2848 for (i=0; i<USB_MAXINTERFACES; i++) {
2849 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2850 continue;
2851 if (handle_priv->interface_handle[i].api_handle == 0)
2852 continue;
2853 if (priv->usb_interface[i].endpoint == NULL)
2854 continue;
2855 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2856 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2857 return i;
2861 return -1;
2864 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2866 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2867 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2868 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2869 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2870 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2871 transfer->dev_handle);
2872 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2873 ULONG size;
2874 HANDLE winusb_handle;
2875 int current_interface;
2876 struct winfd wfd;
2878 CHECK_WINUSBX_AVAILABLE(sub_api);
2880 transfer_priv->pollable_fd = INVALID_WINFD;
2881 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2883 if (size > MAX_CTRL_BUFFER_LENGTH)
2884 return LIBUSB_ERROR_INVALID_PARAM;
2886 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2887 if (current_interface < 0) {
2888 if (auto_claim(transfer, &current_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2889 return LIBUSB_ERROR_NOT_FOUND;
2893 usbi_dbg("will use interface %d", current_interface);
2894 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2896 wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
2897 // Always use the handle returned from usbi_create_fd (wfd.handle)
2898 if (wfd.fd < 0) {
2899 return LIBUSB_ERROR_NO_MEM;
2902 // Sending of set configuration control requests from WinUSB creates issues
2903 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2904 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2905 if (setup->value != priv->active_config) {
2906 usbi_warn(ctx, "cannot set configuration other than the default one");
2907 usbi_free_fd(&wfd);
2908 return LIBUSB_ERROR_INVALID_PARAM;
2910 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2911 wfd.overlapped->InternalHigh = 0;
2912 } else {
2913 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2914 if(GetLastError() != ERROR_IO_PENDING) {
2915 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2916 usbi_free_fd(&wfd);
2917 return LIBUSB_ERROR_IO;
2919 } else {
2920 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2921 wfd.overlapped->InternalHigh = (DWORD)size;
2925 // Use priv_transfer to store data needed for async polling
2926 transfer_priv->pollable_fd = wfd;
2927 transfer_priv->interface_number = (uint8_t)current_interface;
2929 return LIBUSB_SUCCESS;
2932 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2934 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2935 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2936 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2937 HANDLE winusb_handle;
2939 CHECK_WINUSBX_AVAILABLE(sub_api);
2941 if (altsetting > 255) {
2942 return LIBUSB_ERROR_INVALID_PARAM;
2945 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2946 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2947 usbi_err(ctx, "interface must be claimed first");
2948 return LIBUSB_ERROR_NOT_FOUND;
2951 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2952 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2953 return LIBUSB_ERROR_IO;
2956 return LIBUSB_SUCCESS;
2959 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2961 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2962 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2963 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2964 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2965 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2966 HANDLE winusb_handle;
2967 bool ret;
2968 int current_interface;
2969 struct winfd wfd;
2971 CHECK_WINUSBX_AVAILABLE(sub_api);
2973 transfer_priv->pollable_fd = INVALID_WINFD;
2975 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2976 if (current_interface < 0) {
2977 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2978 return LIBUSB_ERROR_NOT_FOUND;
2981 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2983 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2985 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
2986 // Always use the handle returned from usbi_create_fd (wfd.handle)
2987 if (wfd.fd < 0) {
2988 return LIBUSB_ERROR_NO_MEM;
2991 if (IS_XFERIN(transfer)) {
2992 usbi_dbg("reading %d bytes", transfer->length);
2993 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2994 } else {
2995 usbi_dbg("writing %d bytes", transfer->length);
2996 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2998 if (!ret) {
2999 if(GetLastError() != ERROR_IO_PENDING) {
3000 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
3001 usbi_free_fd(&wfd);
3002 return LIBUSB_ERROR_IO;
3004 } else {
3005 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3006 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
3009 transfer_priv->pollable_fd = wfd;
3010 transfer_priv->interface_number = (uint8_t)current_interface;
3012 return LIBUSB_SUCCESS;
3015 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3017 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3018 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3019 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3020 HANDLE winusb_handle;
3021 int current_interface;
3023 CHECK_WINUSBX_AVAILABLE(sub_api);
3025 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3026 if (current_interface < 0) {
3027 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3028 return LIBUSB_ERROR_NOT_FOUND;
3031 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3032 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3034 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3035 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3036 return LIBUSB_ERROR_NO_DEVICE;
3039 return LIBUSB_SUCCESS;
3043 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3044 * through testing as well):
3045 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3046 * the control transfer using CancelIo"
3048 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3050 // Cancelling of the I/O is done in the parent
3051 return LIBUSB_SUCCESS;
3054 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3056 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3057 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3058 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3059 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3060 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3061 HANDLE winusb_handle;
3062 int current_interface;
3064 CHECK_WINUSBX_AVAILABLE(sub_api);
3066 current_interface = transfer_priv->interface_number;
3067 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3068 usbi_err(ctx, "program assertion failed: invalid interface_number");
3069 return LIBUSB_ERROR_NOT_FOUND;
3071 usbi_dbg("will use interface %d", current_interface);
3073 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3075 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3076 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3077 return LIBUSB_ERROR_NO_DEVICE;
3080 return LIBUSB_SUCCESS;
3084 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3085 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3086 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3087 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3088 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3089 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3091 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3092 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3094 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3095 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3096 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3097 struct winfd wfd;
3098 HANDLE winusb_handle;
3099 int i, j;
3101 CHECK_WINUSBX_AVAILABLE(sub_api);
3103 // Reset any available pipe (except control)
3104 for (i=0; i<USB_MAXINTERFACES; i++) {
3105 winusb_handle = handle_priv->interface_handle[i].api_handle;
3106 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3108 // Cancel any pollable I/O
3109 usbi_remove_pollfd(ctx, wfd.fd);
3110 usbi_free_fd(&wfd);
3111 wfd = handle_to_winfd(winusb_handle);
3114 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3115 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3116 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3117 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3118 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3119 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3121 // FlushPipe seems to fail on OUT pipes
3122 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3123 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3124 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3125 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3127 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3128 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3129 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3135 // libusbK & libusb0 have the ability to issue an actual device reset
3136 if (WinUSBX[sub_api].ResetDevice != NULL) {
3137 winusb_handle = handle_priv->interface_handle[0].api_handle;
3138 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3139 WinUSBX[sub_api].ResetDevice(winusb_handle);
3142 return LIBUSB_SUCCESS;
3145 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3147 itransfer->transferred += io_size;
3148 return LIBUSB_TRANSFER_COMPLETED;
3152 * Internal HID Support functions (from libusb-win32)
3153 * Note that functions that complete data transfer synchronously must return
3154 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3156 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3157 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3159 static int _hid_wcslen(WCHAR *str)
3161 int i = 0;
3162 while (str[i] && (str[i] != 0x409)) {
3163 i++;
3165 return i;
3168 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3170 struct libusb_device_descriptor d;
3172 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3173 d.bDescriptorType = LIBUSB_DT_DEVICE;
3174 d.bcdUSB = 0x0200; /* 2.00 */
3175 d.bDeviceClass = 0;
3176 d.bDeviceSubClass = 0;
3177 d.bDeviceProtocol = 0;
3178 d.bMaxPacketSize0 = 64; /* fix this! */
3179 d.idVendor = (uint16_t)dev->vid;
3180 d.idProduct = (uint16_t)dev->pid;
3181 d.bcdDevice = 0x0100;
3182 d.iManufacturer = dev->string_index[0];
3183 d.iProduct = dev->string_index[1];
3184 d.iSerialNumber = dev->string_index[2];
3185 d.bNumConfigurations = 1;
3187 if (*size > LIBUSB_DT_DEVICE_SIZE)
3188 *size = LIBUSB_DT_DEVICE_SIZE;
3189 memcpy(data, &d, *size);
3190 return LIBUSB_COMPLETED;
3193 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3195 char num_endpoints = 0;
3196 size_t config_total_len = 0;
3197 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3198 struct libusb_config_descriptor *cd;
3199 struct libusb_interface_descriptor *id;
3200 struct libusb_hid_descriptor *hd;
3201 struct libusb_endpoint_descriptor *ed;
3202 size_t tmp_size;
3204 if (dev->input_report_size)
3205 num_endpoints++;
3206 if (dev->output_report_size)
3207 num_endpoints++;
3209 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3210 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3213 cd = (struct libusb_config_descriptor *)tmp;
3214 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3215 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3216 + LIBUSB_DT_INTERFACE_SIZE);
3217 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3218 + LIBUSB_DT_INTERFACE_SIZE
3219 + LIBUSB_DT_HID_SIZE);
3221 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3222 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3223 cd->wTotalLength = (uint16_t) config_total_len;
3224 cd->bNumInterfaces = 1;
3225 cd->bConfigurationValue = 1;
3226 cd->iConfiguration = 0;
3227 cd->bmAttributes = 1 << 7; /* bus powered */
3228 cd->MaxPower = 50;
3230 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3231 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3232 id->bInterfaceNumber = 0;
3233 id->bAlternateSetting = 0;
3234 id->bNumEndpoints = num_endpoints;
3235 id->bInterfaceClass = 3;
3236 id->bInterfaceSubClass = 0;
3237 id->bInterfaceProtocol = 0;
3238 id->iInterface = 0;
3240 tmp_size = LIBUSB_DT_HID_SIZE;
3241 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3243 if (dev->input_report_size) {
3244 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3245 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3246 ed->bEndpointAddress = HID_IN_EP;
3247 ed->bmAttributes = 3;
3248 ed->wMaxPacketSize = dev->input_report_size - 1;
3249 ed->bInterval = 10;
3250 ed = (struct libusb_endpoint_descriptor *)((char*)ed + LIBUSB_DT_ENDPOINT_SIZE);
3253 if (dev->output_report_size) {
3254 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3255 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3256 ed->bEndpointAddress = HID_OUT_EP;
3257 ed->bmAttributes = 3;
3258 ed->wMaxPacketSize = dev->output_report_size - 1;
3259 ed->bInterval = 10;
3262 if (*size > config_total_len)
3263 *size = config_total_len;
3264 memcpy(data, tmp, *size);
3265 return LIBUSB_COMPLETED;
3268 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3269 void *data, size_t *size)
3271 void *tmp = NULL;
3272 size_t tmp_size = 0;
3273 int i;
3275 /* language ID, EN-US */
3276 char string_langid[] = {
3277 0x09,
3278 0x04
3281 if ((*size < 2) || (*size > 255)) {
3282 return LIBUSB_ERROR_OVERFLOW;
3285 if (_index == 0) {
3286 tmp = string_langid;
3287 tmp_size = sizeof(string_langid)+2;
3288 } else {
3289 for (i=0; i<3; i++) {
3290 if (_index == (dev->string_index[i])) {
3291 tmp = dev->string[i];
3292 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3293 break;
3296 if (i == 3) { // not found
3297 return LIBUSB_ERROR_INVALID_PARAM;
3301 if(!tmp_size) {
3302 return LIBUSB_ERROR_INVALID_PARAM;
3305 if (tmp_size < *size) {
3306 *size = tmp_size;
3308 // 2 byte header
3309 ((uint8_t*)data)[0] = (uint8_t)*size;
3310 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3311 memcpy((uint8_t*)data+2, tmp, *size-2);
3312 return LIBUSB_COMPLETED;
3315 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3317 struct libusb_hid_descriptor d;
3318 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3319 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3321 _hid_get_report_descriptor(dev, tmp, &report_len);
3323 d.bLength = LIBUSB_DT_HID_SIZE;
3324 d.bDescriptorType = LIBUSB_DT_HID;
3325 d.bcdHID = 0x0110; /* 1.10 */
3326 d.bCountryCode = 0;
3327 d.bNumDescriptors = 1;
3328 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3329 d.wClassDescriptorLength = (uint16_t)report_len;
3331 if (*size > LIBUSB_DT_HID_SIZE)
3332 *size = LIBUSB_DT_HID_SIZE;
3333 memcpy(data, &d, *size);
3334 return LIBUSB_COMPLETED;
3337 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3339 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3340 size_t i = 0;
3342 /* usage page (0xFFA0 == vendor defined) */
3343 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3344 /* usage (vendor defined) */
3345 d[i++] = 0x09; d[i++] = 0x01;
3346 /* start collection (application) */
3347 d[i++] = 0xA1; d[i++] = 0x01;
3348 /* input report */
3349 if (dev->input_report_size) {
3350 /* usage (vendor defined) */
3351 d[i++] = 0x09; d[i++] = 0x01;
3352 /* logical minimum (0) */
3353 d[i++] = 0x15; d[i++] = 0x00;
3354 /* logical maximum (255) */
3355 d[i++] = 0x25; d[i++] = 0xFF;
3356 /* report size (8 bits) */
3357 d[i++] = 0x75; d[i++] = 0x08;
3358 /* report count */
3359 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3360 /* input (data, variable, absolute) */
3361 d[i++] = 0x81; d[i++] = 0x00;
3363 /* output report */
3364 if (dev->output_report_size) {
3365 /* usage (vendor defined) */
3366 d[i++] = 0x09; d[i++] = 0x02;
3367 /* logical minimum (0) */
3368 d[i++] = 0x15; d[i++] = 0x00;
3369 /* logical maximum (255) */
3370 d[i++] = 0x25; d[i++] = 0xFF;
3371 /* report size (8 bits) */
3372 d[i++] = 0x75; d[i++] = 0x08;
3373 /* report count */
3374 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3375 /* output (data, variable, absolute) */
3376 d[i++] = 0x91; d[i++] = 0x00;
3378 /* feature report */
3379 if (dev->feature_report_size) {
3380 /* usage (vendor defined) */
3381 d[i++] = 0x09; d[i++] = 0x03;
3382 /* logical minimum (0) */
3383 d[i++] = 0x15; d[i++] = 0x00;
3384 /* logical maximum (255) */
3385 d[i++] = 0x25; d[i++] = 0xFF;
3386 /* report size (8 bits) */
3387 d[i++] = 0x75; d[i++] = 0x08;
3388 /* report count */
3389 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3390 /* feature (data, variable, absolute) */
3391 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3394 /* end collection */
3395 d[i++] = 0xC0;
3397 if (*size > i)
3398 *size = i;
3399 memcpy(data, d, *size);
3400 return LIBUSB_COMPLETED;
3403 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3404 int type, int _index, void *data, size_t *size)
3406 switch(type) {
3407 case LIBUSB_DT_DEVICE:
3408 usbi_dbg("LIBUSB_DT_DEVICE");
3409 return _hid_get_device_descriptor(dev, data, size);
3410 case LIBUSB_DT_CONFIG:
3411 usbi_dbg("LIBUSB_DT_CONFIG");
3412 if (!_index)
3413 return _hid_get_config_descriptor(dev, data, size);
3414 return LIBUSB_ERROR_INVALID_PARAM;
3415 case LIBUSB_DT_STRING:
3416 usbi_dbg("LIBUSB_DT_STRING");
3417 return _hid_get_string_descriptor(dev, _index, data, size);
3418 case LIBUSB_DT_HID:
3419 usbi_dbg("LIBUSB_DT_HID");
3420 if (!_index)
3421 return _hid_get_hid_descriptor(dev, data, size);
3422 return LIBUSB_ERROR_INVALID_PARAM;
3423 case LIBUSB_DT_REPORT:
3424 usbi_dbg("LIBUSB_DT_REPORT");
3425 if (!_index)
3426 return _hid_get_report_descriptor(dev, data, size);
3427 return LIBUSB_ERROR_INVALID_PARAM;
3428 case LIBUSB_DT_PHYSICAL:
3429 usbi_dbg("LIBUSB_DT_PHYSICAL");
3430 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3431 return LIBUSB_COMPLETED;
3432 return LIBUSB_ERROR_OTHER;
3434 usbi_dbg("unsupported");
3435 return LIBUSB_ERROR_INVALID_PARAM;
3438 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3439 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3440 int report_type)
3442 uint8_t *buf;
3443 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3444 int r = LIBUSB_SUCCESS;
3446 if (tp->hid_buffer != NULL) {
3447 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3450 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3451 usbi_dbg("invalid size (%d)", *size);
3452 return LIBUSB_ERROR_INVALID_PARAM;
3455 switch (report_type) {
3456 case HID_REPORT_TYPE_INPUT:
3457 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3458 break;
3459 case HID_REPORT_TYPE_FEATURE:
3460 ioctl_code = IOCTL_HID_GET_FEATURE;
3461 break;
3462 default:
3463 usbi_dbg("unknown HID report type %d", report_type);
3464 return LIBUSB_ERROR_INVALID_PARAM;
3467 // Add a trailing byte to detect overflows
3468 buf = (uint8_t*)calloc(expected_size+1, 1);
3469 if (buf == NULL) {
3470 return LIBUSB_ERROR_NO_MEM;
3472 buf[0] = (uint8_t)id; // Must be set always
3473 usbi_dbg("report ID: 0x%02X", buf[0]);
3475 tp->hid_expected_size = expected_size;
3476 read_size = expected_size;
3478 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3479 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3480 buf, expected_size+1, &read_size, overlapped)) {
3481 if (GetLastError() != ERROR_IO_PENDING) {
3482 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3483 safe_free(buf);
3484 return LIBUSB_ERROR_IO;
3486 // Asynchronous wait
3487 tp->hid_buffer = buf;
3488 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3489 return LIBUSB_SUCCESS;
3492 // Transfer completed synchronously => copy and discard extra buffer
3493 if (read_size == 0) {
3494 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3495 *size = 0;
3496 } else {
3497 if (buf[0] != id) {
3498 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3500 if ((size_t)read_size > expected_size) {
3501 r = LIBUSB_ERROR_OVERFLOW;
3502 usbi_dbg("OVERFLOW!");
3503 } else {
3504 r = LIBUSB_COMPLETED;
3507 *size = MIN((size_t)read_size, *size);
3508 if (id == 0) {
3509 // Discard report ID
3510 memcpy(data, buf+1, *size);
3511 } else {
3512 memcpy(data, buf, *size);
3515 safe_free(buf);
3516 return r;
3519 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3520 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3521 int report_type)
3523 uint8_t *buf = NULL;
3524 DWORD ioctl_code, write_size= (DWORD)*size;
3526 if (tp->hid_buffer != NULL) {
3527 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3530 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3531 usbi_dbg("invalid size (%d)", *size);
3532 return LIBUSB_ERROR_INVALID_PARAM;
3535 switch (report_type) {
3536 case HID_REPORT_TYPE_OUTPUT:
3537 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3538 break;
3539 case HID_REPORT_TYPE_FEATURE:
3540 ioctl_code = IOCTL_HID_SET_FEATURE;
3541 break;
3542 default:
3543 usbi_dbg("unknown HID report type %d", report_type);
3544 return LIBUSB_ERROR_INVALID_PARAM;
3547 usbi_dbg("report ID: 0x%02X", id);
3548 // When report IDs are not used (i.e. when id == 0), we must add
3549 // a null report ID. Otherwise, we just use original data buffer
3550 if (id == 0) {
3551 write_size++;
3553 buf = (uint8_t*) malloc(write_size);
3554 if (buf == NULL) {
3555 return LIBUSB_ERROR_NO_MEM;
3557 if (id == 0) {
3558 buf[0] = 0;
3559 memcpy(buf + 1, data, *size);
3560 } else {
3561 // This seems like a waste, but if we don't duplicate the
3562 // data, we'll get issues when freeing hid_buffer
3563 memcpy(buf, data, *size);
3564 if (buf[0] != id) {
3565 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3569 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3570 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3571 buf, write_size, &write_size, overlapped)) {
3572 if (GetLastError() != ERROR_IO_PENDING) {
3573 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3574 safe_free(buf);
3575 return LIBUSB_ERROR_IO;
3577 tp->hid_buffer = buf;
3578 tp->hid_dest = NULL;
3579 return LIBUSB_SUCCESS;
3582 // Transfer completed synchronously
3583 *size = write_size;
3584 if (write_size == 0) {
3585 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3587 safe_free(buf);
3588 return LIBUSB_COMPLETED;
3591 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3592 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3593 size_t *size, OVERLAPPED* overlapped)
3595 int report_type = (value >> 8) & 0xFF;
3596 int report_id = value & 0xFF;
3598 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3599 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3600 return LIBUSB_ERROR_INVALID_PARAM;
3602 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3603 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3605 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3606 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3608 return LIBUSB_ERROR_INVALID_PARAM;
3613 * HID API functions
3615 static int hid_init(int sub_api, struct libusb_context *ctx)
3617 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3618 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3619 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3620 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3621 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3622 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3623 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3624 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3625 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3626 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3627 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3628 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3629 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3630 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3631 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3632 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3634 api_hid_available = true;
3635 return LIBUSB_SUCCESS;
3638 static int hid_exit(int sub_api)
3640 return LIBUSB_SUCCESS;
3643 // NB: open and close must ensure that they only handle interface of
3644 // the right API type, as these functions can be called wholesale from
3645 // composite_open(), with interfaces belonging to different APIs
3646 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3648 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3649 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3650 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3652 HIDD_ATTRIBUTES hid_attributes;
3653 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3654 HIDP_CAPS capabilities;
3655 HIDP_VALUE_CAPS *value_caps;
3657 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3658 int i, j;
3659 // report IDs handling
3660 ULONG size[3];
3661 const char* type[3] = {"input", "output", "feature"};
3662 int nb_ids[2]; // zero and nonzero report IDs
3664 CHECK_HID_AVAILABLE;
3665 if (priv->hid == NULL) {
3666 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3667 return LIBUSB_ERROR_NOT_FOUND;
3670 for (i = 0; i < USB_MAXINTERFACES; i++) {
3671 if ( (priv->usb_interface[i].path != NULL)
3672 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3673 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3674 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3676 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3677 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3678 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3679 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3680 * HidD_GetFeature (if the device supports Feature reports)."
3682 if (hid_handle == INVALID_HANDLE_VALUE) {
3683 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3684 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3685 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3686 if (hid_handle == INVALID_HANDLE_VALUE) {
3687 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3688 switch(GetLastError()) {
3689 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3690 return LIBUSB_ERROR_NO_DEVICE;
3691 case ERROR_ACCESS_DENIED:
3692 return LIBUSB_ERROR_ACCESS;
3693 default:
3694 return LIBUSB_ERROR_IO;
3697 priv->usb_interface[i].restricted_functionality = true;
3699 handle_priv->interface_handle[i].api_handle = hid_handle;
3703 hid_attributes.Size = sizeof(hid_attributes);
3704 do {
3705 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3706 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3707 break;
3710 priv->hid->vid = hid_attributes.VendorID;
3711 priv->hid->pid = hid_attributes.ProductID;
3713 // Set the maximum available input buffer size
3714 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3715 usbi_dbg("set maximum input buffer size to %d", i/2);
3717 // Get the maximum input and output report size
3718 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3719 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3720 break;
3722 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3723 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3724 break;
3727 // Find out if interrupt will need report IDs
3728 size[0] = capabilities.NumberInputValueCaps;
3729 size[1] = capabilities.NumberOutputValueCaps;
3730 size[2] = capabilities.NumberFeatureValueCaps;
3731 for (j=HidP_Input; j<=HidP_Feature; j++) {
3732 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3733 priv->hid->uses_report_ids[j] = false;
3734 if (size[j] > 0) {
3735 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3736 if ( (value_caps != NULL)
3737 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3738 && (size[j] >= 1) ) {
3739 nb_ids[0] = 0;
3740 nb_ids[1] = 0;
3741 for (i=0; i<(int)size[j]; i++) {
3742 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3743 if (value_caps[i].ReportID != 0) {
3744 nb_ids[1]++;
3745 } else {
3746 nb_ids[0]++;
3749 if (nb_ids[1] != 0) {
3750 if (nb_ids[0] != 0) {
3751 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3752 type[j]);
3754 priv->hid->uses_report_ids[j] = true;
3756 } else {
3757 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3759 safe_free(value_caps);
3763 // Set the report sizes
3764 priv->hid->input_report_size = capabilities.InputReportByteLength;
3765 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3766 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3768 // Fetch string descriptors
3769 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3770 if (priv->hid->string_index[0] != 0) {
3771 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3772 sizeof(priv->hid->string[0]));
3773 } else {
3774 priv->hid->string[0][0] = 0;
3776 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3777 if (priv->hid->string_index[1] != 0) {
3778 HidD_GetProductString(hid_handle, priv->hid->string[1],
3779 sizeof(priv->hid->string[1]));
3780 } else {
3781 priv->hid->string[1][0] = 0;
3783 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3784 if (priv->hid->string_index[2] != 0) {
3785 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3786 sizeof(priv->hid->string[2]));
3787 } else {
3788 priv->hid->string[2][0] = 0;
3790 } while(0);
3792 if (preparsed_data) {
3793 HidD_FreePreparsedData(preparsed_data);
3796 return LIBUSB_SUCCESS;
3799 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3801 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3802 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3803 HANDLE file_handle;
3804 int i;
3806 if (!api_hid_available)
3807 return;
3809 for (i = 0; i < USB_MAXINTERFACES; i++) {
3810 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3811 file_handle = handle_priv->interface_handle[i].api_handle;
3812 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3813 CloseHandle(file_handle);
3819 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3821 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3822 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3824 CHECK_HID_AVAILABLE;
3826 // NB: Disconnection detection is not possible in this function
3827 if (priv->usb_interface[iface].path == NULL) {
3828 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3831 // We use dev_handle as a flag for interface claimed
3832 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3833 return LIBUSB_ERROR_BUSY; // already claimed
3836 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3838 usbi_dbg("claimed interface %d", iface);
3839 handle_priv->active_interface = iface;
3841 return LIBUSB_SUCCESS;
3844 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3846 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3847 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3849 CHECK_HID_AVAILABLE;
3851 if (priv->usb_interface[iface].path == NULL) {
3852 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3855 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3856 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3859 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3861 return LIBUSB_SUCCESS;
3864 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3866 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3868 CHECK_HID_AVAILABLE;
3870 if (altsetting > 255) {
3871 return LIBUSB_ERROR_INVALID_PARAM;
3874 if (altsetting != 0) {
3875 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3876 return LIBUSB_ERROR_NOT_SUPPORTED;
3879 return LIBUSB_SUCCESS;
3882 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3884 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3885 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3886 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3887 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3888 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3889 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3890 HANDLE hid_handle;
3891 struct winfd wfd;
3892 int current_interface, config;
3893 size_t size;
3894 int r = LIBUSB_ERROR_INVALID_PARAM;
3896 CHECK_HID_AVAILABLE;
3898 transfer_priv->pollable_fd = INVALID_WINFD;
3899 safe_free(transfer_priv->hid_buffer);
3900 transfer_priv->hid_dest = NULL;
3901 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3903 if (size > MAX_CTRL_BUFFER_LENGTH) {
3904 return LIBUSB_ERROR_INVALID_PARAM;
3907 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3908 if (current_interface < 0) {
3909 if (auto_claim(transfer, &current_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3910 return LIBUSB_ERROR_NOT_FOUND;
3914 usbi_dbg("will use interface %d", current_interface);
3915 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3916 // Always use the handle returned from usbi_create_fd (wfd.handle)
3917 wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
3918 if (wfd.fd < 0) {
3919 return LIBUSB_ERROR_NOT_FOUND;
3922 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3923 case LIBUSB_REQUEST_TYPE_STANDARD:
3924 switch(setup->request) {
3925 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3926 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3927 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3928 break;
3929 case LIBUSB_REQUEST_GET_CONFIGURATION:
3930 r = windows_get_configuration(transfer->dev_handle, &config);
3931 if (r == LIBUSB_SUCCESS) {
3932 size = 1;
3933 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3934 r = LIBUSB_COMPLETED;
3936 break;
3937 case LIBUSB_REQUEST_SET_CONFIGURATION:
3938 if (setup->value == priv->active_config) {
3939 r = LIBUSB_COMPLETED;
3940 } else {
3941 usbi_warn(ctx, "cannot set configuration other than the default one");
3942 r = LIBUSB_ERROR_INVALID_PARAM;
3944 break;
3945 case LIBUSB_REQUEST_GET_INTERFACE:
3946 size = 1;
3947 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3948 r = LIBUSB_COMPLETED;
3949 break;
3950 case LIBUSB_REQUEST_SET_INTERFACE:
3951 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3952 if (r == LIBUSB_SUCCESS) {
3953 r = LIBUSB_COMPLETED;
3955 break;
3956 default:
3957 usbi_warn(ctx, "unsupported HID control request");
3958 r = LIBUSB_ERROR_INVALID_PARAM;
3959 break;
3961 break;
3962 case LIBUSB_REQUEST_TYPE_CLASS:
3963 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3964 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3965 &size, wfd.overlapped);
3966 break;
3967 default:
3968 usbi_warn(ctx, "unsupported HID control request");
3969 r = LIBUSB_ERROR_INVALID_PARAM;
3970 break;
3973 if (r == LIBUSB_COMPLETED) {
3974 // Force request to be completed synchronously. Transferred size has been set by previous call
3975 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3976 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3977 // set InternalHigh to the number of bytes transferred
3978 wfd.overlapped->InternalHigh = (DWORD)size;
3979 r = LIBUSB_SUCCESS;
3982 if (r == LIBUSB_SUCCESS) {
3983 // Use priv_transfer to store data needed for async polling
3984 transfer_priv->pollable_fd = wfd;
3985 transfer_priv->interface_number = (uint8_t)current_interface;
3986 } else {
3987 usbi_free_fd(&wfd);
3990 return r;
3993 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3994 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3995 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3996 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3997 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3998 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3999 struct winfd wfd;
4000 HANDLE hid_handle;
4001 bool direction_in, ret;
4002 int current_interface, length;
4003 DWORD size;
4004 int r = LIBUSB_SUCCESS;
4006 CHECK_HID_AVAILABLE;
4008 transfer_priv->pollable_fd = INVALID_WINFD;
4009 transfer_priv->hid_dest = NULL;
4010 safe_free(transfer_priv->hid_buffer);
4012 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4013 if (current_interface < 0) {
4014 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4015 return LIBUSB_ERROR_NOT_FOUND;
4018 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
4020 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4021 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
4023 wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
4024 // Always use the handle returned from usbi_create_fd (wfd.handle)
4025 if (wfd.fd < 0) {
4026 return LIBUSB_ERROR_NO_MEM;
4029 // If report IDs are not in use, an extra prefix byte must be added
4030 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4031 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4032 length = transfer->length+1;
4033 } else {
4034 length = transfer->length;
4036 // Add a trailing byte to detect overflows on input
4037 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4038 if (transfer_priv->hid_buffer == NULL) {
4039 return LIBUSB_ERROR_NO_MEM;
4041 transfer_priv->hid_expected_size = length;
4043 if (direction_in) {
4044 transfer_priv->hid_dest = transfer->buffer;
4045 usbi_dbg("reading %d bytes (report ID: 0x00)", length);
4046 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4047 } else {
4048 if (!priv->hid->uses_report_ids[1]) {
4049 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4050 } else {
4051 // We could actually do without the calloc and memcpy in this case
4052 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4054 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4055 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4057 if (!ret) {
4058 if (GetLastError() != ERROR_IO_PENDING) {
4059 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4060 usbi_free_fd(&wfd);
4061 safe_free(transfer_priv->hid_buffer);
4062 return LIBUSB_ERROR_IO;
4064 } else {
4065 // Only write operations that completed synchronously need to free up
4066 // hid_buffer. For reads, copy_transfer_data() handles that process.
4067 if (!direction_in) {
4068 safe_free(transfer_priv->hid_buffer);
4070 if (size == 0) {
4071 usbi_err(ctx, "program assertion failed - no data was transferred");
4072 size = 1;
4074 if (size > (size_t)length) {
4075 usbi_err(ctx, "OVERFLOW!");
4076 r = LIBUSB_ERROR_OVERFLOW;
4078 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4079 wfd.overlapped->InternalHigh = size;
4082 transfer_priv->pollable_fd = wfd;
4083 transfer_priv->interface_number = (uint8_t)current_interface;
4085 return r;
4088 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4090 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4091 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4092 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4093 HANDLE hid_handle;
4094 int current_interface;
4096 CHECK_HID_AVAILABLE;
4098 current_interface = transfer_priv->interface_number;
4099 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4100 CancelIo(hid_handle);
4102 return LIBUSB_SUCCESS;
4105 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4107 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4108 HANDLE hid_handle;
4109 int current_interface;
4111 CHECK_HID_AVAILABLE;
4113 // Flushing the queues on all interfaces is the best we can achieve
4114 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4115 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4116 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4117 HidD_FlushQueue(hid_handle);
4120 return LIBUSB_SUCCESS;
4123 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4125 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4126 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4127 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4128 HANDLE hid_handle;
4129 int current_interface;
4131 CHECK_HID_AVAILABLE;
4133 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4134 if (current_interface < 0) {
4135 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4136 return LIBUSB_ERROR_NOT_FOUND;
4139 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4140 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4142 // No endpoint selection with Microsoft's implementation, so we try to flush the
4143 // whole interface. Should be OK for most case scenarios
4144 if (!HidD_FlushQueue(hid_handle)) {
4145 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4146 // Device was probably disconnected
4147 return LIBUSB_ERROR_NO_DEVICE;
4150 return LIBUSB_SUCCESS;
4153 // This extra function is only needed for HID
4154 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4155 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4156 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4157 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4158 int r = LIBUSB_TRANSFER_COMPLETED;
4159 uint32_t corrected_size = io_size;
4161 if (transfer_priv->hid_buffer != NULL) {
4162 // If we have a valid hid_buffer, it means the transfer was async
4163 if (transfer_priv->hid_dest != NULL) { // Data readout
4164 // First, check for overflow
4165 if (corrected_size > transfer_priv->hid_expected_size) {
4166 usbi_err(ctx, "OVERFLOW!");
4167 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4168 r = LIBUSB_TRANSFER_OVERFLOW;
4171 if (transfer_priv->hid_buffer[0] == 0) {
4172 // Discard the 1 byte report ID prefix
4173 corrected_size--;
4174 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4175 } else {
4176 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4178 transfer_priv->hid_dest = NULL;
4180 // For write, we just need to free the hid buffer
4181 safe_free(transfer_priv->hid_buffer);
4183 itransfer->transferred += corrected_size;
4184 return r;
4189 * Composite API functions
4191 static int composite_init(int sub_api, struct libusb_context *ctx)
4193 return LIBUSB_SUCCESS;
4196 static int composite_exit(int sub_api)
4198 return LIBUSB_SUCCESS;
4201 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4203 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4204 int r = LIBUSB_ERROR_NOT_FOUND;
4205 uint8_t i;
4206 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4207 bool available[SUB_API_MAX+1] = {0};
4209 for (i=0; i<USB_MAXINTERFACES; i++) {
4210 switch (priv->usb_interface[i].apib->id) {
4211 case USB_API_WINUSBX:
4212 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4213 available[priv->usb_interface[i].sub_api] = true;
4214 break;
4215 case USB_API_HID:
4216 available[SUB_API_MAX] = true;
4217 break;
4218 default:
4219 break;
4223 for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4224 if (available[i]) {
4225 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4226 if (r != LIBUSB_SUCCESS) {
4227 return r;
4231 if (available[SUB_API_MAX]) { // HID driver
4232 r = hid_open(SUB_API_NOTSET, dev_handle);
4234 return r;
4237 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4239 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4240 uint8_t i;
4241 bool available[SUB_API_MAX];
4243 for (i = 0; i<SUB_API_MAX; i++) {
4244 available[i] = false;
4247 for (i=0; i<USB_MAXINTERFACES; i++) {
4248 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4249 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4250 available[priv->usb_interface[i].sub_api] = true;
4254 for (i=0; i<SUB_API_MAX; i++) {
4255 if (available[i]) {
4256 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4261 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4263 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4264 return priv->usb_interface[iface].apib->
4265 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4268 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4270 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4271 return priv->usb_interface[iface].apib->
4272 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4275 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4277 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4278 return priv->usb_interface[iface].apib->
4279 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4282 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4284 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4285 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4286 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4287 int i, pass;
4289 // Interface shouldn't matter for control, but it does in practice, with Windows'
4290 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4291 for (pass = 0; pass < 2; pass++) {
4292 for (i=0; i<USB_MAXINTERFACES; i++) {
4293 if (priv->usb_interface[i].path != NULL) {
4294 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4295 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4296 continue;
4298 usbi_dbg("using interface %d", i);
4299 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4304 usbi_err(ctx, "no libusbx supported interfaces to complete request");
4305 return LIBUSB_ERROR_NOT_FOUND;
4308 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4309 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4310 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4311 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4312 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4313 int current_interface;
4315 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4316 if (current_interface < 0) {
4317 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4318 return LIBUSB_ERROR_NOT_FOUND;
4321 return priv->usb_interface[current_interface].apib->
4322 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4324 static int composite_submit_iso_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_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4340 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4342 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4343 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4344 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4345 int current_interface;
4347 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4348 if (current_interface < 0) {
4349 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4350 return LIBUSB_ERROR_NOT_FOUND;
4353 return priv->usb_interface[current_interface].apib->
4354 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4356 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4358 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4359 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4360 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4362 return priv->usb_interface[transfer_priv->interface_number].apib->
4363 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4365 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4367 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4368 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4369 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4371 return priv->usb_interface[transfer_priv->interface_number].apib->
4372 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4374 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4376 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4377 int r;
4378 uint8_t i;
4379 bool available[SUB_API_MAX];
4380 for (i = 0; i<SUB_API_MAX; i++) {
4381 available[i] = false;
4383 for (i=0; i<USB_MAXINTERFACES; i++) {
4384 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4385 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4386 available[priv->usb_interface[i].sub_api] = true;
4389 for (i=0; i<SUB_API_MAX; i++) {
4390 if (available[i]) {
4391 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4392 if (r != LIBUSB_SUCCESS) {
4393 return r;
4397 return LIBUSB_SUCCESS;
4400 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4402 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4403 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4404 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4406 return priv->usb_interface[transfer_priv->interface_number].apib->
4407 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);