2 * windows backend for libusbx 1.0
3 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4 * With contributions from Michael Plante, Orin Eman et al.
5 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
6 * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
7 * Hash table functions adapted from glibc, by Ulrich Drepper et al.
8 * Major code testing contribution by Xiaofan Chen
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
38 #include "poll_windows.h"
39 #include "windows_usb.h"
41 // The 2 macros below are used in conjunction with safe loops.
42 #define LOOP_CHECK(fcall) { r=fcall; if (r != LIBUSB_SUCCESS) continue; }
43 #define LOOP_BREAK(err) { r=err; continue; }
46 static int windows_get_active_config_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, size_t len
, int *host_endian
);
47 static int windows_clock_gettime(int clk_id
, struct timespec
*tp
);
48 unsigned __stdcall
windows_clock_gettime_threaded(void* param
);
50 static int common_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
);
52 // WinUSB-like API prototypes
53 static int winusbx_init(int sub_api
, struct libusb_context
*ctx
);
54 static int winusbx_exit(int sub_api
);
55 static int winusbx_open(int sub_api
, struct libusb_device_handle
*dev_handle
);
56 static void winusbx_close(int sub_api
, struct libusb_device_handle
*dev_handle
);
57 static int winusbx_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
);
58 static int winusbx_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
);
59 static int winusbx_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
);
60 static int winusbx_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
);
61 static int winusbx_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
);
62 static int winusbx_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
);
63 static int winusbx_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
);
64 static int winusbx_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
);
65 static int winusbx_abort_control(int sub_api
, struct usbi_transfer
*itransfer
);
66 static int winusbx_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
);
67 static int winusbx_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
);
69 static int hid_init(int sub_api
, struct libusb_context
*ctx
);
70 static int hid_exit(int sub_api
);
71 static int hid_open(int sub_api
, struct libusb_device_handle
*dev_handle
);
72 static void hid_close(int sub_api
, struct libusb_device_handle
*dev_handle
);
73 static int hid_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
);
74 static int hid_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
);
75 static int hid_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
);
76 static int hid_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
);
77 static int hid_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
);
78 static int hid_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
);
79 static int hid_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
);
80 static int hid_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
);
81 static int hid_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
);
82 // Composite API prototypes
83 static int composite_init(int sub_api
, struct libusb_context
*ctx
);
84 static int composite_exit(int sub_api
);
85 static int composite_open(int sub_api
, struct libusb_device_handle
*dev_handle
);
86 static void composite_close(int sub_api
, struct libusb_device_handle
*dev_handle
);
87 static int composite_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
);
88 static int composite_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
);
89 static int composite_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
);
90 static int composite_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
);
91 static int composite_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
);
92 static int composite_submit_iso_transfer(int sub_api
, struct usbi_transfer
*itransfer
);
93 static int composite_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
);
94 static int composite_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
);
95 static int composite_abort_control(int sub_api
, struct usbi_transfer
*itransfer
);
96 static int composite_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
);
97 static int composite_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
);
101 uint64_t hires_frequency
, hires_ticks_to_ps
;
102 const uint64_t epoch_time
= UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
103 enum windows_version windows_version
= WINDOWS_UNSUPPORTED
;
105 static int concurrent_usage
= -1;
106 usbi_mutex_t autoclaim_lock
;
108 // NB: index 0 is for monotonic and 1 is for the thread exit event
109 HANDLE timer_thread
= NULL
;
110 HANDLE timer_mutex
= NULL
;
111 struct timespec timer_tp
;
112 volatile LONG request_count
[2] = {0, 1}; // last one must be > 0
113 HANDLE timer_request
[2] = { NULL
, NULL
};
114 HANDLE timer_response
= NULL
;
116 #define CHECK_WINUSBX_AVAILABLE(sub_api) do { if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; \
117 if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0)
118 static struct winusb_interface WinUSBX
[SUB_API_MAX
];
119 const char* sub_api_name
[SUB_API_MAX
] = WINUSBX_DRV_NAMES
;
120 bool api_hid_available
= false;
121 #define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0)
123 static inline BOOLEAN
guid_eq(const GUID
*guid1
, const GUID
*guid2
) {
124 if ((guid1
!= NULL
) && (guid2
!= NULL
)) {
125 return (memcmp(guid1
, guid2
, sizeof(GUID
)) == 0);
130 #if defined(ENABLE_LOGGING)
131 static char* guid_to_string(const GUID
* guid
)
133 static char guid_string
[MAX_GUID_STRING_LENGTH
];
135 if (guid
== NULL
) return NULL
;
136 sprintf(guid_string
, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
137 (unsigned int)guid
->Data1
, guid
->Data2
, guid
->Data3
,
138 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
139 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
145 * Converts a windows error to human readable string
146 * uses retval as errorcode, or, if 0, use GetLastError()
148 #if defined(ENABLE_LOGGING)
149 static char *windows_error_str(uint32_t retval
)
151 static char err_string
[ERR_BUFFER_SIZE
];
155 uint32_t error_code
, format_error
;
157 error_code
= retval
?retval
:GetLastError();
159 safe_sprintf(err_string
, ERR_BUFFER_SIZE
, "[%u] ", error_code
);
161 size
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, error_code
,
162 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), &err_string
[safe_strlen(err_string
)],
163 ERR_BUFFER_SIZE
- (DWORD
)safe_strlen(err_string
), NULL
);
165 format_error
= GetLastError();
167 safe_sprintf(err_string
, ERR_BUFFER_SIZE
,
168 "Windows error code %u (FormatMessage error code %u)", error_code
, format_error
);
170 safe_sprintf(err_string
, ERR_BUFFER_SIZE
, "Unknown error code %u", error_code
);
172 // Remove CR/LF terminators
173 for (i
=safe_strlen(err_string
)-1; (i
>=0) && ((err_string
[i
]==0x0A) || (err_string
[i
]==0x0D)); i
--) {
182 * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
183 * Return an allocated sanitized string or NULL on error.
185 static char* sanitize_path(const char* path
)
187 const char root_prefix
[] = "\\\\.\\";
188 size_t j
, size
, root_size
;
189 char* ret_path
= NULL
;
195 size
= safe_strlen(path
)+1;
196 root_size
= sizeof(root_prefix
)-1;
198 // Microsoft indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
199 if (!((size
> 3) && (((path
[0] == '\\') && (path
[1] == '\\') && (path
[3] == '\\')) ||
200 ((path
[0] == '#') && (path
[1] == '#') && (path
[3] == '#'))))) {
201 add_root
= root_size
;
205 if ((ret_path
= (char*) calloc(size
, 1)) == NULL
)
208 safe_strcpy(&ret_path
[add_root
], size
-add_root
, path
);
210 // Ensure consistancy with root prefix
211 for (j
=0; j
<root_size
; j
++)
212 ret_path
[j
] = root_prefix
[j
];
214 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
215 for(j
=root_size
; j
<size
; j
++) {
216 ret_path
[j
] = (char)toupper((int)ret_path
[j
]); // Fix case too
217 if (ret_path
[j
] == '\\')
225 * Cfgmgr32, OLE32 and SetupAPI DLL functions
227 static int init_dlls(void)
229 DLL_LOAD(Cfgmgr32
.dll
, CM_Get_Parent
, TRUE
);
230 DLL_LOAD(Cfgmgr32
.dll
, CM_Get_Child
, TRUE
);
231 DLL_LOAD(Cfgmgr32
.dll
, CM_Get_Sibling
, TRUE
);
232 DLL_LOAD(Cfgmgr32
.dll
, CM_Get_Device_IDA
, TRUE
);
233 // Prefixed to avoid conflict with header files
234 DLL_LOAD_PREFIXED(OLE32
.dll
, p
, CLSIDFromString
, TRUE
);
235 DLL_LOAD_PREFIXED(SetupAPI
.dll
, p
, SetupDiGetClassDevsA
, TRUE
);
236 DLL_LOAD_PREFIXED(SetupAPI
.dll
, p
, SetupDiEnumDeviceInfo
, TRUE
);
237 DLL_LOAD_PREFIXED(SetupAPI
.dll
, p
, SetupDiEnumDeviceInterfaces
, TRUE
);
238 DLL_LOAD_PREFIXED(SetupAPI
.dll
, p
, SetupDiGetDeviceInterfaceDetailA
, TRUE
);
239 DLL_LOAD_PREFIXED(SetupAPI
.dll
, p
, SetupDiDestroyDeviceInfoList
, TRUE
);
240 DLL_LOAD_PREFIXED(SetupAPI
.dll
, p
, SetupDiOpenDevRegKey
, TRUE
);
241 DLL_LOAD_PREFIXED(SetupAPI
.dll
, p
, SetupDiGetDeviceRegistryPropertyA
, TRUE
);
242 DLL_LOAD_PREFIXED(SetupAPI
.dll
, p
, SetupDiOpenDeviceInterfaceRegKey
, TRUE
);
243 DLL_LOAD_PREFIXED(AdvAPI32
.dll
, p
, RegQueryValueExW
, TRUE
);
244 DLL_LOAD_PREFIXED(AdvAPI32
.dll
, p
, RegCloseKey
, TRUE
);
245 return LIBUSB_SUCCESS
;
249 * enumerate interfaces for the whole USB class
252 * dev_info: a pointer to a dev_info list
253 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
254 * usb_class: the generic USB class for which to retrieve interface details
255 * index: zero based index of the interface in the device info list
257 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
258 * structure returned and call this function repeatedly using the same guid (with an
259 * incremented index starting at zero) until all interfaces have been returned.
261 static bool get_devinfo_data(struct libusb_context
*ctx
,
262 HDEVINFO
*dev_info
, SP_DEVINFO_DATA
*dev_info_data
, const char* usb_class
, unsigned _index
)
265 *dev_info
= pSetupDiGetClassDevsA(NULL
, usb_class
, NULL
, DIGCF_PRESENT
|DIGCF_ALLCLASSES
);
266 if (*dev_info
== INVALID_HANDLE_VALUE
) {
271 dev_info_data
->cbSize
= sizeof(SP_DEVINFO_DATA
);
272 if (!pSetupDiEnumDeviceInfo(*dev_info
, _index
, dev_info_data
)) {
273 if (GetLastError() != ERROR_NO_MORE_ITEMS
) {
274 usbi_err(ctx
, "Could not obtain device info data for index %u: %s",
275 _index
, windows_error_str(0));
277 pSetupDiDestroyDeviceInfoList(*dev_info
);
278 *dev_info
= INVALID_HANDLE_VALUE
;
285 * enumerate interfaces for a specific GUID
288 * dev_info: a pointer to a dev_info list
289 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
290 * guid: the GUID for which to retrieve interface details
291 * index: zero based index of the interface in the device info list
293 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
294 * structure returned and call this function repeatedly using the same guid (with an
295 * incremented index starting at zero) until all interfaces have been returned.
297 static SP_DEVICE_INTERFACE_DETAIL_DATA_A
*get_interface_details(struct libusb_context
*ctx
,
298 HDEVINFO
*dev_info
, SP_DEVINFO_DATA
*dev_info_data
, const GUID
* guid
, unsigned _index
)
300 SP_DEVICE_INTERFACE_DATA dev_interface_data
;
301 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*dev_interface_details
= NULL
;
305 *dev_info
= pSetupDiGetClassDevsA(guid
, NULL
, NULL
, DIGCF_PRESENT
|DIGCF_DEVICEINTERFACE
);
308 if (dev_info_data
!= NULL
) {
309 dev_info_data
->cbSize
= sizeof(SP_DEVINFO_DATA
);
310 if (!pSetupDiEnumDeviceInfo(*dev_info
, _index
, dev_info_data
)) {
311 if (GetLastError() != ERROR_NO_MORE_ITEMS
) {
312 usbi_err(ctx
, "Could not obtain device info data for index %u: %s",
313 _index
, windows_error_str(0));
315 pSetupDiDestroyDeviceInfoList(*dev_info
);
316 *dev_info
= INVALID_HANDLE_VALUE
;
321 dev_interface_data
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
322 if (!pSetupDiEnumDeviceInterfaces(*dev_info
, NULL
, guid
, _index
, &dev_interface_data
)) {
323 if (GetLastError() != ERROR_NO_MORE_ITEMS
) {
324 usbi_err(ctx
, "Could not obtain interface data for index %u: %s",
325 _index
, windows_error_str(0));
327 pSetupDiDestroyDeviceInfoList(*dev_info
);
328 *dev_info
= INVALID_HANDLE_VALUE
;
332 // Read interface data (dummy + actual) to access the device path
333 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info
, &dev_interface_data
, NULL
, 0, &size
, NULL
)) {
334 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
335 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
336 usbi_err(ctx
, "could not access interface data (dummy) for index %u: %s",
337 _index
, windows_error_str(0));
341 usbi_err(ctx
, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
345 if ((dev_interface_details
= (SP_DEVICE_INTERFACE_DETAIL_DATA_A
*) calloc(size
, 1)) == NULL
) {
346 usbi_err(ctx
, "could not allocate interface data for index %u.", _index
);
350 dev_interface_details
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A
);
351 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info
, &dev_interface_data
,
352 dev_interface_details
, size
, &size
, NULL
)) {
353 usbi_err(ctx
, "could not access interface data (actual) for index %u: %s",
354 _index
, windows_error_str(0));
357 return dev_interface_details
;
360 pSetupDiDestroyDeviceInfoList(*dev_info
);
361 *dev_info
= INVALID_HANDLE_VALUE
;
365 /* For libusb0 filter */
366 static SP_DEVICE_INTERFACE_DETAIL_DATA_A
*get_interface_details_filter(struct libusb_context
*ctx
,
367 HDEVINFO
*dev_info
, SP_DEVINFO_DATA
*dev_info_data
, const GUID
* guid
, unsigned _index
, char* filter_path
){
368 SP_DEVICE_INTERFACE_DATA dev_interface_data
;
369 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*dev_interface_details
= NULL
;
372 *dev_info
= pSetupDiGetClassDevsA(guid
, NULL
, NULL
, DIGCF_PRESENT
|DIGCF_DEVICEINTERFACE
);
374 if (dev_info_data
!= NULL
) {
375 dev_info_data
->cbSize
= sizeof(SP_DEVINFO_DATA
);
376 if (!pSetupDiEnumDeviceInfo(*dev_info
, _index
, dev_info_data
)) {
377 if (GetLastError() != ERROR_NO_MORE_ITEMS
) {
378 usbi_err(ctx
, "Could not obtain device info data for index %u: %s",
379 _index
, windows_error_str(0));
381 pSetupDiDestroyDeviceInfoList(*dev_info
);
382 *dev_info
= INVALID_HANDLE_VALUE
;
386 dev_interface_data
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
387 if (!pSetupDiEnumDeviceInterfaces(*dev_info
, NULL
, guid
, _index
, &dev_interface_data
)) {
388 if (GetLastError() != ERROR_NO_MORE_ITEMS
) {
389 usbi_err(ctx
, "Could not obtain interface data for index %u: %s",
390 _index
, windows_error_str(0));
392 pSetupDiDestroyDeviceInfoList(*dev_info
);
393 *dev_info
= INVALID_HANDLE_VALUE
;
396 // Read interface data (dummy + actual) to access the device path
397 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info
, &dev_interface_data
, NULL
, 0, &size
, NULL
)) {
398 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
399 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
400 usbi_err(ctx
, "could not access interface data (dummy) for index %u: %s",
401 _index
, windows_error_str(0));
405 usbi_err(ctx
, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
408 if ((dev_interface_details
= malloc(size
)) == NULL
) {
409 usbi_err(ctx
, "could not allocate interface data for index %u.", _index
);
412 dev_interface_details
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A
);
413 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info
, &dev_interface_data
,
414 dev_interface_details
, size
, &size
, NULL
)) {
415 usbi_err(ctx
, "could not access interface data (actual) for index %u: %s",
416 _index
, windows_error_str(0));
418 // [trobinso] lookup the libusb0 symbolic index.
419 if (dev_interface_details
) {
420 HKEY hkey_device_interface
=pSetupDiOpenDeviceInterfaceRegKey(*dev_info
,&dev_interface_data
,0,KEY_READ
);
421 if (hkey_device_interface
!= INVALID_HANDLE_VALUE
) {
422 DWORD libusb0_symboliclink_index
=0;
423 DWORD value_length
=sizeof(DWORD
);
426 status
= pRegQueryValueExW(hkey_device_interface
, L
"LUsb0", NULL
, &value_type
,
427 (LPBYTE
) &libusb0_symboliclink_index
, &value_length
);
428 if (status
== ERROR_SUCCESS
) {
429 if (libusb0_symboliclink_index
< 256) {
430 // libusb0.sys is connected to this device instance.
431 // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
432 safe_sprintf(filter_path
, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index
);
433 usbi_dbg("assigned libusb0 symbolic link %s", filter_path
);
435 // libusb0.sys was connected to this device instance at one time; but not anymore.
438 pRegCloseKey(hkey_device_interface
);
441 return dev_interface_details
;
443 pSetupDiDestroyDeviceInfoList(*dev_info
);
444 *dev_info
= INVALID_HANDLE_VALUE
;
447 /* Hash table functions - modified From glibc 2.3.2:
448 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
449 [Knuth] The Art of Computer Programming, part 3 (6.4) */
450 typedef struct htab_entry
{
454 htab_entry
* htab_table
= NULL
;
455 usbi_mutex_t htab_write_mutex
= NULL
;
456 unsigned long htab_size
, htab_filled
;
458 /* For the used double hash method the table size has to be a prime. To
459 correct the user given table size we need a prime test. This trivial
460 algorithm is adequate because the code is called only during init and
461 the number is likely to be small */
462 static int isprime(unsigned long number
)
464 // no even number will be passed
465 unsigned int divider
= 3;
467 while((divider
* divider
< number
) && (number
% divider
!= 0))
470 return (number
% divider
!= 0);
473 /* Before using the hash table we must allocate memory for it.
474 We allocate one element more as the found prime number says.
475 This is done for more effective indexing as explained in the
476 comment for the hash function. */
477 static int htab_create(struct libusb_context
*ctx
, unsigned long nel
)
479 if (htab_table
!= NULL
) {
480 usbi_err(ctx
, "hash table already allocated");
484 usbi_mutex_init(&htab_write_mutex
, NULL
);
486 // Change nel to the first prime number not smaller as nel.
492 usbi_dbg("using %d entries hash table", nel
);
495 // allocate memory and zero out.
496 htab_table
= (htab_entry
*) calloc(htab_size
+ 1, sizeof(htab_entry
));
497 if (htab_table
== NULL
) {
498 usbi_err(ctx
, "could not allocate space for hash table");
505 /* After using the hash table it has to be destroyed. */
506 static void htab_destroy(void)
509 if (htab_table
== NULL
) {
513 for (i
=0; i
<htab_size
; i
++) {
514 if (htab_table
[i
].used
) {
515 safe_free(htab_table
[i
].str
);
518 usbi_mutex_destroy(&htab_write_mutex
);
519 safe_free(htab_table
);
522 /* This is the search function. It uses double hashing with open addressing.
523 We use an trick to speed up the lookup. The table is created with one
524 more element available. This enables us to use the index zero special.
525 This index will never be used because we store the first hash index in
526 the field used where zero means not used. Every other value means used.
527 The used field can be used as a first fast comparison for equality of
528 the stored and the parameter value. This helps to prevent unnecessary
529 expensive calls of strcmp. */
530 static unsigned long htab_hash(char* str
)
532 unsigned long hval
, hval2
;
534 unsigned long r
= 5381;
541 // Compute main hash value (algorithm suggested by Nokia)
542 while ((c
= *sz
++) != 0)
543 r
= ((r
<< 5) + r
) + c
;
547 // compute table hash: simply take the modulus
548 hval
= r
% htab_size
;
552 // Try the first index
555 if (htab_table
[idx
].used
) {
556 if ( (htab_table
[idx
].used
== hval
)
557 && (safe_strcmp(str
, htab_table
[idx
].str
) == 0) ) {
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);
567 // Because size is prime this guarantees to step through all available indexes
569 idx
= htab_size
+ idx
- hval2
;
574 // If we visited all entries leave the loop unsuccessfully
579 // If entry is found use it.
580 if ( (htab_table
[idx
].used
== hval
)
581 && (safe_strcmp(str
, htab_table
[idx
].str
) == 0) ) {
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
);
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
);
610 memcpy(htab_table
[idx
].str
, str
, safe_strlen(str
)+1);
612 usbi_mutex_unlock(&htab_write_mutex
);
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
];
629 if (level
< 1) return 0;
630 for (i
= 0; i
<level
; i
++) {
631 if (CM_Get_Parent(&parent_devinst
, devinst
, 0) != CR_SUCCESS
) {
634 devinst
= parent_devinst
;
636 if (CM_Get_Device_IDA(devinst
, path
, MAX_PATH_LENGTH
, 0) != CR_SUCCESS
) {
639 // TODO: (post hotplug): try without sanitizing
640 sanitized_path
= sanitize_path(path
);
641 if (sanitized_path
== NULL
) {
644 session_id
= htab_hash(sanitized_path
);
645 safe_free(sanitized_path
);
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
)
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
);
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
){
694 const char sep_str
[2] = {LIST_SEPARATOR
, 0};
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) {
710 tok
= strtok(NULL
, sep_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
;
729 case USB_API_WINUSBX
:
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
]++;
751 if (current_interface
== USB_MAXINTERFACES
) {
752 usbi_err(ctx
, "could not auto-claim any interface");
753 r
= LIBUSB_ERROR_NOT_FOUND
;
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
;
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
);
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
);
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
;
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?
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
;
844 // We need a lock for proper auto-release
845 usbi_mutex_init(&autoclaim_lock
, NULL
);
847 // Initialize pollable file descriptors
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
);
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");
877 timer_mutex
= CreateMutex(NULL
, FALSE
, NULL
);
878 if (timer_mutex
== NULL
) {
879 usbi_err(ctx
, "could not create timer mutex - aborting");
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");
887 SetThreadAffinityMask(timer_thread
, 0);
889 // Create a hash table to store session ids. Second parameter is better if prime
890 htab_create(ctx
, HTAB_SIZE
);
892 // At this stage, either we went through full init successfully, or didn't need to
895 init_exit
: // Holds semaphore here.
896 if (!concurrent_usage
&& r
!= LIBUSB_SUCCESS
) { // First init failed?
898 SetEvent(timer_request
[1]); // actually the signal to quit the thread.
899 if (WAIT_OBJECT_0
!= WaitForSingleObject(timer_thread
, INFINITE
)) {
900 usbi_warn(ctx
, "could not wait for timer thread to quit");
901 TerminateThread(timer_thread
, 1); // shouldn't happen, but we're destroying
902 // all objects it might have held anyway.
904 CloseHandle(timer_thread
);
907 for (i
= 0; i
< 2; i
++) {
908 if (timer_request
[i
]) {
909 CloseHandle(timer_request
[i
]);
910 timer_request
[i
] = NULL
;
913 if (timer_response
) {
914 CloseHandle(timer_response
);
915 timer_response
= NULL
;
918 CloseHandle(timer_mutex
);
924 if (r
!= LIBUSB_SUCCESS
)
925 --concurrent_usage
; // Not expected to call libusb_exit if we failed.
927 ReleaseSemaphore(semaphore
, 1, NULL
); // increase count back to 1
928 CloseHandle(semaphore
);
933 * HCD (root) hubs need to have their device descriptor manually populated
935 * Note that, like Microsoft does in the device manager, we populate the
936 * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device.
938 static int force_hcd_device_descriptor(struct libusb_device
*dev
)
940 struct windows_device_priv
*parent_priv
, *priv
= _device_priv(dev
);
941 struct libusb_context
*ctx
= DEVICE_CTX(dev
);
944 dev
->num_configurations
= 1;
945 priv
->dev_descriptor
.bLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
946 priv
->dev_descriptor
.bDescriptorType
= USB_DEVICE_DESCRIPTOR_TYPE
;
947 priv
->dev_descriptor
.bNumConfigurations
= 1;
948 priv
->active_config
= 1;
950 if (priv
->parent_dev
== NULL
) {
951 usbi_err(ctx
, "program assertion failed - HCD hub has no parent");
952 return LIBUSB_ERROR_NO_DEVICE
;
954 parent_priv
= _device_priv(priv
->parent_dev
);
955 if (sscanf(parent_priv
->path
, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid
, &pid
) == 2) {
956 priv
->dev_descriptor
.idVendor
= (uint16_t)vid
;
957 priv
->dev_descriptor
.idProduct
= (uint16_t)pid
;
959 usbi_warn(ctx
, "could not infer VID/PID of HCD hub from '%s'", parent_priv
->path
);
960 priv
->dev_descriptor
.idVendor
= 0x1d6b; // Linux Foundation root hub
961 priv
->dev_descriptor
.idProduct
= 1;
963 return LIBUSB_SUCCESS
;
967 * fetch and cache all the config descriptors through I/O
969 static int cache_config_descriptors(struct libusb_device
*dev
, HANDLE hub_handle
, char* device_id
)
971 DWORD size
, ret_size
;
972 struct libusb_context
*ctx
= DEVICE_CTX(dev
);
973 struct windows_device_priv
*priv
= _device_priv(dev
);
977 USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short
; // dummy request
978 PUSB_DESCRIPTOR_REQUEST cd_buf_actual
= NULL
; // actual request
979 PUSB_CONFIGURATION_DESCRIPTOR cd_data
= NULL
;
981 if (dev
->num_configurations
== 0)
982 return LIBUSB_ERROR_INVALID_PARAM
;
984 priv
->config_descriptor
= (unsigned char**) calloc(dev
->num_configurations
, sizeof(unsigned char*));
985 if (priv
->config_descriptor
== NULL
)
986 return LIBUSB_ERROR_NO_MEM
;
987 for (i
=0; i
<dev
->num_configurations
; i
++)
988 priv
->config_descriptor
[i
] = NULL
;
990 for (i
=0, r
=LIBUSB_SUCCESS
; ; i
++)
992 // safe loop: release all dynamic resources
993 safe_free(cd_buf_actual
);
995 // safe loop: end of loop condition
996 if ((i
>= dev
->num_configurations
) || (r
!= LIBUSB_SUCCESS
))
999 size
= sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT
);
1000 memset(&cd_buf_short
, 0, size
);
1002 cd_buf_short
.req
.ConnectionIndex
= (ULONG
)priv
->port
;
1003 cd_buf_short
.req
.SetupPacket
.bmRequest
= LIBUSB_ENDPOINT_IN
;
1004 cd_buf_short
.req
.SetupPacket
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1005 cd_buf_short
.req
.SetupPacket
.wValue
= (USB_CONFIGURATION_DESCRIPTOR_TYPE
<< 8) | i
;
1006 cd_buf_short
.req
.SetupPacket
.wIndex
= i
;
1007 cd_buf_short
.req
.SetupPacket
.wLength
= (USHORT
)(size
- sizeof(USB_DESCRIPTOR_REQUEST
));
1009 // Dummy call to get the required data size. Initial failures are reported as info rather
1010 // than error as they can occur for non-penalizing situations, such as with some hubs.
1011 if (!DeviceIoControl(hub_handle
, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION
, &cd_buf_short
, size
,
1012 &cd_buf_short
, size
, &ret_size
, NULL
)) {
1013 usbi_info(ctx
, "could not access configuration descriptor (dummy) for '%s': %s", device_id
, windows_error_str(0));
1014 LOOP_BREAK(LIBUSB_ERROR_IO
);
1017 if ((ret_size
!= size
) || (cd_buf_short
.data
.wTotalLength
< sizeof(USB_CONFIGURATION_DESCRIPTOR
))) {
1018 usbi_info(ctx
, "unexpected configuration descriptor size (dummy) for '%s'.", device_id
);
1019 LOOP_BREAK(LIBUSB_ERROR_IO
);
1022 size
= sizeof(USB_DESCRIPTOR_REQUEST
) + cd_buf_short
.data
.wTotalLength
;
1023 if ((cd_buf_actual
= (PUSB_DESCRIPTOR_REQUEST
) calloc(1, size
)) == NULL
) {
1024 usbi_err(ctx
, "could not allocate configuration descriptor buffer for '%s'.", device_id
);
1025 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1027 memset(cd_buf_actual
, 0, size
);
1030 cd_buf_actual
->ConnectionIndex
= (ULONG
)priv
->port
;
1031 cd_buf_actual
->SetupPacket
.bmRequest
= LIBUSB_ENDPOINT_IN
;
1032 cd_buf_actual
->SetupPacket
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1033 cd_buf_actual
->SetupPacket
.wValue
= (USB_CONFIGURATION_DESCRIPTOR_TYPE
<< 8) | i
;
1034 cd_buf_actual
->SetupPacket
.wIndex
= i
;
1035 cd_buf_actual
->SetupPacket
.wLength
= (USHORT
)(size
- sizeof(USB_DESCRIPTOR_REQUEST
));
1037 if (!DeviceIoControl(hub_handle
, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION
, cd_buf_actual
, size
,
1038 cd_buf_actual
, size
, &ret_size
, NULL
)) {
1039 usbi_err(ctx
, "could not access configuration descriptor (actual) for '%s': %s", device_id
, windows_error_str(0));
1040 LOOP_BREAK(LIBUSB_ERROR_IO
);
1043 cd_data
= (PUSB_CONFIGURATION_DESCRIPTOR
)((UCHAR
*)cd_buf_actual
+sizeof(USB_DESCRIPTOR_REQUEST
));
1045 if ((size
!= ret_size
) || (cd_data
->wTotalLength
!= cd_buf_short
.data
.wTotalLength
)) {
1046 usbi_err(ctx
, "unexpected configuration descriptor size (actual) for '%s'.", device_id
);
1047 LOOP_BREAK(LIBUSB_ERROR_IO
);
1050 if (cd_data
->bDescriptorType
!= USB_CONFIGURATION_DESCRIPTOR_TYPE
) {
1051 usbi_err(ctx
, "not a configuration descriptor for '%s'", device_id
);
1052 LOOP_BREAK(LIBUSB_ERROR_IO
);
1055 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1056 i
, cd_data
->bConfigurationValue
, cd_data
->wTotalLength
);
1058 // Cache the descriptor
1059 priv
->config_descriptor
[i
] = (unsigned char*) malloc(cd_data
->wTotalLength
);
1060 if (priv
->config_descriptor
[i
] == NULL
)
1061 return LIBUSB_ERROR_NO_MEM
;
1062 memcpy(priv
->config_descriptor
[i
], cd_data
, cd_data
->wTotalLength
);
1064 return LIBUSB_SUCCESS
;
1068 * Populate a libusbx device structure
1070 static int init_device(struct libusb_device
* dev
, struct libusb_device
* parent_dev
,
1071 uint8_t port_number
, char* device_id
, DWORD devinst
)
1075 USB_NODE_CONNECTION_INFORMATION_EX conn_info
;
1076 struct windows_device_priv
*priv
, *parent_priv
;
1077 struct libusb_context
*ctx
= DEVICE_CTX(dev
);
1078 struct libusb_device
* tmp_dev
;
1081 if ((dev
== NULL
) || (parent_dev
== NULL
)) {
1082 return LIBUSB_ERROR_NOT_FOUND
;
1084 priv
= _device_priv(dev
);
1085 parent_priv
= _device_priv(parent_dev
);
1086 if (parent_priv
->apib
->id
!= USB_API_HUB
) {
1087 usbi_warn(ctx
, "parent for device '%s' is not a hub", device_id
);
1088 return LIBUSB_ERROR_NOT_FOUND
;
1091 // It is possible for the parent hub not to have been initialized yet
1092 // If that's the case, lookup the ancestors to set the bus number
1093 if (parent_dev
->bus_number
== 0) {
1095 tmp_dev
= usbi_get_device_by_session_id(ctx
, get_ancestor_session_id(devinst
, i
));
1096 if (tmp_dev
== NULL
) break;
1097 if (tmp_dev
->bus_number
!= 0) {
1098 usbi_dbg("got bus number from ancestor #%d", i
);
1099 parent_dev
->bus_number
= tmp_dev
->bus_number
;
1104 if (parent_dev
->bus_number
== 0) {
1105 usbi_err(ctx
, "program assertion failed: unable to find ancestor bus number for '%s'", device_id
);
1106 return LIBUSB_ERROR_NOT_FOUND
;
1108 dev
->bus_number
= parent_dev
->bus_number
;
1109 priv
->port
= port_number
;
1110 dev
->port_number
= port_number
;
1111 priv
->depth
= parent_priv
->depth
+ 1;
1112 priv
->parent_dev
= parent_dev
;
1113 dev
->parent_dev
= parent_dev
;
1115 // If the device address is already set, we can stop here
1116 if (dev
->device_address
!= 0) {
1117 return LIBUSB_SUCCESS
;
1119 memset(&conn_info
, 0, sizeof(conn_info
));
1120 if (priv
->depth
!= 0) { // Not a HCD hub
1121 handle
= CreateFileA(parent_priv
->path
, GENERIC_WRITE
, FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
1122 FILE_FLAG_OVERLAPPED
, NULL
);
1123 if (handle
== INVALID_HANDLE_VALUE
) {
1124 usbi_warn(ctx
, "could not open hub %s: %s", parent_priv
->path
, windows_error_str(0));
1125 return LIBUSB_ERROR_ACCESS
;
1127 size
= sizeof(conn_info
);
1128 conn_info
.ConnectionIndex
= (ULONG
)port_number
;
1129 if (!DeviceIoControl(handle
, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX
, &conn_info
, size
,
1130 &conn_info
, size
, &size
, NULL
)) {
1131 usbi_warn(ctx
, "could not get node connection information for device '%s': %s",
1132 device_id
, windows_error_str(0));
1133 safe_closehandle(handle
);
1134 return LIBUSB_ERROR_NO_DEVICE
;
1136 if (conn_info
.ConnectionStatus
== NoDeviceConnected
) {
1137 usbi_err(ctx
, "device '%s' is no longer connected!", device_id
);
1138 safe_closehandle(handle
);
1139 return LIBUSB_ERROR_NO_DEVICE
;
1141 memcpy(&priv
->dev_descriptor
, &(conn_info
.DeviceDescriptor
), sizeof(USB_DEVICE_DESCRIPTOR
));
1142 dev
->num_configurations
= priv
->dev_descriptor
.bNumConfigurations
;
1143 priv
->active_config
= conn_info
.CurrentConfigurationValue
;
1144 usbi_dbg("found %d configurations (active conf: %d)", dev
->num_configurations
, priv
->active_config
);
1145 // If we can't read the config descriptors, just set the number of confs to zero
1146 if (cache_config_descriptors(dev
, handle
, device_id
) != LIBUSB_SUCCESS
) {
1147 dev
->num_configurations
= 0;
1148 priv
->dev_descriptor
.bNumConfigurations
= 0;
1150 safe_closehandle(handle
);
1152 if (conn_info
.DeviceAddress
> UINT8_MAX
) {
1153 usbi_err(ctx
, "program assertion failed: device address overflow");
1155 dev
->device_address
= (uint8_t)conn_info
.DeviceAddress
+ 1;
1156 if (dev
->device_address
== 1) {
1157 usbi_err(ctx
, "program assertion failed: device address collision with root hub");
1159 switch (conn_info
.Speed
) {
1160 case 0: dev
->speed
= LIBUSB_SPEED_LOW
; break;
1161 case 1: dev
->speed
= LIBUSB_SPEED_FULL
; break;
1162 case 2: dev
->speed
= LIBUSB_SPEED_HIGH
; break;
1163 case 3: dev
->speed
= LIBUSB_SPEED_SUPER
; break;
1165 usbi_warn(ctx
, "Got unknown device speed %d", conn_info
.Speed
);
1169 dev
->device_address
= 1; // root hubs are set to use device number 1
1170 force_hcd_device_descriptor(dev
);
1173 usbi_sanitize_device(dev
);
1175 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1176 dev
->bus_number
, dev
->device_address
, priv
->depth
, priv
->port
, device_id
);
1178 return LIBUSB_SUCCESS
;
1181 // Returns the api type, or 0 if not found/unsupported
1182 static void get_api_type(struct libusb_context
*ctx
, HDEVINFO
*dev_info
,
1183 SP_DEVINFO_DATA
*dev_info_data
, int *api
, int *sub_api
)
1185 // Precedence for filter drivers vs driver is in the order of this array
1186 struct driver_lookup lookup
[3] = {
1187 {"\0\0", SPDRP_SERVICE
, "driver"},
1188 {"\0\0", SPDRP_UPPERFILTERS
, "upper filter driver"},
1189 {"\0\0", SPDRP_LOWERFILTERS
, "lower filter driver"}
1191 DWORD size
, reg_type
;
1195 *api
= USB_API_UNSUPPORTED
;
1196 *sub_api
= SUB_API_NOTSET
;
1197 // Check the service & filter names to know the API we should use
1198 for (k
=0; k
<3; k
++) {
1199 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info
, dev_info_data
, lookup
[k
].reg_prop
,
1200 ®_type
, (BYTE
*)lookup
[k
].list
, MAX_KEY_LENGTH
, &size
)) {
1201 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1202 if (lookup
[k
].reg_prop
== SPDRP_SERVICE
) {
1203 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1204 lookup
[k
].list
[safe_strlen(lookup
[k
].list
)+1] = 0;
1206 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1207 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1208 // (currently ';'), so even if an unsuported one does, it's not an issue
1209 for (l
=0; (lookup
[k
].list
[l
] != 0) || (lookup
[k
].list
[l
+1] != 0); l
++) {
1210 if (lookup
[k
].list
[l
] == 0) {
1211 lookup
[k
].list
[l
] = LIST_SEPARATOR
;
1214 usbi_dbg("%s(s): %s", lookup
[k
].designation
, lookup
[k
].list
);
1216 if (GetLastError() != ERROR_INVALID_DATA
) {
1217 usbi_dbg("could not access %s: %s", lookup
[k
].designation
, windows_error_str(0));
1219 lookup
[k
].list
[0] = 0;
1223 for (i
=1; i
<USB_API_MAX
; i
++) {
1224 for (k
=0; k
<3; k
++) {
1225 j
= get_sub_api(lookup
[k
].list
, i
);
1227 usbi_dbg("matched %s name against %s API",
1228 lookup
[k
].designation
, (i
!=USB_API_WINUSBX
)?usb_api_backend
[i
].designation
:sub_api_name
[j
]);
1237 static int set_composite_interface(struct libusb_context
* ctx
, struct libusb_device
* dev
,
1238 char* dev_interface_path
, char* device_id
, int api
, int sub_api
)
1241 struct windows_device_priv
*priv
= _device_priv(dev
);
1242 int interface_number
;
1244 if (priv
->apib
->id
!= USB_API_COMPOSITE
) {
1245 usbi_err(ctx
, "program assertion failed: '%s' is not composite", device_id
);
1246 return LIBUSB_ERROR_NO_DEVICE
;
1249 // Because MI_## are not necessarily in sequential order (some composite
1250 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1251 // interface number from the path's MI value
1252 interface_number
= 0;
1253 for (i
=0; device_id
[i
] != 0; ) {
1254 if ( (device_id
[i
++] == 'M') && (device_id
[i
++] == 'I')
1255 && (device_id
[i
++] == '_') ) {
1256 interface_number
= (device_id
[i
++] - '0')*10;
1257 interface_number
+= device_id
[i
] - '0';
1262 if (device_id
[i
] == 0) {
1263 usbi_warn(ctx
, "failure to read interface number for %s. Using default value %d",
1264 device_id
, interface_number
);
1267 if (priv
->usb_interface
[interface_number
].path
!= NULL
) {
1268 if (api
== USB_API_HID
) {
1269 // HID devices can have multiple collections (COL##) for each MI_## interface
1270 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1271 interface_number
, device_id
);
1272 return LIBUSB_ERROR_ACCESS
;
1274 // In other cases, just use the latest data
1275 safe_free(priv
->usb_interface
[interface_number
].path
);
1278 usbi_dbg("interface[%d] = %s", interface_number
, dev_interface_path
);
1279 priv
->usb_interface
[interface_number
].path
= dev_interface_path
;
1280 priv
->usb_interface
[interface_number
].apib
= &usb_api_backend
[api
];
1281 priv
->usb_interface
[interface_number
].sub_api
= sub_api
;
1282 if ((api
== USB_API_HID
) && (priv
->hid
== NULL
)) {
1283 priv
->hid
= (struct hid_device_priv
*) calloc(1, sizeof(struct hid_device_priv
));
1284 if (priv
->hid
== NULL
)
1285 return LIBUSB_ERROR_NO_MEM
;
1288 return LIBUSB_SUCCESS
;
1291 static int set_hid_interface(struct libusb_context
* ctx
, struct libusb_device
* dev
,
1292 char* dev_interface_path
)
1295 struct windows_device_priv
*priv
= _device_priv(dev
);
1297 if (priv
->hid
== NULL
) {
1298 usbi_err(ctx
, "program assertion failed: parent is not HID");
1299 return LIBUSB_ERROR_NO_DEVICE
;
1301 if (priv
->hid
->nb_interfaces
== USB_MAXINTERFACES
) {
1302 usbi_err(ctx
, "program assertion failed: max USB interfaces reached for HID device");
1303 return LIBUSB_ERROR_NO_DEVICE
;
1305 for (i
=0; i
<priv
->hid
->nb_interfaces
; i
++) {
1306 if (safe_strcmp(priv
->usb_interface
[i
].path
, dev_interface_path
) == 0) {
1307 usbi_dbg("interface[%d] already set to %s", i
, dev_interface_path
);
1308 return LIBUSB_SUCCESS
;
1312 priv
->usb_interface
[priv
->hid
->nb_interfaces
].path
= dev_interface_path
;
1313 priv
->usb_interface
[priv
->hid
->nb_interfaces
].apib
= &usb_api_backend
[USB_API_HID
];
1314 usbi_dbg("interface[%d] = %s", priv
->hid
->nb_interfaces
, dev_interface_path
);
1315 priv
->hid
->nb_interfaces
++;
1316 return LIBUSB_SUCCESS
;
1320 * get_device_list: libusbx backend device enumeration function
1322 static int windows_get_device_list(struct libusb_context
*ctx
, struct discovered_devs
**_discdevs
)
1324 struct discovered_devs
*discdevs
;
1325 HDEVINFO dev_info
= { 0 };
1326 const char* usb_class
[] = {"USB", "NUSB3", "IUSB3"};
1327 SP_DEVINFO_DATA dev_info_data
= { 0 };
1328 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*dev_interface_details
= NULL
;
1330 #define MAX_ENUM_GUIDS 64
1331 const GUID
* guid
[MAX_ENUM_GUIDS
];
1337 int r
= LIBUSB_SUCCESS
;
1339 size_t class_index
= 0;
1340 unsigned int nb_guids
, pass
, i
, j
, ancestor
;
1341 char path
[MAX_PATH_LENGTH
];
1342 char strbuf
[MAX_PATH_LENGTH
];
1343 struct libusb_device
*dev
, *parent_dev
;
1344 struct windows_device_priv
*priv
, *parent_priv
;
1345 char* dev_interface_path
= NULL
;
1346 char* dev_id_path
= NULL
;
1347 unsigned long session_id
;
1348 DWORD size
, reg_type
, port_nr
, install_state
;
1350 WCHAR guid_string_w
[MAX_GUID_STRING_LENGTH
];
1353 // Keep a list of newly allocated devs to unref
1354 libusb_device
** unref_list
;
1355 unsigned int unref_size
= 64;
1356 unsigned int unref_cur
= 0;
1358 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1359 // PASS 2 : (re)enumerate HUBS
1360 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1361 // and list additional USB device interface GUIDs to explore
1362 // PASS 4 : (re)enumerate master USB devices that have a device interface
1363 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1364 // set the device interfaces.
1366 // Init the GUID table
1367 guid
[HCD_PASS
] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER
;
1368 guid
[HUB_PASS
] = &GUID_DEVINTERFACE_USB_HUB
;
1369 guid
[GEN_PASS
] = NULL
;
1370 guid
[DEV_PASS
] = &GUID_DEVINTERFACE_USB_DEVICE
;
1371 HidD_GetHidGuid(&hid_guid
);
1372 guid
[HID_PASS
] = &hid_guid
;
1373 nb_guids
= HID_PASS
+1;
1375 unref_list
= (libusb_device
**) calloc(unref_size
, sizeof(libusb_device
*));
1376 if (unref_list
== NULL
) {
1377 return LIBUSB_ERROR_NO_MEM
;
1380 for (pass
= 0; ((pass
< nb_guids
) && (r
== LIBUSB_SUCCESS
)); pass
++) {
1381 //#define ENUM_DEBUG
1383 const char *passname
[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1384 usbi_dbg("\n#### PROCESSING %ss %s", passname
[(pass
<=HID_PASS
)?pass
:HID_PASS
+1],
1385 (pass
!=GEN_PASS
)?guid_to_string(guid
[pass
]):"");
1387 for (i
= 0; ; i
++) {
1388 // safe loop: free up any (unprotected) dynamic resource
1389 // NB: this is always executed before breaking the loop
1390 safe_free(dev_interface_details
);
1391 safe_free(dev_interface_path
);
1392 safe_free(dev_id_path
);
1393 priv
= parent_priv
= NULL
;
1394 dev
= parent_dev
= NULL
;
1396 // Safe loop: end of loop conditions
1397 if (r
!= LIBUSB_SUCCESS
) {
1400 if ((pass
== HCD_PASS
) && (i
== UINT8_MAX
)) {
1401 usbi_warn(ctx
, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX
);
1404 if (pass
!= GEN_PASS
) {
1405 // Except for GEN, all passes deal with device interfaces
1406 dev_interface_details
= get_interface_details(ctx
, &dev_info
, &dev_info_data
, guid
[pass
], i
);
1407 if (dev_interface_details
== NULL
) {
1410 dev_interface_path
= sanitize_path(dev_interface_details
->DevicePath
);
1411 if (dev_interface_path
== NULL
) {
1412 usbi_warn(ctx
, "could not sanitize device interface path for '%s'", dev_interface_details
->DevicePath
);
1417 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1418 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1419 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1420 for (; class_index
< ARRAYSIZE(usb_class
); class_index
++) {
1421 if (get_devinfo_data(ctx
, &dev_info
, &dev_info_data
, usb_class
[class_index
], i
))
1425 if (class_index
>= ARRAYSIZE(usb_class
))
1429 // Read the Device ID path. This is what we'll use as UID
1430 // Note that if the device is plugged in a different port or hub, the Device ID changes
1431 if (CM_Get_Device_IDA(dev_info_data
.DevInst
, path
, sizeof(path
), 0) != CR_SUCCESS
) {
1432 usbi_warn(ctx
, "could not read the device id path for devinst %X, skipping",
1433 dev_info_data
.DevInst
);
1436 dev_id_path
= sanitize_path(path
);
1437 if (dev_id_path
== NULL
) {
1438 usbi_warn(ctx
, "could not sanitize device id path for devinst %X, skipping",
1439 dev_info_data
.DevInst
);
1443 usbi_dbg("PRO: %s", dev_id_path
);
1446 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1448 if ((pass
>= HUB_PASS
) && (pass
<= GEN_PASS
)) {
1449 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_ADDRESS
,
1450 ®_type
, (BYTE
*)&port_nr
, 4, &size
))
1452 usbi_warn(ctx
, "could not retrieve port number for device '%s', skipping: %s",
1453 dev_id_path
, windows_error_str(0));
1458 // Set API to use or get additional data from generic pass
1459 api
= USB_API_UNSUPPORTED
;
1460 sub_api
= SUB_API_NOTSET
;
1465 // We use the GEN pass to detect driverless devices...
1466 size
= sizeof(strbuf
);
1467 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_DRIVER
,
1468 ®_type
, (BYTE
*)strbuf
, size
, &size
)) {
1469 usbi_info(ctx
, "The following device has no driver: '%s'", dev_id_path
);
1470 usbi_info(ctx
, "libusbx will not be able to access it.");
1472 // ...and to add the additional device interface GUIDs
1473 key
= pSetupDiOpenDevRegKey(dev_info
, &dev_info_data
, DICS_FLAG_GLOBAL
, 0, DIREG_DEV
, KEY_READ
);
1474 if (key
!= INVALID_HANDLE_VALUE
) {
1475 size
= sizeof(guid_string_w
);
1476 s
= pRegQueryValueExW(key
, L
"DeviceInterfaceGUIDs", NULL
, ®_type
,
1477 (BYTE
*)guid_string_w
, &size
);
1479 if (s
== ERROR_SUCCESS
) {
1480 if (nb_guids
>= MAX_ENUM_GUIDS
) {
1481 // If this assert is ever reported, grow a GUID table dynamically
1482 usbi_err(ctx
, "program assertion failed: too many GUIDs");
1483 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW
);
1485 if_guid
= (GUID
*) calloc(1, sizeof(GUID
));
1486 pCLSIDFromString(guid_string_w
, if_guid
);
1487 guid
[nb_guids
++] = if_guid
;
1488 usbi_dbg("extra GUID: %s", guid_to_string(if_guid
));
1496 // Get the API type (after checking that the driver installation is OK)
1497 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_INSTALL_STATE
,
1498 ®_type
, (BYTE
*)&install_state
, 4, &size
))
1500 usbi_warn(ctx
, "could not detect installation state of driver for '%s': %s",
1501 dev_id_path
, windows_error_str(0));
1502 } else if (install_state
!= 0) {
1503 usbi_warn(ctx
, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1504 dev_id_path
, install_state
);
1507 get_api_type(ctx
, &dev_info
, &dev_info_data
, &api
, &sub_api
);
1511 // Find parent device (for the passes that need it)
1518 // Go through the ancestors until we see a face we recognize
1520 for (ancestor
= 1; parent_dev
== NULL
; ancestor
++) {
1521 session_id
= get_ancestor_session_id(dev_info_data
.DevInst
, ancestor
);
1522 if (session_id
== 0) {
1525 parent_dev
= usbi_get_device_by_session_id(ctx
, session_id
);
1527 if (parent_dev
== NULL
) {
1528 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path
);
1531 parent_priv
= _device_priv(parent_dev
);
1532 // virtual USB devices are also listed during GEN - don't process these yet
1533 if ( (pass
== GEN_PASS
) && (parent_priv
->apib
->id
!= USB_API_HUB
) ) {
1539 // Create new or match existing device, using the (hashed) device_id as session id
1540 if (pass
<= DEV_PASS
) { // For subsequent passes, we'll lookup the parent
1541 // These are the passes that create "new" devices
1542 session_id
= htab_hash(dev_id_path
);
1543 dev
= usbi_get_device_by_session_id(ctx
, session_id
);
1545 if (pass
== DEV_PASS
) {
1546 // This can occur if the OS only reports a newly plugged device after we started enum
1547 usbi_warn(ctx
, "'%s' was only detected in late pass (newly connected device?)"
1548 " - ignoring", dev_id_path
);
1551 usbi_dbg("allocating new device for session [%X]", session_id
);
1552 if ((dev
= usbi_alloc_device(ctx
, session_id
)) == NULL
) {
1553 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1555 windows_device_priv_init(dev
);
1556 // Keep track of devices that need unref
1557 unref_list
[unref_cur
++] = dev
;
1558 if (unref_cur
>= unref_size
) {
1560 unref_list
= usbi_reallocf(unref_list
, unref_size
*sizeof(libusb_device
*));
1561 if (unref_list
== NULL
) {
1562 usbi_err(ctx
, "could not realloc list for unref - aborting.");
1563 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1567 usbi_dbg("found existing device for session [%X] (%d.%d)",
1568 session_id
, dev
->bus_number
, dev
->device_address
);
1570 priv
= _device_priv(dev
);
1576 dev
->bus_number
= (uint8_t)(i
+ 1); // bus 0 is reserved for disconnected
1577 dev
->device_address
= 0;
1578 dev
->num_configurations
= 0;
1579 priv
->apib
= &usb_api_backend
[USB_API_HUB
];
1580 priv
->sub_api
= SUB_API_NOTSET
;
1581 priv
->depth
= UINT8_MAX
; // Overflow to 0 for HCD Hubs
1582 priv
->path
= dev_interface_path
; dev_interface_path
= NULL
;
1586 // If the device has already been setup, don't do it again
1587 if (priv
->path
!= NULL
)
1589 // Take care of API initialization
1590 priv
->path
= dev_interface_path
; dev_interface_path
= NULL
;
1591 priv
->apib
= &usb_api_backend
[api
];
1592 priv
->sub_api
= sub_api
;
1594 case USB_API_COMPOSITE
:
1598 priv
->hid
= calloc(1, sizeof(struct hid_device_priv
));
1599 if (priv
->hid
== NULL
) {
1600 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1602 priv
->hid
->nb_interfaces
= 0;
1605 // For other devices, the first interface is the same as the device
1606 priv
->usb_interface
[0].path
= (char*) calloc(safe_strlen(priv
->path
)+1, 1);
1607 if (priv
->usb_interface
[0].path
!= NULL
) {
1608 safe_strcpy(priv
->usb_interface
[0].path
, safe_strlen(priv
->path
)+1, priv
->path
);
1610 usbi_warn(ctx
, "could not duplicate interface path '%s'", priv
->path
);
1612 // The following is needed if we want API calls to work for both simple
1613 // and composite devices.
1614 for(j
=0; j
<USB_MAXINTERFACES
; j
++) {
1615 priv
->usb_interface
[j
].apib
= &usb_api_backend
[api
];
1621 r
= init_device(dev
, parent_dev
, (uint8_t)port_nr
, dev_id_path
, dev_info_data
.DevInst
);
1622 if (r
== LIBUSB_SUCCESS
) {
1623 // Append device to the list of discovered devices
1624 discdevs
= discovered_devs_append(*_discdevs
, dev
);
1626 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1628 *_discdevs
= discdevs
;
1629 } else if (r
== LIBUSB_ERROR_NO_DEVICE
) {
1630 // This can occur if the device was disconnected but Windows hasn't
1631 // refreshed its enumeration yet - in that case, we ignore the device
1635 default: // HID_PASS and later
1636 if (parent_priv
->apib
->id
== USB_API_HID
) {
1637 usbi_dbg("setting HID interface for [%lX]:", parent_dev
->session_data
);
1638 r
= set_hid_interface(ctx
, parent_dev
, dev_interface_path
);
1639 if (r
!= LIBUSB_SUCCESS
) LOOP_BREAK(r
);
1640 dev_interface_path
= NULL
;
1641 } else if (parent_priv
->apib
->id
== USB_API_COMPOSITE
) {
1642 usbi_dbg("setting composite interface for [%lX]:", parent_dev
->session_data
);
1643 switch (set_composite_interface(ctx
, parent_dev
, dev_interface_path
, dev_id_path
, api
, sub_api
)) {
1644 case LIBUSB_SUCCESS
:
1645 dev_interface_path
= NULL
;
1647 case LIBUSB_ERROR_ACCESS
:
1648 // interface has already been set => make sure dev_interface_path is freed then
1660 // Free any additional GUIDs
1661 for (pass
= HID_PASS
+1; pass
< nb_guids
; pass
++) {
1662 safe_free(guid
[pass
]);
1665 // Unref newly allocated devs
1666 for (i
=0; i
<unref_cur
; i
++) {
1667 safe_unref_device(unref_list
[i
]);
1669 safe_free(unref_list
);
1675 * exit: libusbx backend deinitialization function
1677 static void windows_exit(void)
1681 char sem_name
[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1683 sprintf(sem_name
, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1684 semaphore
= CreateSemaphoreA(NULL
, 1, 1, sem_name
);
1685 if (semaphore
== NULL
) {
1689 // A successful wait brings our semaphore count to 0 (unsignaled)
1690 // => any concurent wait stalls until the semaphore release
1691 if (WaitForSingleObject(semaphore
, INFINITE
) != WAIT_OBJECT_0
) {
1692 CloseHandle(semaphore
);
1696 // Only works if exits and inits are balanced exactly
1697 if (--concurrent_usage
< 0) { // Last exit
1698 for (i
=0; i
<USB_API_MAX
; i
++) {
1699 usb_api_backend
[i
].exit(SUB_API_NOTSET
);
1704 SetEvent(timer_request
[1]); // actually the signal to quit the thread.
1705 if (WAIT_OBJECT_0
!= WaitForSingleObject(timer_thread
, INFINITE
)) {
1706 usbi_dbg("could not wait for timer thread to quit");
1707 TerminateThread(timer_thread
, 1);
1709 CloseHandle(timer_thread
);
1710 timer_thread
= NULL
;
1712 for (i
= 0; i
< 2; i
++) {
1713 if (timer_request
[i
]) {
1714 CloseHandle(timer_request
[i
]);
1715 timer_request
[i
] = NULL
;
1718 if (timer_response
) {
1719 CloseHandle(timer_response
);
1720 timer_response
= NULL
;
1723 CloseHandle(timer_mutex
);
1729 ReleaseSemaphore(semaphore
, 1, NULL
); // increase count back to 1
1730 CloseHandle(semaphore
);
1733 static int windows_get_device_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, int *host_endian
)
1735 struct windows_device_priv
*priv
= _device_priv(dev
);
1737 memcpy(buffer
, &(priv
->dev_descriptor
), DEVICE_DESC_LENGTH
);
1740 return LIBUSB_SUCCESS
;
1743 static int windows_get_config_descriptor(struct libusb_device
*dev
, uint8_t config_index
, unsigned char *buffer
, size_t len
, int *host_endian
)
1745 struct windows_device_priv
*priv
= _device_priv(dev
);
1746 PUSB_CONFIGURATION_DESCRIPTOR config_header
;
1749 // config index is zero based
1750 if (config_index
>= dev
->num_configurations
)
1751 return LIBUSB_ERROR_INVALID_PARAM
;
1753 if ((priv
->config_descriptor
== NULL
) || (priv
->config_descriptor
[config_index
] == NULL
))
1754 return LIBUSB_ERROR_NOT_FOUND
;
1756 config_header
= (PUSB_CONFIGURATION_DESCRIPTOR
)priv
->config_descriptor
[config_index
];
1758 size
= min(config_header
->wTotalLength
, len
);
1759 memcpy(buffer
, priv
->config_descriptor
[config_index
], size
);
1761 return LIBUSB_SUCCESS
;
1765 * return the cached copy of the active config descriptor
1767 static int windows_get_active_config_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, size_t len
, int *host_endian
)
1769 struct windows_device_priv
*priv
= _device_priv(dev
);
1771 if (priv
->active_config
== 0)
1772 return LIBUSB_ERROR_NOT_FOUND
;
1774 // config index is zero based
1775 return windows_get_config_descriptor(dev
, (uint8_t)(priv
->active_config
-1), buffer
, len
, host_endian
);
1778 static int windows_open(struct libusb_device_handle
*dev_handle
)
1780 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1781 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
1783 if (priv
->apib
== NULL
) {
1784 usbi_err(ctx
, "program assertion failed - device is not initialized");
1785 return LIBUSB_ERROR_NO_DEVICE
;
1788 return priv
->apib
->open(SUB_API_NOTSET
, dev_handle
);
1791 static void windows_close(struct libusb_device_handle
*dev_handle
)
1793 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1795 priv
->apib
->close(SUB_API_NOTSET
, dev_handle
);
1798 static int windows_get_configuration(struct libusb_device_handle
*dev_handle
, int *config
)
1800 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1802 if (priv
->active_config
== 0) {
1804 return LIBUSB_ERROR_NOT_FOUND
;
1807 *config
= priv
->active_config
;
1808 return LIBUSB_SUCCESS
;
1812 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1813 * does not currently expose a service that allows higher-level drivers to set
1814 * the configuration."
1816 static int windows_set_configuration(struct libusb_device_handle
*dev_handle
, int config
)
1818 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1819 int r
= LIBUSB_SUCCESS
;
1821 if (config
>= USB_MAXCONFIG
)
1822 return LIBUSB_ERROR_INVALID_PARAM
;
1824 r
= libusb_control_transfer(dev_handle
, LIBUSB_ENDPOINT_OUT
|
1825 LIBUSB_REQUEST_TYPE_STANDARD
| LIBUSB_RECIPIENT_DEVICE
,
1826 LIBUSB_REQUEST_SET_CONFIGURATION
, (uint16_t)config
,
1829 if (r
== LIBUSB_SUCCESS
) {
1830 priv
->active_config
= (uint8_t)config
;
1835 static int windows_claim_interface(struct libusb_device_handle
*dev_handle
, int iface
)
1837 int r
= LIBUSB_SUCCESS
;
1838 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1840 if (iface
>= USB_MAXINTERFACES
)
1841 return LIBUSB_ERROR_INVALID_PARAM
;
1843 safe_free(priv
->usb_interface
[iface
].endpoint
);
1844 priv
->usb_interface
[iface
].nb_endpoints
= 0;
1846 r
= priv
->apib
->claim_interface(SUB_API_NOTSET
, dev_handle
, iface
);
1848 if (r
== LIBUSB_SUCCESS
) {
1849 r
= windows_assign_endpoints(dev_handle
, iface
, 0);
1855 static int windows_set_interface_altsetting(struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
1857 int r
= LIBUSB_SUCCESS
;
1858 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1860 safe_free(priv
->usb_interface
[iface
].endpoint
);
1861 priv
->usb_interface
[iface
].nb_endpoints
= 0;
1863 r
= priv
->apib
->set_interface_altsetting(SUB_API_NOTSET
, dev_handle
, iface
, altsetting
);
1865 if (r
== LIBUSB_SUCCESS
) {
1866 r
= windows_assign_endpoints(dev_handle
, iface
, altsetting
);
1872 static int windows_release_interface(struct libusb_device_handle
*dev_handle
, int iface
)
1874 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1876 return priv
->apib
->release_interface(SUB_API_NOTSET
, dev_handle
, iface
);
1879 static int windows_clear_halt(struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
1881 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1882 return priv
->apib
->clear_halt(SUB_API_NOTSET
, dev_handle
, endpoint
);
1885 static int windows_reset_device(struct libusb_device_handle
*dev_handle
)
1887 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1888 return priv
->apib
->reset_device(SUB_API_NOTSET
, dev_handle
);
1891 // The 3 functions below are unlikely to ever get supported on Windows
1892 static int windows_kernel_driver_active(struct libusb_device_handle
*dev_handle
, int iface
)
1894 return LIBUSB_ERROR_NOT_SUPPORTED
;
1897 static int windows_attach_kernel_driver(struct libusb_device_handle
*dev_handle
, int iface
)
1899 return LIBUSB_ERROR_NOT_SUPPORTED
;
1902 static int windows_detach_kernel_driver(struct libusb_device_handle
*dev_handle
, int iface
)
1904 return LIBUSB_ERROR_NOT_SUPPORTED
;
1907 static void windows_destroy_device(struct libusb_device
*dev
)
1909 windows_device_priv_release(dev
);
1912 static void windows_clear_transfer_priv(struct usbi_transfer
*itransfer
)
1914 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1916 usbi_free_fd(&transfer_priv
->pollable_fd
);
1917 safe_free(transfer_priv
->hid_buffer
);
1918 // When auto claim is in use, attempt to release the auto-claimed interface
1919 auto_release(itransfer
);
1922 static int submit_bulk_transfer(struct usbi_transfer
*itransfer
)
1924 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1925 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1926 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1927 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1930 r
= priv
->apib
->submit_bulk_transfer(SUB_API_NOTSET
, itransfer
);
1931 if (r
!= LIBUSB_SUCCESS
) {
1935 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
,
1936 (short)(IS_XFERIN(transfer
) ? POLLIN
: POLLOUT
));
1938 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1939 return LIBUSB_SUCCESS
;
1942 static int submit_iso_transfer(struct usbi_transfer
*itransfer
)
1944 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1945 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1946 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1947 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1950 r
= priv
->apib
->submit_iso_transfer(SUB_API_NOTSET
, itransfer
);
1951 if (r
!= LIBUSB_SUCCESS
) {
1955 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
,
1956 (short)(IS_XFERIN(transfer
) ? POLLIN
: POLLOUT
));
1958 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1959 return LIBUSB_SUCCESS
;
1962 static int submit_control_transfer(struct usbi_transfer
*itransfer
)
1964 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1965 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1966 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1967 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1970 r
= priv
->apib
->submit_control_transfer(SUB_API_NOTSET
, itransfer
);
1971 if (r
!= LIBUSB_SUCCESS
) {
1975 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
, POLLIN
);
1977 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1978 return LIBUSB_SUCCESS
;
1982 static int windows_submit_transfer(struct usbi_transfer
*itransfer
)
1984 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1986 switch (transfer
->type
) {
1987 case LIBUSB_TRANSFER_TYPE_CONTROL
:
1988 return submit_control_transfer(itransfer
);
1989 case LIBUSB_TRANSFER_TYPE_BULK
:
1990 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
1991 if (IS_XFEROUT(transfer
) &&
1992 transfer
->flags
& LIBUSB_TRANSFER_ADD_ZERO_PACKET
)
1993 return LIBUSB_ERROR_NOT_SUPPORTED
;
1994 return submit_bulk_transfer(itransfer
);
1995 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
1996 return submit_iso_transfer(itransfer
);
1998 usbi_err(TRANSFER_CTX(transfer
), "unknown endpoint type %d", transfer
->type
);
1999 return LIBUSB_ERROR_INVALID_PARAM
;
2003 static int windows_abort_control(struct usbi_transfer
*itransfer
)
2005 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2006 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2008 return priv
->apib
->abort_control(SUB_API_NOTSET
, itransfer
);
2011 static int windows_abort_transfers(struct usbi_transfer
*itransfer
)
2013 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2014 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2016 return priv
->apib
->abort_transfers(SUB_API_NOTSET
, itransfer
);
2019 static int windows_cancel_transfer(struct usbi_transfer
*itransfer
)
2021 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2023 switch (transfer
->type
) {
2024 case LIBUSB_TRANSFER_TYPE_CONTROL
:
2025 return windows_abort_control(itransfer
);
2026 case LIBUSB_TRANSFER_TYPE_BULK
:
2027 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
2028 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
2029 return windows_abort_transfers(itransfer
);
2031 usbi_err(ITRANSFER_CTX(itransfer
), "unknown endpoint type %d", transfer
->type
);
2032 return LIBUSB_ERROR_INVALID_PARAM
;
2036 static void windows_transfer_callback(struct usbi_transfer
*itransfer
, uint32_t io_result
, uint32_t io_size
)
2038 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2039 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2040 int status
, istatus
;
2042 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result
, io_size
);
2046 status
= priv
->apib
->copy_transfer_data(SUB_API_NOTSET
, itransfer
, io_size
);
2048 case ERROR_GEN_FAILURE
:
2049 usbi_dbg("detected endpoint stall");
2050 status
= LIBUSB_TRANSFER_STALL
;
2052 case ERROR_SEM_TIMEOUT
:
2053 usbi_dbg("detected semaphore timeout");
2054 status
= LIBUSB_TRANSFER_TIMED_OUT
;
2056 case ERROR_OPERATION_ABORTED
:
2057 istatus
= priv
->apib
->copy_transfer_data(SUB_API_NOTSET
, itransfer
, io_size
);
2058 if (istatus
!= LIBUSB_TRANSFER_COMPLETED
) {
2059 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus
);
2061 if (itransfer
->flags
& USBI_TRANSFER_TIMED_OUT
) {
2062 usbi_dbg("detected timeout");
2063 status
= LIBUSB_TRANSFER_TIMED_OUT
;
2065 usbi_dbg("detected operation aborted");
2066 status
= LIBUSB_TRANSFER_CANCELLED
;
2070 usbi_err(ITRANSFER_CTX(itransfer
), "detected I/O error %d: %s", io_result
, windows_error_str(0));
2071 status
= LIBUSB_TRANSFER_ERROR
;
2074 windows_clear_transfer_priv(itransfer
); // Cancel polling
2075 usbi_handle_transfer_completion(itransfer
, (enum libusb_transfer_status
)status
);
2078 static void windows_handle_callback (struct usbi_transfer
*itransfer
, uint32_t io_result
, uint32_t io_size
)
2080 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2082 switch (transfer
->type
) {
2083 case LIBUSB_TRANSFER_TYPE_CONTROL
:
2084 case LIBUSB_TRANSFER_TYPE_BULK
:
2085 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
2086 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
2087 windows_transfer_callback (itransfer
, io_result
, io_size
);
2090 usbi_err(ITRANSFER_CTX(itransfer
), "unknown endpoint type %d", transfer
->type
);
2094 static int windows_handle_events(struct libusb_context
*ctx
, struct pollfd
*fds
, POLL_NFDS_TYPE nfds
, int num_ready
)
2096 struct windows_transfer_priv
* transfer_priv
= NULL
;
2097 POLL_NFDS_TYPE i
= 0;
2099 struct usbi_transfer
*transfer
;
2100 DWORD io_size
, io_result
;
2102 usbi_mutex_lock(&ctx
->open_devs_lock
);
2103 for (i
= 0; i
< nfds
&& num_ready
> 0; i
++) {
2105 usbi_dbg("checking fd %d with revents = %04x", fds
[i
].fd
, fds
[i
].revents
);
2107 if (!fds
[i
].revents
) {
2113 // Because a Windows OVERLAPPED is used for poll emulation,
2114 // a pollable fd is created and stored with each transfer
2115 usbi_mutex_lock(&ctx
->flying_transfers_lock
);
2116 list_for_each_entry(transfer
, &ctx
->flying_transfers
, list
, struct usbi_transfer
) {
2117 transfer_priv
= usbi_transfer_get_os_priv(transfer
);
2118 if (transfer_priv
->pollable_fd
.fd
== fds
[i
].fd
) {
2123 usbi_mutex_unlock(&ctx
->flying_transfers_lock
);
2126 // Handle async requests that completed synchronously first
2127 if (HasOverlappedIoCompletedSync(transfer_priv
->pollable_fd
.overlapped
)) {
2128 io_result
= NO_ERROR
;
2129 io_size
= (DWORD
)transfer_priv
->pollable_fd
.overlapped
->InternalHigh
;
2130 // Regular async overlapped
2131 } else if (GetOverlappedResult(transfer_priv
->pollable_fd
.handle
,
2132 transfer_priv
->pollable_fd
.overlapped
, &io_size
, false)) {
2133 io_result
= NO_ERROR
;
2135 io_result
= GetLastError();
2137 usbi_remove_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
);
2138 // let handle_callback free the event using the transfer wfd
2139 // If you don't use the transfer wfd, you run a risk of trying to free a
2140 // newly allocated wfd that took the place of the one from the transfer.
2141 windows_handle_callback(transfer
, io_result
, io_size
);
2143 usbi_err(ctx
, "could not find a matching transfer for fd %x", fds
[i
]);
2144 return LIBUSB_ERROR_NOT_FOUND
;
2148 usbi_mutex_unlock(&ctx
->open_devs_lock
);
2149 return LIBUSB_SUCCESS
;
2153 * Monotonic and real time functions
2155 unsigned __stdcall
windows_clock_gettime_threaded(void* param
)
2157 LARGE_INTEGER hires_counter
, li_frequency
;
2161 // Init - find out if we have access to a monotonic (hires) timer
2162 if (!QueryPerformanceFrequency(&li_frequency
)) {
2163 usbi_dbg("no hires timer available on this platform");
2164 hires_frequency
= 0;
2165 hires_ticks_to_ps
= UINT64_C(0);
2167 hires_frequency
= li_frequency
.QuadPart
;
2168 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2169 // to picoseconds to compute the tv_nsecs part in clock_gettime
2170 hires_ticks_to_ps
= UINT64_C(1000000000000) / hires_frequency
;
2171 usbi_dbg("hires timer available (Frequency: %"PRIu64
" Hz)", hires_frequency
);
2174 // Main loop - wait for requests
2176 timer_index
= WaitForMultipleObjects(2, timer_request
, FALSE
, INFINITE
) - WAIT_OBJECT_0
;
2177 if ( (timer_index
!= 0) && (timer_index
!= 1) ) {
2178 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2181 if (request_count
[timer_index
] == 0) {
2182 // Request already handled
2183 ResetEvent(timer_request
[timer_index
]);
2184 // There's still a possiblity that a thread sends a request between the
2185 // time we test request_count[] == 0 and we reset the event, in which case
2186 // the request would be ignored. The simple solution to that is to test
2187 // request_count again and process requests if non zero.
2188 if (request_count
[timer_index
] == 0)
2191 switch (timer_index
) {
2193 WaitForSingleObject(timer_mutex
, INFINITE
);
2194 // Requests to this thread are for hires always
2195 if (QueryPerformanceCounter(&hires_counter
) != 0) {
2196 timer_tp
.tv_sec
= (long)(hires_counter
.QuadPart
/ hires_frequency
);
2197 timer_tp
.tv_nsec
= (long)(((hires_counter
.QuadPart
% hires_frequency
)/1000) * hires_ticks_to_ps
);
2199 // Fallback to real-time if we can't get monotonic value
2200 // Note that real-time clock does not wait on the mutex or this thread.
2201 windows_clock_gettime(USBI_CLOCK_REALTIME
, &timer_tp
);
2203 ReleaseMutex(timer_mutex
);
2205 nb_responses
= InterlockedExchange((LONG
*)&request_count
[0], 0);
2207 && (ReleaseSemaphore(timer_response
, nb_responses
, NULL
) == 0) ) {
2208 usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0));
2211 case 1: // time to quit
2212 usbi_dbg("timer thread quitting");
2218 static int windows_clock_gettime(int clk_id
, struct timespec
*tp
)
2221 ULARGE_INTEGER rtime
;
2224 case USBI_CLOCK_MONOTONIC
:
2225 if (hires_frequency
!= 0) {
2227 InterlockedIncrement((LONG
*)&request_count
[0]);
2228 SetEvent(timer_request
[0]);
2229 r
= WaitForSingleObject(timer_response
, TIMER_REQUEST_RETRY_MS
);
2232 WaitForSingleObject(timer_mutex
, INFINITE
);
2234 ReleaseMutex(timer_mutex
);
2235 return LIBUSB_SUCCESS
;
2237 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2238 break; // Retry until successful
2240 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2241 return LIBUSB_ERROR_OTHER
;
2245 // Fall through and return real-time if monotonic was not detected @ timer init
2246 case USBI_CLOCK_REALTIME
:
2247 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2248 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2249 // Note however that our resolution is bounded by the Windows system time
2250 // functions and is at best of the order of 1 ms (or, usually, worse)
2251 GetSystemTimeAsFileTime(&filetime
);
2252 rtime
.LowPart
= filetime
.dwLowDateTime
;
2253 rtime
.HighPart
= filetime
.dwHighDateTime
;
2254 rtime
.QuadPart
-= epoch_time
;
2255 tp
->tv_sec
= (long)(rtime
.QuadPart
/ 10000000);
2256 tp
->tv_nsec
= (long)((rtime
.QuadPart
% 10000000)*100);
2257 return LIBUSB_SUCCESS
;
2259 return LIBUSB_ERROR_INVALID_PARAM
;
2264 // NB: MSVC6 does not support named initializers.
2265 const struct usbi_os_backend windows_backend
= {
2267 USBI_CAP_HAS_HID_ACCESS
,
2271 windows_get_device_list
,
2275 windows_get_device_descriptor
,
2276 windows_get_active_config_descriptor
,
2277 windows_get_config_descriptor
,
2279 windows_get_configuration
,
2280 windows_set_configuration
,
2281 windows_claim_interface
,
2282 windows_release_interface
,
2284 windows_set_interface_altsetting
,
2286 windows_reset_device
,
2288 windows_kernel_driver_active
,
2289 windows_detach_kernel_driver
,
2290 windows_attach_kernel_driver
,
2292 windows_destroy_device
,
2294 windows_submit_transfer
,
2295 windows_cancel_transfer
,
2296 windows_clear_transfer_priv
,
2298 windows_handle_events
,
2300 windows_clock_gettime
,
2301 #if defined(USBI_TIMERFD_AVAILABLE)
2304 sizeof(struct windows_device_priv
),
2305 sizeof(struct windows_device_handle_priv
),
2306 sizeof(struct windows_transfer_priv
),
2314 static int unsupported_init(int sub_api
, struct libusb_context
*ctx
) {
2315 return LIBUSB_SUCCESS
;
2317 static int unsupported_exit(int sub_api
) {
2318 return LIBUSB_SUCCESS
;
2320 static int unsupported_open(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2321 PRINT_UNSUPPORTED_API(open
);
2323 static void unsupported_close(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2324 usbi_dbg("unsupported API call for 'close'");
2326 static int unsupported_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2327 PRINT_UNSUPPORTED_API(configure_endpoints
);
2329 static int unsupported_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2330 PRINT_UNSUPPORTED_API(claim_interface
);
2332 static int unsupported_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
) {
2333 PRINT_UNSUPPORTED_API(set_interface_altsetting
);
2335 static int unsupported_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2336 PRINT_UNSUPPORTED_API(release_interface
);
2338 static int unsupported_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
) {
2339 PRINT_UNSUPPORTED_API(clear_halt
);
2341 static int unsupported_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2342 PRINT_UNSUPPORTED_API(reset_device
);
2344 static int unsupported_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2345 PRINT_UNSUPPORTED_API(submit_bulk_transfer
);
2347 static int unsupported_submit_iso_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2348 PRINT_UNSUPPORTED_API(submit_iso_transfer
);
2350 static int unsupported_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2351 PRINT_UNSUPPORTED_API(submit_control_transfer
);
2353 static int unsupported_abort_control(int sub_api
, struct usbi_transfer
*itransfer
) {
2354 PRINT_UNSUPPORTED_API(abort_control
);
2356 static int unsupported_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
) {
2357 PRINT_UNSUPPORTED_API(abort_transfers
);
2359 static int unsupported_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
) {
2360 PRINT_UNSUPPORTED_API(copy_transfer_data
);
2362 static int common_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2363 return LIBUSB_SUCCESS
;
2365 // These names must be uppercase
2366 const char* hub_driver_names
[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2367 const char* composite_driver_names
[] = {"USBCCGP"};
2368 const char* winusbx_driver_names
[] = WINUSBX_DRV_NAMES
;
2369 const char* hid_driver_names
[] = {"HIDUSB", "MOUHID", "KBDHID"};
2370 const struct windows_usb_api_backend usb_api_backend
[USB_API_MAX
] = {
2372 USB_API_UNSUPPORTED
,
2380 unsupported_configure_endpoints
,
2381 unsupported_claim_interface
,
2382 unsupported_set_interface_altsetting
,
2383 unsupported_release_interface
,
2384 unsupported_clear_halt
,
2385 unsupported_reset_device
,
2386 unsupported_submit_bulk_transfer
,
2387 unsupported_submit_iso_transfer
,
2388 unsupported_submit_control_transfer
,
2389 unsupported_abort_control
,
2390 unsupported_abort_transfers
,
2391 unsupported_copy_transfer_data
,
2396 ARRAYSIZE(hub_driver_names
),
2401 unsupported_configure_endpoints
,
2402 unsupported_claim_interface
,
2403 unsupported_set_interface_altsetting
,
2404 unsupported_release_interface
,
2405 unsupported_clear_halt
,
2406 unsupported_reset_device
,
2407 unsupported_submit_bulk_transfer
,
2408 unsupported_submit_iso_transfer
,
2409 unsupported_submit_control_transfer
,
2410 unsupported_abort_control
,
2411 unsupported_abort_transfers
,
2412 unsupported_copy_transfer_data
,
2416 composite_driver_names
,
2417 ARRAYSIZE(composite_driver_names
),
2422 common_configure_endpoints
,
2423 composite_claim_interface
,
2424 composite_set_interface_altsetting
,
2425 composite_release_interface
,
2426 composite_clear_halt
,
2427 composite_reset_device
,
2428 composite_submit_bulk_transfer
,
2429 composite_submit_iso_transfer
,
2430 composite_submit_control_transfer
,
2431 composite_abort_control
,
2432 composite_abort_transfers
,
2433 composite_copy_transfer_data
,
2437 winusbx_driver_names
,
2438 ARRAYSIZE(winusbx_driver_names
),
2443 winusbx_configure_endpoints
,
2444 winusbx_claim_interface
,
2445 winusbx_set_interface_altsetting
,
2446 winusbx_release_interface
,
2448 winusbx_reset_device
,
2449 winusbx_submit_bulk_transfer
,
2450 unsupported_submit_iso_transfer
,
2451 winusbx_submit_control_transfer
,
2452 winusbx_abort_control
,
2453 winusbx_abort_transfers
,
2454 winusbx_copy_transfer_data
,
2459 ARRAYSIZE(hid_driver_names
),
2464 common_configure_endpoints
,
2465 hid_claim_interface
,
2466 hid_set_interface_altsetting
,
2467 hid_release_interface
,
2470 hid_submit_bulk_transfer
,
2471 unsupported_submit_iso_transfer
,
2472 hid_submit_control_transfer
,
2473 hid_abort_transfers
,
2474 hid_abort_transfers
,
2475 hid_copy_transfer_data
,
2481 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2483 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2484 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2486 static int winusbx_init(int sub_api
, struct libusb_context
*ctx
)
2489 bool native_winusb
= false;
2491 KLIB_VERSION LibK_Version
;
2492 LibK_GetProcAddress_t pLibK_GetProcAddress
= NULL
;
2493 LibK_GetVersion_t pLibK_GetVersion
= NULL
;
2495 h
= GetModuleHandleA("libusbK");
2497 h
= LoadLibraryA("libusbK");
2500 usbi_info(ctx
, "libusbK DLL is not available, will use native WinUSB");
2501 h
= GetModuleHandleA("WinUSB");
2503 h
= LoadLibraryA("WinUSB");
2505 usbi_warn(ctx
, "WinUSB DLL is not available either,\n"
2506 "you will not be able to access devices outside of enumeration");
2507 return LIBUSB_ERROR_NOT_FOUND
;
2510 usbi_dbg("using libusbK DLL for universal access");
2511 pLibK_GetVersion
= (LibK_GetVersion_t
) GetProcAddress(h
, "LibK_GetVersion");
2512 if (pLibK_GetVersion
!= NULL
) {
2513 pLibK_GetVersion(&LibK_Version
);
2514 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version
.Major
, LibK_Version
.Minor
,
2515 LibK_Version
.Micro
, LibK_Version
.Nano
);
2517 pLibK_GetProcAddress
= (LibK_GetProcAddress_t
) GetProcAddress(h
, "LibK_GetProcAddress");
2518 if (pLibK_GetProcAddress
== NULL
) {
2519 usbi_err(ctx
, "LibK_GetProcAddress() not found in libusbK DLL");
2520 return LIBUSB_ERROR_NOT_FOUND
;
2523 native_winusb
= (pLibK_GetProcAddress
== NULL
);
2524 for (i
=SUB_API_LIBUSBK
; i
<SUB_API_MAX
; i
++) {
2525 WinUSBX_Set(AbortPipe
);
2526 WinUSBX_Set(ControlTransfer
);
2527 WinUSBX_Set(FlushPipe
);
2529 WinUSBX_Set(GetAssociatedInterface
);
2530 WinUSBX_Set(GetCurrentAlternateSetting
);
2531 WinUSBX_Set(GetDescriptor
);
2532 WinUSBX_Set(GetOverlappedResult
);
2533 WinUSBX_Set(GetPipePolicy
);
2534 WinUSBX_Set(GetPowerPolicy
);
2535 WinUSBX_Set(Initialize
);
2536 WinUSBX_Set(QueryDeviceInformation
);
2537 WinUSBX_Set(QueryInterfaceSettings
);
2538 WinUSBX_Set(QueryPipe
);
2539 WinUSBX_Set(ReadPipe
);
2540 WinUSBX_Set(ResetPipe
);
2541 WinUSBX_Set(SetCurrentAlternateSetting
);
2542 WinUSBX_Set(SetPipePolicy
);
2543 WinUSBX_Set(SetPowerPolicy
);
2544 WinUSBX_Set(WritePipe
);
2545 if (!native_winusb
) {
2546 WinUSBX_Set(ResetDevice
);
2548 if (WinUSBX
[i
].Initialize
!= NULL
) {
2549 WinUSBX
[i
].initialized
= true;
2550 usbi_dbg("initalized sub API %s", sub_api_name
[i
]);
2552 usbi_warn(ctx
, "Failed to initalize sub API %s", sub_api_name
[i
]);
2553 WinUSBX
[i
].initialized
= false;
2556 return LIBUSB_SUCCESS
;
2559 static int winusbx_exit(int sub_api
)
2561 return LIBUSB_SUCCESS
;
2564 // NB: open and close must ensure that they only handle interface of
2565 // the right API type, as these functions can be called wholesale from
2566 // composite_open(), with interfaces belonging to different APIs
2567 static int winusbx_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
2569 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2570 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2571 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2576 CHECK_WINUSBX_AVAILABLE(sub_api
);
2578 // WinUSB requires a seperate handle for each interface
2579 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
2580 if ( (priv
->usb_interface
[i
].path
!= NULL
)
2581 && (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
) ) {
2582 file_handle
= CreateFileA(priv
->usb_interface
[i
].path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
2583 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2584 if (file_handle
== INVALID_HANDLE_VALUE
) {
2585 usbi_err(ctx
, "could not open device %s (interface %d): %s", priv
->usb_interface
[i
].path
, i
, windows_error_str(0));
2586 switch(GetLastError()) {
2587 case ERROR_FILE_NOT_FOUND
: // The device was disconnected
2588 return LIBUSB_ERROR_NO_DEVICE
;
2589 case ERROR_ACCESS_DENIED
:
2590 return LIBUSB_ERROR_ACCESS
;
2592 return LIBUSB_ERROR_IO
;
2595 handle_priv
->interface_handle
[i
].dev_handle
= file_handle
;
2599 return LIBUSB_SUCCESS
;
2602 static void winusbx_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
2604 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2605 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2609 if (sub_api
== SUB_API_NOTSET
)
2610 sub_api
= priv
->sub_api
;
2611 if (!WinUSBX
[sub_api
].initialized
)
2614 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
2615 if (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
) {
2616 file_handle
= handle_priv
->interface_handle
[i
].dev_handle
;
2617 if ( (file_handle
!= 0) && (file_handle
!= INVALID_HANDLE_VALUE
)) {
2618 CloseHandle(file_handle
);
2624 static int winusbx_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2626 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2627 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2628 HANDLE winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2631 uint8_t endpoint_address
;
2634 CHECK_WINUSBX_AVAILABLE(sub_api
);
2636 // With handle and enpoints set (in parent), we can setup the default pipe properties
2637 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2638 for (i
=-1; i
<priv
->usb_interface
[iface
].nb_endpoints
; i
++) {
2639 endpoint_address
=(i
==-1)?0:priv
->usb_interface
[iface
].endpoint
[i
];
2640 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2641 PIPE_TRANSFER_TIMEOUT
, sizeof(ULONG
), &timeout
)) {
2642 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address
);
2644 if ((i
== -1) || (sub_api
== SUB_API_LIBUSB0
)) {
2645 continue; // Other policies don't apply to control endpoint or libusb0
2648 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2649 SHORT_PACKET_TERMINATE
, sizeof(UCHAR
), &policy
)) {
2650 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address
);
2652 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2653 IGNORE_SHORT_PACKETS
, sizeof(UCHAR
), &policy
)) {
2654 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address
);
2657 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2658 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2659 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2660 ALLOW_PARTIAL_READS
, sizeof(UCHAR
), &policy
)) {
2661 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address
);
2663 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2664 AUTO_CLEAR_STALL
, sizeof(UCHAR
), &policy
)) {
2665 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address
);
2669 return LIBUSB_SUCCESS
;
2672 static int winusbx_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2674 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2675 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2676 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2677 bool is_using_usbccgp
= (priv
->apib
->id
== USB_API_COMPOSITE
);
2678 HANDLE file_handle
, winusb_handle
;
2681 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*dev_interface_details
= NULL
;
2682 HDEVINFO dev_info
= INVALID_HANDLE_VALUE
;
2683 SP_DEVINFO_DATA dev_info_data
;
2684 char* dev_path_no_guid
= NULL
;
2685 char filter_path
[] = "\\\\.\\libusb0-0000";
2686 bool found_filter
= false;
2688 CHECK_WINUSBX_AVAILABLE(sub_api
);
2690 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2691 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2692 if ((is_using_usbccgp
) || (iface
== 0)) {
2693 // composite device (independent interfaces) or interface 0
2694 file_handle
= handle_priv
->interface_handle
[iface
].dev_handle
;
2695 if ((file_handle
== 0) || (file_handle
== INVALID_HANDLE_VALUE
)) {
2696 return LIBUSB_ERROR_NOT_FOUND
;
2699 if (!WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2700 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2701 err
= GetLastError();
2703 case ERROR_BAD_COMMAND
:
2704 // The device was disconnected
2705 usbi_err(ctx
, "could not access interface %d: %s", iface
, windows_error_str(0));
2706 return LIBUSB_ERROR_NO_DEVICE
;
2708 // it may be that we're using the libusb0 filter driver.
2709 // TODO: can we move this whole business into the K/0 DLL?
2710 for (i
= 0; ; i
++) {
2711 safe_free(dev_interface_details
);
2712 safe_free(dev_path_no_guid
);
2713 dev_interface_details
= get_interface_details_filter(ctx
, &dev_info
, &dev_info_data
, &GUID_DEVINTERFACE_LIBUSB0_FILTER
, i
, filter_path
);
2714 if ((found_filter
) || (dev_interface_details
== NULL
)) {
2718 dev_path_no_guid
= sanitize_path(strtok(dev_interface_details
->DevicePath
, "{"));
2719 if (safe_strncmp(dev_path_no_guid
, priv
->usb_interface
[iface
].path
, safe_strlen(dev_path_no_guid
)) == 0) {
2720 file_handle
= CreateFileA(filter_path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
2721 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2722 if (file_handle
== INVALID_HANDLE_VALUE
) {
2723 usbi_err(ctx
, "could not open device %s: %s", filter_path
, windows_error_str(0));
2725 WinUSBX
[sub_api
].Free(winusb_handle
);
2726 if (!WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2729 found_filter
= true;
2734 if (!found_filter
) {
2735 usbi_err(ctx
, "could not access interface %d: %s", iface
, windows_error_str(err
));
2736 return LIBUSB_ERROR_ACCESS
;
2740 handle_priv
->interface_handle
[iface
].api_handle
= winusb_handle
;
2742 // For all other interfaces, use GetAssociatedInterface()
2743 winusb_handle
= handle_priv
->interface_handle
[0].api_handle
;
2744 // It is a requirement for multiple interface devices on Windows that, to you
2745 // must first claim the first interface before you claim the others
2746 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2747 file_handle
= handle_priv
->interface_handle
[0].dev_handle
;
2748 if (WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2749 handle_priv
->interface_handle
[0].api_handle
= winusb_handle
;
2750 usbi_warn(ctx
, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface
);
2752 usbi_warn(ctx
, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface
, windows_error_str(0));
2753 return LIBUSB_ERROR_ACCESS
;
2756 if (!WinUSBX
[sub_api
].GetAssociatedInterface(winusb_handle
, (UCHAR
)(iface
-1),
2757 &handle_priv
->interface_handle
[iface
].api_handle
)) {
2758 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2759 switch(GetLastError()) {
2760 case ERROR_NO_MORE_ITEMS
: // invalid iface
2761 return LIBUSB_ERROR_NOT_FOUND
;
2762 case ERROR_BAD_COMMAND
: // The device was disconnected
2763 return LIBUSB_ERROR_NO_DEVICE
;
2764 case ERROR_ALREADY_EXISTS
: // already claimed
2765 return LIBUSB_ERROR_BUSY
;
2767 usbi_err(ctx
, "could not claim interface %d: %s", iface
, windows_error_str(0));
2768 return LIBUSB_ERROR_ACCESS
;
2772 usbi_dbg("claimed interface %d", iface
);
2773 handle_priv
->active_interface
= iface
;
2775 return LIBUSB_SUCCESS
;
2778 static int winusbx_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2780 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2781 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2782 HANDLE winusb_handle
;
2784 CHECK_WINUSBX_AVAILABLE(sub_api
);
2786 winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2787 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2788 return LIBUSB_ERROR_NOT_FOUND
;
2791 WinUSBX
[sub_api
].Free(winusb_handle
);
2792 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2794 return LIBUSB_SUCCESS
;
2798 * Return the first valid interface (of the same API type), for control transfers
2800 static int get_valid_interface(struct libusb_device_handle
*dev_handle
, int api_id
)
2802 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2803 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2806 if ((api_id
< USB_API_WINUSBX
) || (api_id
> USB_API_HID
)) {
2807 usbi_dbg("unsupported API ID");
2811 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
2812 if ( (handle_priv
->interface_handle
[i
].dev_handle
!= 0)
2813 && (handle_priv
->interface_handle
[i
].dev_handle
!= INVALID_HANDLE_VALUE
)
2814 && (handle_priv
->interface_handle
[i
].api_handle
!= 0)
2815 && (handle_priv
->interface_handle
[i
].api_handle
!= INVALID_HANDLE_VALUE
)
2816 && (priv
->usb_interface
[i
].apib
->id
== api_id
) ) {
2824 * Lookup interface by endpoint address. -1 if not found
2826 static int interface_by_endpoint(struct windows_device_priv
*priv
,
2827 struct windows_device_handle_priv
*handle_priv
, uint8_t endpoint_address
)
2830 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
2831 if (handle_priv
->interface_handle
[i
].api_handle
== INVALID_HANDLE_VALUE
)
2833 if (handle_priv
->interface_handle
[i
].api_handle
== 0)
2835 if (priv
->usb_interface
[i
].endpoint
== NULL
)
2837 for (j
=0; j
<priv
->usb_interface
[i
].nb_endpoints
; j
++) {
2838 if (priv
->usb_interface
[i
].endpoint
[j
] == endpoint_address
) {
2846 static int winusbx_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
2848 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2849 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
2850 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2851 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
2852 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(
2853 transfer
->dev_handle
);
2854 WINUSB_SETUP_PACKET
*setup
= (WINUSB_SETUP_PACKET
*) transfer
->buffer
;
2856 HANDLE winusb_handle
;
2857 int current_interface
;
2860 CHECK_WINUSBX_AVAILABLE(sub_api
);
2862 transfer_priv
->pollable_fd
= INVALID_WINFD
;
2863 size
= transfer
->length
- LIBUSB_CONTROL_SETUP_SIZE
;
2865 if (size
> MAX_CTRL_BUFFER_LENGTH
)
2866 return LIBUSB_ERROR_INVALID_PARAM
;
2868 current_interface
= get_valid_interface(transfer
->dev_handle
, USB_API_WINUSBX
);
2869 if (current_interface
< 0) {
2870 if (auto_claim(transfer
, ¤t_interface
, USB_API_WINUSBX
) != LIBUSB_SUCCESS
) {
2871 return LIBUSB_ERROR_NOT_FOUND
;
2875 usbi_dbg("will use interface %d", current_interface
);
2876 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
2878 wfd
= usbi_create_fd(winusb_handle
, RW_READ
, NULL
, NULL
);
2879 // Always use the handle returned from usbi_create_fd (wfd.handle)
2881 return LIBUSB_ERROR_NO_MEM
;
2884 // Sending of set configuration control requests from WinUSB creates issues
2885 if ( ((setup
->request_type
& (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD
)
2886 && (setup
->request
== LIBUSB_REQUEST_SET_CONFIGURATION
) ) {
2887 if (setup
->value
!= priv
->active_config
) {
2888 usbi_warn(ctx
, "cannot set configuration other than the default one");
2890 return LIBUSB_ERROR_INVALID_PARAM
;
2892 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2893 wfd
.overlapped
->InternalHigh
= 0;
2895 if (!WinUSBX
[sub_api
].ControlTransfer(wfd
.handle
, *setup
, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, size
, NULL
, wfd
.overlapped
)) {
2896 if(GetLastError() != ERROR_IO_PENDING
) {
2897 usbi_warn(ctx
, "ControlTransfer failed: %s", windows_error_str(0));
2899 return LIBUSB_ERROR_IO
;
2902 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2903 wfd
.overlapped
->InternalHigh
= (DWORD
)size
;
2907 // Use priv_transfer to store data needed for async polling
2908 transfer_priv
->pollable_fd
= wfd
;
2909 transfer_priv
->interface_number
= (uint8_t)current_interface
;
2911 return LIBUSB_SUCCESS
;
2914 static int winusbx_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
2916 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2917 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2918 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2919 HANDLE winusb_handle
;
2921 CHECK_WINUSBX_AVAILABLE(sub_api
);
2923 if (altsetting
> 255) {
2924 return LIBUSB_ERROR_INVALID_PARAM
;
2927 winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2928 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2929 usbi_err(ctx
, "interface must be claimed first");
2930 return LIBUSB_ERROR_NOT_FOUND
;
2933 if (!WinUSBX
[sub_api
].SetCurrentAlternateSetting(winusb_handle
, (UCHAR
)altsetting
)) {
2934 usbi_err(ctx
, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2935 return LIBUSB_ERROR_IO
;
2938 return LIBUSB_SUCCESS
;
2941 static int winusbx_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
2943 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2944 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
2945 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
2946 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
2947 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2948 HANDLE winusb_handle
;
2950 int current_interface
;
2953 CHECK_WINUSBX_AVAILABLE(sub_api
);
2955 transfer_priv
->pollable_fd
= INVALID_WINFD
;
2957 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
2958 if (current_interface
< 0) {
2959 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
2960 return LIBUSB_ERROR_NOT_FOUND
;
2963 usbi_dbg("matched endpoint %02X with interface %d", transfer
->endpoint
, current_interface
);
2965 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
2967 wfd
= usbi_create_fd(winusb_handle
, IS_XFERIN(transfer
) ? RW_READ
: RW_WRITE
, NULL
, NULL
);
2968 // Always use the handle returned from usbi_create_fd (wfd.handle)
2970 return LIBUSB_ERROR_NO_MEM
;
2973 if (IS_XFERIN(transfer
)) {
2974 usbi_dbg("reading %d bytes", transfer
->length
);
2975 ret
= WinUSBX
[sub_api
].ReadPipe(wfd
.handle
, transfer
->endpoint
, transfer
->buffer
, transfer
->length
, NULL
, wfd
.overlapped
);
2977 usbi_dbg("writing %d bytes", transfer
->length
);
2978 ret
= WinUSBX
[sub_api
].WritePipe(wfd
.handle
, transfer
->endpoint
, transfer
->buffer
, transfer
->length
, NULL
, wfd
.overlapped
);
2981 if(GetLastError() != ERROR_IO_PENDING
) {
2982 usbi_err(ctx
, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2984 return LIBUSB_ERROR_IO
;
2987 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2988 wfd
.overlapped
->InternalHigh
= (DWORD
)transfer
->length
;
2991 transfer_priv
->pollable_fd
= wfd
;
2992 transfer_priv
->interface_number
= (uint8_t)current_interface
;
2994 return LIBUSB_SUCCESS
;
2997 static int winusbx_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
2999 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3000 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3001 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3002 HANDLE winusb_handle
;
3003 int current_interface
;
3005 CHECK_WINUSBX_AVAILABLE(sub_api
);
3007 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
3008 if (current_interface
< 0) {
3009 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
3010 return LIBUSB_ERROR_NOT_FOUND
;
3013 usbi_dbg("matched endpoint %02X with interface %d", endpoint
, current_interface
);
3014 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3016 if (!WinUSBX
[sub_api
].ResetPipe(winusb_handle
, endpoint
)) {
3017 usbi_err(ctx
, "ResetPipe failed: %s", windows_error_str(0));
3018 return LIBUSB_ERROR_NO_DEVICE
;
3021 return LIBUSB_SUCCESS
;
3025 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3026 * through testing as well):
3027 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3028 * the control transfer using CancelIo"
3030 static int winusbx_abort_control(int sub_api
, struct usbi_transfer
*itransfer
)
3032 // Cancelling of the I/O is done in the parent
3033 return LIBUSB_SUCCESS
;
3036 static int winusbx_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
3038 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3039 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3040 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3041 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3042 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3043 HANDLE winusb_handle
;
3044 int current_interface
;
3046 CHECK_WINUSBX_AVAILABLE(sub_api
);
3048 current_interface
= transfer_priv
->interface_number
;
3049 if ((current_interface
< 0) || (current_interface
>= USB_MAXINTERFACES
)) {
3050 usbi_err(ctx
, "program assertion failed: invalid interface_number");
3051 return LIBUSB_ERROR_NOT_FOUND
;
3053 usbi_dbg("will use interface %d", current_interface
);
3055 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3057 if (!WinUSBX
[sub_api
].AbortPipe(winusb_handle
, transfer
->endpoint
)) {
3058 usbi_err(ctx
, "AbortPipe failed: %s", windows_error_str(0));
3059 return LIBUSB_ERROR_NO_DEVICE
;
3062 return LIBUSB_SUCCESS
;
3066 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3067 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3068 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3069 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3070 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3071 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3073 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3074 static int winusbx_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
3076 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3077 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3078 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3080 HANDLE winusb_handle
;
3083 CHECK_WINUSBX_AVAILABLE(sub_api
);
3085 // Reset any available pipe (except control)
3086 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
3087 winusb_handle
= handle_priv
->interface_handle
[i
].api_handle
;
3088 for (wfd
= handle_to_winfd(winusb_handle
); wfd
.fd
> 0;)
3090 // Cancel any pollable I/O
3091 usbi_remove_pollfd(ctx
, wfd
.fd
);
3093 wfd
= handle_to_winfd(winusb_handle
);
3096 if ( (winusb_handle
!= 0) && (winusb_handle
!= INVALID_HANDLE_VALUE
)) {
3097 for (j
=0; j
<priv
->usb_interface
[i
].nb_endpoints
; j
++) {
3098 usbi_dbg("resetting ep %02X", priv
->usb_interface
[i
].endpoint
[j
]);
3099 if (!WinUSBX
[sub_api
].AbortPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) {
3100 usbi_err(ctx
, "AbortPipe (pipe address %02X) failed: %s",
3101 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3103 // FlushPipe seems to fail on OUT pipes
3104 if (IS_EPIN(priv
->usb_interface
[i
].endpoint
[j
])
3105 && (!WinUSBX
[sub_api
].FlushPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) ) {
3106 usbi_err(ctx
, "FlushPipe (pipe address %02X) failed: %s",
3107 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3109 if (!WinUSBX
[sub_api
].ResetPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) {
3110 usbi_err(ctx
, "ResetPipe (pipe address %02X) failed: %s",
3111 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3117 // libusbK & libusb0 have the ability to issue an actual device reset
3118 if (WinUSBX
[sub_api
].ResetDevice
!= NULL
) {
3119 winusb_handle
= handle_priv
->interface_handle
[0].api_handle
;
3120 if ( (winusb_handle
!= 0) && (winusb_handle
!= INVALID_HANDLE_VALUE
)) {
3121 WinUSBX
[sub_api
].ResetDevice(winusb_handle
);
3124 return LIBUSB_SUCCESS
;
3127 static int winusbx_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
)
3129 itransfer
->transferred
+= io_size
;
3130 return LIBUSB_TRANSFER_COMPLETED
;
3134 * Internal HID Support functions (from libusb-win32)
3135 * Note that functions that complete data transfer synchronously must return
3136 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3138 static int _hid_get_hid_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
);
3139 static int _hid_get_report_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
);
3141 static int _hid_wcslen(WCHAR
*str
)
3144 while (str
[i
] && (str
[i
] != 0x409)) {
3150 static int _hid_get_device_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3152 struct libusb_device_descriptor d
;
3154 d
.bLength
= LIBUSB_DT_DEVICE_SIZE
;
3155 d
.bDescriptorType
= LIBUSB_DT_DEVICE
;
3156 d
.bcdUSB
= 0x0200; /* 2.00 */
3158 d
.bDeviceSubClass
= 0;
3159 d
.bDeviceProtocol
= 0;
3160 d
.bMaxPacketSize0
= 64; /* fix this! */
3161 d
.idVendor
= (uint16_t)dev
->vid
;
3162 d
.idProduct
= (uint16_t)dev
->pid
;
3163 d
.bcdDevice
= 0x0100;
3164 d
.iManufacturer
= dev
->string_index
[0];
3165 d
.iProduct
= dev
->string_index
[1];
3166 d
.iSerialNumber
= dev
->string_index
[2];
3167 d
.bNumConfigurations
= 1;
3169 if (*size
> LIBUSB_DT_DEVICE_SIZE
)
3170 *size
= LIBUSB_DT_DEVICE_SIZE
;
3171 memcpy(data
, &d
, *size
);
3172 return LIBUSB_COMPLETED
;
3175 static int _hid_get_config_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3177 char num_endpoints
= 0;
3178 size_t config_total_len
= 0;
3179 char tmp
[HID_MAX_CONFIG_DESC_SIZE
];
3180 struct libusb_config_descriptor
*cd
;
3181 struct libusb_interface_descriptor
*id
;
3182 struct libusb_hid_descriptor
*hd
;
3183 struct libusb_endpoint_descriptor
*ed
;
3186 if (dev
->input_report_size
)
3188 if (dev
->output_report_size
)
3191 config_total_len
= LIBUSB_DT_CONFIG_SIZE
+ LIBUSB_DT_INTERFACE_SIZE
3192 + LIBUSB_DT_HID_SIZE
+ num_endpoints
* LIBUSB_DT_ENDPOINT_SIZE
;
3195 cd
= (struct libusb_config_descriptor
*)tmp
;
3196 id
= (struct libusb_interface_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
);
3197 hd
= (struct libusb_hid_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
3198 + LIBUSB_DT_INTERFACE_SIZE
);
3199 ed
= (struct libusb_endpoint_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
3200 + LIBUSB_DT_INTERFACE_SIZE
3201 + LIBUSB_DT_HID_SIZE
);
3203 cd
->bLength
= LIBUSB_DT_CONFIG_SIZE
;
3204 cd
->bDescriptorType
= LIBUSB_DT_CONFIG
;
3205 cd
->wTotalLength
= (uint16_t) config_total_len
;
3206 cd
->bNumInterfaces
= 1;
3207 cd
->bConfigurationValue
= 1;
3208 cd
->iConfiguration
= 0;
3209 cd
->bmAttributes
= 1 << 7; /* bus powered */
3212 id
->bLength
= LIBUSB_DT_INTERFACE_SIZE
;
3213 id
->bDescriptorType
= LIBUSB_DT_INTERFACE
;
3214 id
->bInterfaceNumber
= 0;
3215 id
->bAlternateSetting
= 0;
3216 id
->bNumEndpoints
= num_endpoints
;
3217 id
->bInterfaceClass
= 3;
3218 id
->bInterfaceSubClass
= 0;
3219 id
->bInterfaceProtocol
= 0;
3222 tmp_size
= LIBUSB_DT_HID_SIZE
;
3223 _hid_get_hid_descriptor(dev
, hd
, &tmp_size
);
3225 if (dev
->input_report_size
) {
3226 ed
->bLength
= LIBUSB_DT_ENDPOINT_SIZE
;
3227 ed
->bDescriptorType
= LIBUSB_DT_ENDPOINT
;
3228 ed
->bEndpointAddress
= HID_IN_EP
;
3229 ed
->bmAttributes
= 3;
3230 ed
->wMaxPacketSize
= dev
->input_report_size
- 1;
3232 ed
= (struct libusb_endpoint_descriptor
*)((char*)ed
+ LIBUSB_DT_ENDPOINT_SIZE
);
3235 if (dev
->output_report_size
) {
3236 ed
->bLength
= LIBUSB_DT_ENDPOINT_SIZE
;
3237 ed
->bDescriptorType
= LIBUSB_DT_ENDPOINT
;
3238 ed
->bEndpointAddress
= HID_OUT_EP
;
3239 ed
->bmAttributes
= 3;
3240 ed
->wMaxPacketSize
= dev
->output_report_size
- 1;
3244 if (*size
> config_total_len
)
3245 *size
= config_total_len
;
3246 memcpy(data
, tmp
, *size
);
3247 return LIBUSB_COMPLETED
;
3250 static int _hid_get_string_descriptor(struct hid_device_priv
* dev
, int _index
,
3251 void *data
, size_t *size
)
3254 size_t tmp_size
= 0;
3257 /* language ID, EN-US */
3258 char string_langid
[] = {
3263 if ((*size
< 2) || (*size
> 255)) {
3264 return LIBUSB_ERROR_OVERFLOW
;
3268 tmp
= string_langid
;
3269 tmp_size
= sizeof(string_langid
)+2;
3271 for (i
=0; i
<3; i
++) {
3272 if (_index
== (dev
->string_index
[i
])) {
3273 tmp
= dev
->string
[i
];
3274 tmp_size
= (_hid_wcslen(dev
->string
[i
])+1) * sizeof(WCHAR
);
3278 if (i
== 3) { // not found
3279 return LIBUSB_ERROR_INVALID_PARAM
;
3284 return LIBUSB_ERROR_INVALID_PARAM
;
3287 if (tmp_size
< *size
) {
3291 ((uint8_t*)data
)[0] = (uint8_t)*size
;
3292 ((uint8_t*)data
)[1] = LIBUSB_DT_STRING
;
3293 memcpy((uint8_t*)data
+2, tmp
, *size
-2);
3294 return LIBUSB_COMPLETED
;
3297 static int _hid_get_hid_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3299 struct libusb_hid_descriptor d
;
3300 uint8_t tmp
[MAX_HID_DESCRIPTOR_SIZE
];
3301 size_t report_len
= MAX_HID_DESCRIPTOR_SIZE
;
3303 _hid_get_report_descriptor(dev
, tmp
, &report_len
);
3305 d
.bLength
= LIBUSB_DT_HID_SIZE
;
3306 d
.bDescriptorType
= LIBUSB_DT_HID
;
3307 d
.bcdHID
= 0x0110; /* 1.10 */
3309 d
.bNumDescriptors
= 1;
3310 d
.bClassDescriptorType
= LIBUSB_DT_REPORT
;
3311 d
.wClassDescriptorLength
= (uint16_t)report_len
;
3313 if (*size
> LIBUSB_DT_HID_SIZE
)
3314 *size
= LIBUSB_DT_HID_SIZE
;
3315 memcpy(data
, &d
, *size
);
3316 return LIBUSB_COMPLETED
;
3319 static int _hid_get_report_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3321 uint8_t d
[MAX_HID_DESCRIPTOR_SIZE
];
3324 /* usage page (0xFFA0 == vendor defined) */
3325 d
[i
++] = 0x06; d
[i
++] = 0xA0; d
[i
++] = 0xFF;
3326 /* usage (vendor defined) */
3327 d
[i
++] = 0x09; d
[i
++] = 0x01;
3328 /* start collection (application) */
3329 d
[i
++] = 0xA1; d
[i
++] = 0x01;
3331 if (dev
->input_report_size
) {
3332 /* usage (vendor defined) */
3333 d
[i
++] = 0x09; d
[i
++] = 0x01;
3334 /* logical minimum (0) */
3335 d
[i
++] = 0x15; d
[i
++] = 0x00;
3336 /* logical maximum (255) */
3337 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3338 /* report size (8 bits) */
3339 d
[i
++] = 0x75; d
[i
++] = 0x08;
3341 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->input_report_size
- 1;
3342 /* input (data, variable, absolute) */
3343 d
[i
++] = 0x81; d
[i
++] = 0x00;
3346 if (dev
->output_report_size
) {
3347 /* usage (vendor defined) */
3348 d
[i
++] = 0x09; d
[i
++] = 0x02;
3349 /* logical minimum (0) */
3350 d
[i
++] = 0x15; d
[i
++] = 0x00;
3351 /* logical maximum (255) */
3352 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3353 /* report size (8 bits) */
3354 d
[i
++] = 0x75; d
[i
++] = 0x08;
3356 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->output_report_size
- 1;
3357 /* output (data, variable, absolute) */
3358 d
[i
++] = 0x91; d
[i
++] = 0x00;
3360 /* feature report */
3361 if (dev
->feature_report_size
) {
3362 /* usage (vendor defined) */
3363 d
[i
++] = 0x09; d
[i
++] = 0x03;
3364 /* logical minimum (0) */
3365 d
[i
++] = 0x15; d
[i
++] = 0x00;
3366 /* logical maximum (255) */
3367 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3368 /* report size (8 bits) */
3369 d
[i
++] = 0x75; d
[i
++] = 0x08;
3371 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->feature_report_size
- 1;
3372 /* feature (data, variable, absolute) */
3373 d
[i
++] = 0xb2; d
[i
++] = 0x02; d
[i
++] = 0x01;
3376 /* end collection */
3381 memcpy(data
, d
, *size
);
3382 return LIBUSB_COMPLETED
;
3385 static int _hid_get_descriptor(struct hid_device_priv
* dev
, HANDLE hid_handle
, int recipient
,
3386 int type
, int _index
, void *data
, size_t *size
)
3389 case LIBUSB_DT_DEVICE
:
3390 usbi_dbg("LIBUSB_DT_DEVICE");
3391 return _hid_get_device_descriptor(dev
, data
, size
);
3392 case LIBUSB_DT_CONFIG
:
3393 usbi_dbg("LIBUSB_DT_CONFIG");
3395 return _hid_get_config_descriptor(dev
, data
, size
);
3396 return LIBUSB_ERROR_INVALID_PARAM
;
3397 case LIBUSB_DT_STRING
:
3398 usbi_dbg("LIBUSB_DT_STRING");
3399 return _hid_get_string_descriptor(dev
, _index
, data
, size
);
3401 usbi_dbg("LIBUSB_DT_HID");
3403 return _hid_get_hid_descriptor(dev
, data
, size
);
3404 return LIBUSB_ERROR_INVALID_PARAM
;
3405 case LIBUSB_DT_REPORT
:
3406 usbi_dbg("LIBUSB_DT_REPORT");
3408 return _hid_get_report_descriptor(dev
, data
, size
);
3409 return LIBUSB_ERROR_INVALID_PARAM
;
3410 case LIBUSB_DT_PHYSICAL
:
3411 usbi_dbg("LIBUSB_DT_PHYSICAL");
3412 if (HidD_GetPhysicalDescriptor(hid_handle
, data
, (ULONG
)*size
))
3413 return LIBUSB_COMPLETED
;
3414 return LIBUSB_ERROR_OTHER
;
3416 usbi_dbg("unsupported");
3417 return LIBUSB_ERROR_INVALID_PARAM
;
3420 static int _hid_get_report(struct hid_device_priv
* dev
, HANDLE hid_handle
, int id
, void *data
,
3421 struct windows_transfer_priv
*tp
, size_t *size
, OVERLAPPED
* overlapped
,
3425 DWORD ioctl_code
, read_size
, expected_size
= (DWORD
)*size
;
3426 int r
= LIBUSB_SUCCESS
;
3428 if (tp
->hid_buffer
!= NULL
) {
3429 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3432 if ((*size
== 0) || (*size
> MAX_HID_REPORT_SIZE
)) {
3433 usbi_dbg("invalid size (%d)", *size
);
3434 return LIBUSB_ERROR_INVALID_PARAM
;
3437 switch (report_type
) {
3438 case HID_REPORT_TYPE_INPUT
:
3439 ioctl_code
= IOCTL_HID_GET_INPUT_REPORT
;
3441 case HID_REPORT_TYPE_FEATURE
:
3442 ioctl_code
= IOCTL_HID_GET_FEATURE
;
3445 usbi_dbg("unknown HID report type %d", report_type
);
3446 return LIBUSB_ERROR_INVALID_PARAM
;
3449 // Add a trailing byte to detect overflows
3450 buf
= (uint8_t*)calloc(expected_size
+1, 1);
3452 return LIBUSB_ERROR_NO_MEM
;
3454 buf
[0] = (uint8_t)id
; // Must be set always
3455 usbi_dbg("report ID: 0x%02X", buf
[0]);
3457 tp
->hid_expected_size
= expected_size
;
3458 read_size
= expected_size
;
3460 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3461 if (!DeviceIoControl(hid_handle
, ioctl_code
, buf
, expected_size
+1,
3462 buf
, expected_size
+1, &read_size
, overlapped
)) {
3463 if (GetLastError() != ERROR_IO_PENDING
) {
3464 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3466 return LIBUSB_ERROR_IO
;
3468 // Asynchronous wait
3469 tp
->hid_buffer
= buf
;
3470 tp
->hid_dest
= (uint8_t*)data
; // copy dest, as not necessarily the start of the transfer buffer
3471 return LIBUSB_SUCCESS
;
3474 // Transfer completed synchronously => copy and discard extra buffer
3475 if (read_size
== 0) {
3476 usbi_warn(NULL
, "program assertion failed - read completed synchronously, but no data was read");
3480 usbi_warn(NULL
, "mismatched report ID (data is %02X, parameter is %02X)", buf
[0], id
);
3482 if ((size_t)read_size
> expected_size
) {
3483 r
= LIBUSB_ERROR_OVERFLOW
;
3484 usbi_dbg("OVERFLOW!");
3486 r
= LIBUSB_COMPLETED
;
3489 *size
= MIN((size_t)read_size
, *size
);
3491 // Discard report ID
3492 memcpy(data
, buf
+1, *size
);
3494 memcpy(data
, buf
, *size
);
3501 static int _hid_set_report(struct hid_device_priv
* dev
, HANDLE hid_handle
, int id
, void *data
,
3502 struct windows_transfer_priv
*tp
, size_t *size
, OVERLAPPED
* overlapped
,
3505 uint8_t *buf
= NULL
;
3506 DWORD ioctl_code
, write_size
= (DWORD
)*size
;
3508 if (tp
->hid_buffer
!= NULL
) {
3509 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3512 if ((*size
== 0) || (*size
> MAX_HID_REPORT_SIZE
)) {
3513 usbi_dbg("invalid size (%d)", *size
);
3514 return LIBUSB_ERROR_INVALID_PARAM
;
3517 switch (report_type
) {
3518 case HID_REPORT_TYPE_OUTPUT
:
3519 ioctl_code
= IOCTL_HID_SET_OUTPUT_REPORT
;
3521 case HID_REPORT_TYPE_FEATURE
:
3522 ioctl_code
= IOCTL_HID_SET_FEATURE
;
3525 usbi_dbg("unknown HID report type %d", report_type
);
3526 return LIBUSB_ERROR_INVALID_PARAM
;
3529 usbi_dbg("report ID: 0x%02X", id
);
3530 // When report IDs are not used (i.e. when id == 0), we must add
3531 // a null report ID. Otherwise, we just use original data buffer
3535 buf
= (uint8_t*) malloc(write_size
);
3537 return LIBUSB_ERROR_NO_MEM
;
3541 memcpy(buf
+ 1, data
, *size
);
3543 // This seems like a waste, but if we don't duplicate the
3544 // data, we'll get issues when freeing hid_buffer
3545 memcpy(buf
, data
, *size
);
3547 usbi_warn(NULL
, "mismatched report ID (data is %02X, parameter is %02X)", buf
[0], id
);
3551 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3552 if (!DeviceIoControl(hid_handle
, ioctl_code
, buf
, write_size
,
3553 buf
, write_size
, &write_size
, overlapped
)) {
3554 if (GetLastError() != ERROR_IO_PENDING
) {
3555 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3557 return LIBUSB_ERROR_IO
;
3559 tp
->hid_buffer
= buf
;
3560 tp
->hid_dest
= NULL
;
3561 return LIBUSB_SUCCESS
;
3564 // Transfer completed synchronously
3566 if (write_size
== 0) {
3567 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3570 return LIBUSB_COMPLETED
;
3573 static int _hid_class_request(struct hid_device_priv
* dev
, HANDLE hid_handle
, int request_type
,
3574 int request
, int value
, int _index
, void *data
, struct windows_transfer_priv
*tp
,
3575 size_t *size
, OVERLAPPED
* overlapped
)
3577 int report_type
= (value
>> 8) & 0xFF;
3578 int report_id
= value
& 0xFF;
3580 if ( (LIBUSB_REQ_RECIPIENT(request_type
) != LIBUSB_RECIPIENT_INTERFACE
)
3581 && (LIBUSB_REQ_RECIPIENT(request_type
) != LIBUSB_RECIPIENT_DEVICE
) )
3582 return LIBUSB_ERROR_INVALID_PARAM
;
3584 if (LIBUSB_REQ_OUT(request_type
) && request
== HID_REQ_SET_REPORT
)
3585 return _hid_set_report(dev
, hid_handle
, report_id
, data
, tp
, size
, overlapped
, report_type
);
3587 if (LIBUSB_REQ_IN(request_type
) && request
== HID_REQ_GET_REPORT
)
3588 return _hid_get_report(dev
, hid_handle
, report_id
, data
, tp
, size
, overlapped
, report_type
);
3590 return LIBUSB_ERROR_INVALID_PARAM
;
3597 static int hid_init(int sub_api
, struct libusb_context
*ctx
)
3599 DLL_LOAD(hid
.dll
, HidD_GetAttributes
, TRUE
);
3600 DLL_LOAD(hid
.dll
, HidD_GetHidGuid
, TRUE
);
3601 DLL_LOAD(hid
.dll
, HidD_GetPreparsedData
, TRUE
);
3602 DLL_LOAD(hid
.dll
, HidD_FreePreparsedData
, TRUE
);
3603 DLL_LOAD(hid
.dll
, HidD_GetManufacturerString
, TRUE
);
3604 DLL_LOAD(hid
.dll
, HidD_GetProductString
, TRUE
);
3605 DLL_LOAD(hid
.dll
, HidD_GetSerialNumberString
, TRUE
);
3606 DLL_LOAD(hid
.dll
, HidP_GetCaps
, TRUE
);
3607 DLL_LOAD(hid
.dll
, HidD_SetNumInputBuffers
, TRUE
);
3608 DLL_LOAD(hid
.dll
, HidD_SetFeature
, TRUE
);
3609 DLL_LOAD(hid
.dll
, HidD_GetFeature
, TRUE
);
3610 DLL_LOAD(hid
.dll
, HidD_GetPhysicalDescriptor
, TRUE
);
3611 DLL_LOAD(hid
.dll
, HidD_GetInputReport
, FALSE
);
3612 DLL_LOAD(hid
.dll
, HidD_SetOutputReport
, FALSE
);
3613 DLL_LOAD(hid
.dll
, HidD_FlushQueue
, TRUE
);
3614 DLL_LOAD(hid
.dll
, HidP_GetValueCaps
, TRUE
);
3616 api_hid_available
= true;
3617 return LIBUSB_SUCCESS
;
3620 static int hid_exit(int sub_api
)
3622 return LIBUSB_SUCCESS
;
3625 // NB: open and close must ensure that they only handle interface of
3626 // the right API type, as these functions can be called wholesale from
3627 // composite_open(), with interfaces belonging to different APIs
3628 static int hid_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
3630 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3631 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3632 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3634 HIDD_ATTRIBUTES hid_attributes
;
3635 PHIDP_PREPARSED_DATA preparsed_data
= NULL
;
3636 HIDP_CAPS capabilities
;
3637 HIDP_VALUE_CAPS
*value_caps
;
3639 HANDLE hid_handle
= INVALID_HANDLE_VALUE
;
3641 // report IDs handling
3643 const char* type
[3] = {"input", "output", "feature"};
3644 int nb_ids
[2]; // zero and nonzero report IDs
3646 CHECK_HID_AVAILABLE
;
3647 if (priv
->hid
== NULL
) {
3648 usbi_err(ctx
, "program assertion failed - private HID structure is unitialized");
3649 return LIBUSB_ERROR_NOT_FOUND
;
3652 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
3653 if ( (priv
->usb_interface
[i
].path
!= NULL
)
3654 && (priv
->usb_interface
[i
].apib
->id
== USB_API_HID
) ) {
3655 hid_handle
= CreateFileA(priv
->usb_interface
[i
].path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
3656 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
3658 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3659 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3660 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3661 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3662 * HidD_GetFeature (if the device supports Feature reports)."
3664 if (hid_handle
== INVALID_HANDLE_VALUE
) {
3665 usbi_warn(ctx
, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3666 hid_handle
= CreateFileA(priv
->usb_interface
[i
].path
, 0, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
3667 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
3668 if (hid_handle
== INVALID_HANDLE_VALUE
) {
3669 usbi_err(ctx
, "could not open device %s (interface %d): %s", priv
->path
, i
, windows_error_str(0));
3670 switch(GetLastError()) {
3671 case ERROR_FILE_NOT_FOUND
: // The device was disconnected
3672 return LIBUSB_ERROR_NO_DEVICE
;
3673 case ERROR_ACCESS_DENIED
:
3674 return LIBUSB_ERROR_ACCESS
;
3676 return LIBUSB_ERROR_IO
;
3679 priv
->usb_interface
[i
].restricted_functionality
= true;
3681 handle_priv
->interface_handle
[i
].api_handle
= hid_handle
;
3685 hid_attributes
.Size
= sizeof(hid_attributes
);
3687 if (!HidD_GetAttributes(hid_handle
, &hid_attributes
)) {
3688 usbi_err(ctx
, "could not gain access to HID top collection (HidD_GetAttributes)");
3692 priv
->hid
->vid
= hid_attributes
.VendorID
;
3693 priv
->hid
->pid
= hid_attributes
.ProductID
;
3695 // Set the maximum available input buffer size
3696 for (i
=32; HidD_SetNumInputBuffers(hid_handle
, i
); i
*=2);
3697 usbi_dbg("set maximum input buffer size to %d", i
/2);
3699 // Get the maximum input and output report size
3700 if (!HidD_GetPreparsedData(hid_handle
, &preparsed_data
) || !preparsed_data
) {
3701 usbi_err(ctx
, "could not read HID preparsed data (HidD_GetPreparsedData)");
3704 if (HidP_GetCaps(preparsed_data
, &capabilities
) != HIDP_STATUS_SUCCESS
) {
3705 usbi_err(ctx
, "could not parse HID capabilities (HidP_GetCaps)");
3709 // Find out if interrupt will need report IDs
3710 size
[0] = capabilities
.NumberInputValueCaps
;
3711 size
[1] = capabilities
.NumberOutputValueCaps
;
3712 size
[2] = capabilities
.NumberFeatureValueCaps
;
3713 for (j
=HidP_Input
; j
<=HidP_Feature
; j
++) {
3714 usbi_dbg("%d HID %s report value(s) found", size
[j
], type
[j
]);
3715 priv
->hid
->uses_report_ids
[j
] = false;
3717 value_caps
= (HIDP_VALUE_CAPS
*) calloc(size
[j
], sizeof(HIDP_VALUE_CAPS
));
3718 if ( (value_caps
!= NULL
)
3719 && (HidP_GetValueCaps((HIDP_REPORT_TYPE
)j
, value_caps
, &size
[j
], preparsed_data
) == HIDP_STATUS_SUCCESS
)
3720 && (size
[j
] >= 1) ) {
3723 for (i
=0; i
<(int)size
[j
]; i
++) {
3724 usbi_dbg(" Report ID: 0x%02X", value_caps
[i
].ReportID
);
3725 if (value_caps
[i
].ReportID
!= 0) {
3731 if (nb_ids
[1] != 0) {
3732 if (nb_ids
[0] != 0) {
3733 usbi_warn(ctx
, "program assertion failed: zero and nonzero report IDs used for %s",
3736 priv
->hid
->uses_report_ids
[j
] = true;
3739 usbi_warn(ctx
, " could not process %s report IDs", type
[j
]);
3741 safe_free(value_caps
);
3745 // Set the report sizes
3746 priv
->hid
->input_report_size
= capabilities
.InputReportByteLength
;
3747 priv
->hid
->output_report_size
= capabilities
.OutputReportByteLength
;
3748 priv
->hid
->feature_report_size
= capabilities
.FeatureReportByteLength
;
3750 // Fetch string descriptors
3751 priv
->hid
->string_index
[0] = priv
->dev_descriptor
.iManufacturer
;
3752 if (priv
->hid
->string_index
[0] != 0) {
3753 HidD_GetManufacturerString(hid_handle
, priv
->hid
->string
[0],
3754 sizeof(priv
->hid
->string
[0]));
3756 priv
->hid
->string
[0][0] = 0;
3758 priv
->hid
->string_index
[1] = priv
->dev_descriptor
.iProduct
;
3759 if (priv
->hid
->string_index
[1] != 0) {
3760 HidD_GetProductString(hid_handle
, priv
->hid
->string
[1],
3761 sizeof(priv
->hid
->string
[1]));
3763 priv
->hid
->string
[1][0] = 0;
3765 priv
->hid
->string_index
[2] = priv
->dev_descriptor
.iSerialNumber
;
3766 if (priv
->hid
->string_index
[2] != 0) {
3767 HidD_GetSerialNumberString(hid_handle
, priv
->hid
->string
[2],
3768 sizeof(priv
->hid
->string
[2]));
3770 priv
->hid
->string
[2][0] = 0;
3774 if (preparsed_data
) {
3775 HidD_FreePreparsedData(preparsed_data
);
3778 return LIBUSB_SUCCESS
;
3781 static void hid_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
3783 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3784 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3788 if (!api_hid_available
)
3791 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
3792 if (priv
->usb_interface
[i
].apib
->id
== USB_API_HID
) {
3793 file_handle
= handle_priv
->interface_handle
[i
].api_handle
;
3794 if ( (file_handle
!= 0) && (file_handle
!= INVALID_HANDLE_VALUE
)) {
3795 CloseHandle(file_handle
);
3801 static int hid_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
3803 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3804 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3806 CHECK_HID_AVAILABLE
;
3808 // NB: Disconnection detection is not possible in this function
3809 if (priv
->usb_interface
[iface
].path
== NULL
) {
3810 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3813 // We use dev_handle as a flag for interface claimed
3814 if (handle_priv
->interface_handle
[iface
].dev_handle
== INTERFACE_CLAIMED
) {
3815 return LIBUSB_ERROR_BUSY
; // already claimed
3818 handle_priv
->interface_handle
[iface
].dev_handle
= INTERFACE_CLAIMED
;
3820 usbi_dbg("claimed interface %d", iface
);
3821 handle_priv
->active_interface
= iface
;
3823 return LIBUSB_SUCCESS
;
3826 static int hid_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
3828 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3829 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3831 CHECK_HID_AVAILABLE
;
3833 if (priv
->usb_interface
[iface
].path
== NULL
) {
3834 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3837 if (handle_priv
->interface_handle
[iface
].dev_handle
!= INTERFACE_CLAIMED
) {
3838 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3841 handle_priv
->interface_handle
[iface
].dev_handle
= INVALID_HANDLE_VALUE
;
3843 return LIBUSB_SUCCESS
;
3846 static int hid_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
3848 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3850 CHECK_HID_AVAILABLE
;
3852 if (altsetting
> 255) {
3853 return LIBUSB_ERROR_INVALID_PARAM
;
3856 if (altsetting
!= 0) {
3857 usbi_err(ctx
, "set interface altsetting not supported for altsetting >0");
3858 return LIBUSB_ERROR_NOT_SUPPORTED
;
3861 return LIBUSB_SUCCESS
;
3864 static int hid_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
3866 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3867 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3868 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3869 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3870 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3871 WINUSB_SETUP_PACKET
*setup
= (WINUSB_SETUP_PACKET
*) transfer
->buffer
;
3874 int current_interface
, config
;
3876 int r
= LIBUSB_ERROR_INVALID_PARAM
;
3878 CHECK_HID_AVAILABLE
;
3880 transfer_priv
->pollable_fd
= INVALID_WINFD
;
3881 safe_free(transfer_priv
->hid_buffer
);
3882 transfer_priv
->hid_dest
= NULL
;
3883 size
= transfer
->length
- LIBUSB_CONTROL_SETUP_SIZE
;
3885 if (size
> MAX_CTRL_BUFFER_LENGTH
) {
3886 return LIBUSB_ERROR_INVALID_PARAM
;
3889 current_interface
= get_valid_interface(transfer
->dev_handle
, USB_API_HID
);
3890 if (current_interface
< 0) {
3891 if (auto_claim(transfer
, ¤t_interface
, USB_API_HID
) != LIBUSB_SUCCESS
) {
3892 return LIBUSB_ERROR_NOT_FOUND
;
3896 usbi_dbg("will use interface %d", current_interface
);
3897 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3898 // Always use the handle returned from usbi_create_fd (wfd.handle)
3899 wfd
= usbi_create_fd(hid_handle
, RW_READ
, NULL
, NULL
);
3901 return LIBUSB_ERROR_NOT_FOUND
;
3904 switch(LIBUSB_REQ_TYPE(setup
->request_type
)) {
3905 case LIBUSB_REQUEST_TYPE_STANDARD
:
3906 switch(setup
->request
) {
3907 case LIBUSB_REQUEST_GET_DESCRIPTOR
:
3908 r
= _hid_get_descriptor(priv
->hid
, wfd
.handle
, LIBUSB_REQ_RECIPIENT(setup
->request_type
),
3909 (setup
->value
>> 8) & 0xFF, setup
->value
& 0xFF, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, &size
);
3911 case LIBUSB_REQUEST_GET_CONFIGURATION
:
3912 r
= windows_get_configuration(transfer
->dev_handle
, &config
);
3913 if (r
== LIBUSB_SUCCESS
) {
3915 ((uint8_t*)transfer
->buffer
)[LIBUSB_CONTROL_SETUP_SIZE
] = (uint8_t)config
;
3916 r
= LIBUSB_COMPLETED
;
3919 case LIBUSB_REQUEST_SET_CONFIGURATION
:
3920 if (setup
->value
== priv
->active_config
) {
3921 r
= LIBUSB_COMPLETED
;
3923 usbi_warn(ctx
, "cannot set configuration other than the default one");
3924 r
= LIBUSB_ERROR_INVALID_PARAM
;
3927 case LIBUSB_REQUEST_GET_INTERFACE
:
3929 ((uint8_t*)transfer
->buffer
)[LIBUSB_CONTROL_SETUP_SIZE
] = 0;
3930 r
= LIBUSB_COMPLETED
;
3932 case LIBUSB_REQUEST_SET_INTERFACE
:
3933 r
= hid_set_interface_altsetting(0, transfer
->dev_handle
, setup
->index
, setup
->value
);
3934 if (r
== LIBUSB_SUCCESS
) {
3935 r
= LIBUSB_COMPLETED
;
3939 usbi_warn(ctx
, "unsupported HID control request");
3940 r
= LIBUSB_ERROR_INVALID_PARAM
;
3944 case LIBUSB_REQUEST_TYPE_CLASS
:
3945 r
=_hid_class_request(priv
->hid
, wfd
.handle
, setup
->request_type
, setup
->request
, setup
->value
,
3946 setup
->index
, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, transfer_priv
,
3947 &size
, wfd
.overlapped
);
3950 usbi_warn(ctx
, "unsupported HID control request");
3951 r
= LIBUSB_ERROR_INVALID_PARAM
;
3955 if (r
== LIBUSB_COMPLETED
) {
3956 // Force request to be completed synchronously. Transferred size has been set by previous call
3957 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
3958 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3959 // set InternalHigh to the number of bytes transferred
3960 wfd
.overlapped
->InternalHigh
= (DWORD
)size
;
3964 if (r
== LIBUSB_SUCCESS
) {
3965 // Use priv_transfer to store data needed for async polling
3966 transfer_priv
->pollable_fd
= wfd
;
3967 transfer_priv
->interface_number
= (uint8_t)current_interface
;
3975 static int hid_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
3976 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3977 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3978 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3979 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3980 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3983 bool direction_in
, ret
;
3984 int current_interface
, length
;
3986 int r
= LIBUSB_SUCCESS
;
3988 CHECK_HID_AVAILABLE
;
3990 transfer_priv
->pollable_fd
= INVALID_WINFD
;
3991 transfer_priv
->hid_dest
= NULL
;
3992 safe_free(transfer_priv
->hid_buffer
);
3994 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
3995 if (current_interface
< 0) {
3996 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
3997 return LIBUSB_ERROR_NOT_FOUND
;
4000 usbi_dbg("matched endpoint %02X with interface %d", transfer
->endpoint
, current_interface
);
4002 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4003 direction_in
= transfer
->endpoint
& LIBUSB_ENDPOINT_IN
;
4005 wfd
= usbi_create_fd(hid_handle
, direction_in
?RW_READ
:RW_WRITE
, NULL
, NULL
);
4006 // Always use the handle returned from usbi_create_fd (wfd.handle)
4008 return LIBUSB_ERROR_NO_MEM
;
4011 // If report IDs are not in use, an extra prefix byte must be added
4012 if ( ((direction_in
) && (!priv
->hid
->uses_report_ids
[0]))
4013 || ((!direction_in
) && (!priv
->hid
->uses_report_ids
[1])) ) {
4014 length
= transfer
->length
+1;
4016 length
= transfer
->length
;
4018 // Add a trailing byte to detect overflows on input
4019 transfer_priv
->hid_buffer
= (uint8_t*)calloc(length
+1, 1);
4020 if (transfer_priv
->hid_buffer
== NULL
) {
4021 return LIBUSB_ERROR_NO_MEM
;
4023 transfer_priv
->hid_expected_size
= length
;
4026 transfer_priv
->hid_dest
= transfer
->buffer
;
4027 usbi_dbg("reading %d bytes (report ID: 0x00)", length
);
4028 ret
= ReadFile(wfd
.handle
, transfer_priv
->hid_buffer
, length
+1, &size
, wfd
.overlapped
);
4030 if (!priv
->hid
->uses_report_ids
[1]) {
4031 memcpy(transfer_priv
->hid_buffer
+1, transfer
->buffer
, transfer
->length
);
4033 // We could actually do without the calloc and memcpy in this case
4034 memcpy(transfer_priv
->hid_buffer
, transfer
->buffer
, transfer
->length
);
4036 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length
, transfer_priv
->hid_buffer
[0]);
4037 ret
= WriteFile(wfd
.handle
, transfer_priv
->hid_buffer
, length
, &size
, wfd
.overlapped
);
4040 if (GetLastError() != ERROR_IO_PENDING
) {
4041 usbi_err(ctx
, "HID transfer failed: %s", windows_error_str(0));
4043 safe_free(transfer_priv
->hid_buffer
);
4044 return LIBUSB_ERROR_IO
;
4047 // Only write operations that completed synchronously need to free up
4048 // hid_buffer. For reads, copy_transfer_data() handles that process.
4049 if (!direction_in
) {
4050 safe_free(transfer_priv
->hid_buffer
);
4053 usbi_err(ctx
, "program assertion failed - no data was transferred");
4056 if (size
> (size_t)length
) {
4057 usbi_err(ctx
, "OVERFLOW!");
4058 r
= LIBUSB_ERROR_OVERFLOW
;
4060 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
4061 wfd
.overlapped
->InternalHigh
= size
;
4064 transfer_priv
->pollable_fd
= wfd
;
4065 transfer_priv
->interface_number
= (uint8_t)current_interface
;
4070 static int hid_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
4072 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4073 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
4074 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4076 int current_interface
;
4078 CHECK_HID_AVAILABLE
;
4080 current_interface
= transfer_priv
->interface_number
;
4081 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4082 CancelIo(hid_handle
);
4084 return LIBUSB_SUCCESS
;
4087 static int hid_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
4089 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4091 int current_interface
;
4093 CHECK_HID_AVAILABLE
;
4095 // Flushing the queues on all interfaces is the best we can achieve
4096 for (current_interface
= 0; current_interface
< USB_MAXINTERFACES
; current_interface
++) {
4097 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4098 if ((hid_handle
!= 0) && (hid_handle
!= INVALID_HANDLE_VALUE
)) {
4099 HidD_FlushQueue(hid_handle
);
4102 return LIBUSB_SUCCESS
;
4105 static int hid_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
4107 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
4108 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4109 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4111 int current_interface
;
4113 CHECK_HID_AVAILABLE
;
4115 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
4116 if (current_interface
< 0) {
4117 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
4118 return LIBUSB_ERROR_NOT_FOUND
;
4121 usbi_dbg("matched endpoint %02X with interface %d", endpoint
, current_interface
);
4122 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4124 // No endpoint selection with Microsoft's implementation, so we try to flush the
4125 // whole interface. Should be OK for most case scenarios
4126 if (!HidD_FlushQueue(hid_handle
)) {
4127 usbi_err(ctx
, "Flushing of HID queue failed: %s", windows_error_str(0));
4128 // Device was probably disconnected
4129 return LIBUSB_ERROR_NO_DEVICE
;
4132 return LIBUSB_SUCCESS
;
4135 // This extra function is only needed for HID
4136 static int hid_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
) {
4137 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4138 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4139 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4140 int r
= LIBUSB_TRANSFER_COMPLETED
;
4141 uint32_t corrected_size
= io_size
;
4143 if (transfer_priv
->hid_buffer
!= NULL
) {
4144 // If we have a valid hid_buffer, it means the transfer was async
4145 if (transfer_priv
->hid_dest
!= NULL
) { // Data readout
4146 // First, check for overflow
4147 if (corrected_size
> transfer_priv
->hid_expected_size
) {
4148 usbi_err(ctx
, "OVERFLOW!");
4149 corrected_size
= (uint32_t)transfer_priv
->hid_expected_size
;
4150 r
= LIBUSB_TRANSFER_OVERFLOW
;
4153 if (transfer_priv
->hid_buffer
[0] == 0) {
4154 // Discard the 1 byte report ID prefix
4156 memcpy(transfer_priv
->hid_dest
, transfer_priv
->hid_buffer
+1, corrected_size
);
4158 memcpy(transfer_priv
->hid_dest
, transfer_priv
->hid_buffer
, corrected_size
);
4160 transfer_priv
->hid_dest
= NULL
;
4162 // For write, we just need to free the hid buffer
4163 safe_free(transfer_priv
->hid_buffer
);
4165 itransfer
->transferred
+= corrected_size
;
4171 * Composite API functions
4173 static int composite_init(int sub_api
, struct libusb_context
*ctx
)
4175 return LIBUSB_SUCCESS
;
4178 static int composite_exit(int sub_api
)
4180 return LIBUSB_SUCCESS
;
4183 static int composite_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
4185 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4186 int r
= LIBUSB_ERROR_NOT_FOUND
;
4188 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4189 bool available
[SUB_API_MAX
+1] = {0};
4191 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4192 switch (priv
->usb_interface
[i
].apib
->id
) {
4193 case USB_API_WINUSBX
:
4194 if (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
)
4195 available
[priv
->usb_interface
[i
].sub_api
] = true;
4198 available
[SUB_API_MAX
] = true;
4205 for (i
=0; i
<SUB_API_MAX
; i
++) { // WinUSB-like drivers
4207 r
= usb_api_backend
[USB_API_WINUSBX
].open(i
, dev_handle
);
4208 if (r
!= LIBUSB_SUCCESS
) {
4213 if (available
[SUB_API_MAX
]) { // HID driver
4214 r
= hid_open(SUB_API_NOTSET
, dev_handle
);
4219 static void composite_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
4221 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4223 bool available
[SUB_API_MAX
];
4225 for (i
= 0; i
<SUB_API_MAX
; i
++) {
4226 available
[i
] = false;
4229 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4230 if ( (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
)
4231 && (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
) ) {
4232 available
[priv
->usb_interface
[i
].sub_api
] = true;
4236 for (i
=0; i
<SUB_API_MAX
; i
++) {
4238 usb_api_backend
[USB_API_WINUSBX
].close(i
, dev_handle
);
4243 static int composite_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
4245 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4246 return priv
->usb_interface
[iface
].apib
->
4247 claim_interface(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
);
4250 static int composite_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
4252 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4253 return priv
->usb_interface
[iface
].apib
->
4254 set_interface_altsetting(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
, altsetting
);
4257 static int composite_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
4259 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4260 return priv
->usb_interface
[iface
].apib
->
4261 release_interface(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
);
4264 static int composite_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
4266 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4267 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4268 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4271 // Interface shouldn't matter for control, but it does in practice, with Windows'
4272 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4273 for (pass
= 0; pass
< 2; pass
++) {
4274 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4275 if (priv
->usb_interface
[i
].path
!= NULL
) {
4276 if ((pass
== 0) && (priv
->usb_interface
[i
].restricted_functionality
)) {
4277 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i
);
4280 usbi_dbg("using interface %d", i
);
4281 return priv
->usb_interface
[i
].apib
->submit_control_transfer(priv
->usb_interface
[i
].sub_api
, itransfer
);
4286 usbi_err(ctx
, "no libusbx supported interfaces to complete request");
4287 return LIBUSB_ERROR_NOT_FOUND
;
4290 static int composite_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
4291 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4292 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4293 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4294 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4295 int current_interface
;
4297 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
4298 if (current_interface
< 0) {
4299 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
4300 return LIBUSB_ERROR_NOT_FOUND
;
4303 return priv
->usb_interface
[current_interface
].apib
->
4304 submit_bulk_transfer(priv
->usb_interface
[current_interface
].sub_api
, itransfer
);}
4306 static int composite_submit_iso_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
4307 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4308 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4309 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4310 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4311 int current_interface
;
4313 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
4314 if (current_interface
< 0) {
4315 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
4316 return LIBUSB_ERROR_NOT_FOUND
;
4319 return priv
->usb_interface
[current_interface
].apib
->
4320 submit_iso_transfer(priv
->usb_interface
[current_interface
].sub_api
, itransfer
);}
4322 static int composite_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
4324 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
4325 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4326 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4327 int current_interface
;
4329 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
4330 if (current_interface
< 0) {
4331 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
4332 return LIBUSB_ERROR_NOT_FOUND
;
4335 return priv
->usb_interface
[current_interface
].apib
->
4336 clear_halt(priv
->usb_interface
[current_interface
].sub_api
, dev_handle
, endpoint
);}
4338 static int composite_abort_control(int sub_api
, struct usbi_transfer
*itransfer
)
4340 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4341 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4342 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4344 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4345 abort_control(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
);}
4347 static int composite_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
4349 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4350 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4351 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4353 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4354 abort_transfers(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
);}
4356 static int composite_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
4358 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4361 bool available
[SUB_API_MAX
];
4362 for (i
= 0; i
<SUB_API_MAX
; i
++) {
4363 available
[i
] = false;
4365 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4366 if ( (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
)
4367 && (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
) ) {
4368 available
[priv
->usb_interface
[i
].sub_api
] = true;
4371 for (i
=0; i
<SUB_API_MAX
; i
++) {
4373 r
= usb_api_backend
[USB_API_WINUSBX
].reset_device(i
, dev_handle
);
4374 if (r
!= LIBUSB_SUCCESS
) {
4379 return LIBUSB_SUCCESS
;
4382 static int composite_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
)
4384 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4385 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4386 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4388 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4389 copy_transfer_data(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
, io_size
);