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_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1174 dev
->bus_number
, dev
->device_address
, priv
->depth
, priv
->port
, device_id
);
1176 return LIBUSB_SUCCESS
;
1179 // Returns the api type, or 0 if not found/unsupported
1180 static void get_api_type(struct libusb_context
*ctx
, HDEVINFO
*dev_info
,
1181 SP_DEVINFO_DATA
*dev_info_data
, int *api
, int *sub_api
)
1183 // Precedence for filter drivers vs driver is in the order of this array
1184 struct driver_lookup lookup
[3] = {
1185 {"\0\0", SPDRP_SERVICE
, "driver"},
1186 {"\0\0", SPDRP_UPPERFILTERS
, "upper filter driver"},
1187 {"\0\0", SPDRP_LOWERFILTERS
, "lower filter driver"}
1189 DWORD size
, reg_type
;
1193 *api
= USB_API_UNSUPPORTED
;
1194 *sub_api
= SUB_API_NOTSET
;
1195 // Check the service & filter names to know the API we should use
1196 for (k
=0; k
<3; k
++) {
1197 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info
, dev_info_data
, lookup
[k
].reg_prop
,
1198 ®_type
, (BYTE
*)lookup
[k
].list
, MAX_KEY_LENGTH
, &size
)) {
1199 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1200 if (lookup
[k
].reg_prop
== SPDRP_SERVICE
) {
1201 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1202 lookup
[k
].list
[safe_strlen(lookup
[k
].list
)+1] = 0;
1204 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1205 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1206 // (currently ';'), so even if an unsuported one does, it's not an issue
1207 for (l
=0; (lookup
[k
].list
[l
] != 0) || (lookup
[k
].list
[l
+1] != 0); l
++) {
1208 if (lookup
[k
].list
[l
] == 0) {
1209 lookup
[k
].list
[l
] = LIST_SEPARATOR
;
1212 usbi_dbg("%s(s): %s", lookup
[k
].designation
, lookup
[k
].list
);
1214 if (GetLastError() != ERROR_INVALID_DATA
) {
1215 usbi_dbg("could not access %s: %s", lookup
[k
].designation
, windows_error_str(0));
1217 lookup
[k
].list
[0] = 0;
1221 for (i
=1; i
<USB_API_MAX
; i
++) {
1222 for (k
=0; k
<3; k
++) {
1223 j
= get_sub_api(lookup
[k
].list
, i
);
1225 usbi_dbg("matched %s name against %s API",
1226 lookup
[k
].designation
, (i
!=USB_API_WINUSBX
)?usb_api_backend
[i
].designation
:sub_api_name
[j
]);
1235 static int set_composite_interface(struct libusb_context
* ctx
, struct libusb_device
* dev
,
1236 char* dev_interface_path
, char* device_id
, int api
, int sub_api
)
1239 struct windows_device_priv
*priv
= _device_priv(dev
);
1240 int interface_number
;
1242 if (priv
->apib
->id
!= USB_API_COMPOSITE
) {
1243 usbi_err(ctx
, "program assertion failed: '%s' is not composite", device_id
);
1244 return LIBUSB_ERROR_NO_DEVICE
;
1247 // Because MI_## are not necessarily in sequential order (some composite
1248 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1249 // interface number from the path's MI value
1250 interface_number
= 0;
1251 for (i
=0; device_id
[i
] != 0; ) {
1252 if ( (device_id
[i
++] == 'M') && (device_id
[i
++] == 'I')
1253 && (device_id
[i
++] == '_') ) {
1254 interface_number
= (device_id
[i
++] - '0')*10;
1255 interface_number
+= device_id
[i
] - '0';
1260 if (device_id
[i
] == 0) {
1261 usbi_warn(ctx
, "failure to read interface number for %s. Using default value %d",
1262 device_id
, interface_number
);
1265 if (priv
->usb_interface
[interface_number
].path
!= NULL
) {
1266 if (api
== USB_API_HID
) {
1267 // HID devices can have multiple collections (COL##) for each MI_## interface
1268 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1269 interface_number
, device_id
);
1270 return LIBUSB_ERROR_ACCESS
;
1272 // In other cases, just use the latest data
1273 safe_free(priv
->usb_interface
[interface_number
].path
);
1276 usbi_dbg("interface[%d] = %s", interface_number
, dev_interface_path
);
1277 priv
->usb_interface
[interface_number
].path
= dev_interface_path
;
1278 priv
->usb_interface
[interface_number
].apib
= &usb_api_backend
[api
];
1279 priv
->usb_interface
[interface_number
].sub_api
= sub_api
;
1280 if ((api
== USB_API_HID
) && (priv
->hid
== NULL
)) {
1281 priv
->hid
= (struct hid_device_priv
*) calloc(1, sizeof(struct hid_device_priv
));
1282 if (priv
->hid
== NULL
)
1283 return LIBUSB_ERROR_NO_MEM
;
1286 return LIBUSB_SUCCESS
;
1289 static int set_hid_interface(struct libusb_context
* ctx
, struct libusb_device
* dev
,
1290 char* dev_interface_path
)
1293 struct windows_device_priv
*priv
= _device_priv(dev
);
1295 if (priv
->hid
== NULL
) {
1296 usbi_err(ctx
, "program assertion failed: parent is not HID");
1297 return LIBUSB_ERROR_NO_DEVICE
;
1299 if (priv
->hid
->nb_interfaces
== USB_MAXINTERFACES
) {
1300 usbi_err(ctx
, "program assertion failed: max USB interfaces reached for HID device");
1301 return LIBUSB_ERROR_NO_DEVICE
;
1303 for (i
=0; i
<priv
->hid
->nb_interfaces
; i
++) {
1304 if (safe_strcmp(priv
->usb_interface
[i
].path
, dev_interface_path
) == 0) {
1305 usbi_dbg("interface[%d] already set to %s", i
, dev_interface_path
);
1306 return LIBUSB_SUCCESS
;
1310 priv
->usb_interface
[priv
->hid
->nb_interfaces
].path
= dev_interface_path
;
1311 priv
->usb_interface
[priv
->hid
->nb_interfaces
].apib
= &usb_api_backend
[USB_API_HID
];
1312 usbi_dbg("interface[%d] = %s", priv
->hid
->nb_interfaces
, dev_interface_path
);
1313 priv
->hid
->nb_interfaces
++;
1314 return LIBUSB_SUCCESS
;
1318 * get_device_list: libusbx backend device enumeration function
1320 static int windows_get_device_list(struct libusb_context
*ctx
, struct discovered_devs
**_discdevs
)
1322 struct discovered_devs
*discdevs
;
1323 HDEVINFO dev_info
= { 0 };
1324 const char* usb_class
[] = {"USB", "NUSB3", "IUSB3"};
1325 SP_DEVINFO_DATA dev_info_data
= { 0 };
1326 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*dev_interface_details
= NULL
;
1328 #define MAX_ENUM_GUIDS 64
1329 const GUID
* guid
[MAX_ENUM_GUIDS
];
1335 int r
= LIBUSB_SUCCESS
;
1337 size_t class_index
= 0;
1338 unsigned int nb_guids
, pass
, i
, j
, ancestor
;
1339 char path
[MAX_PATH_LENGTH
];
1340 char strbuf
[MAX_PATH_LENGTH
];
1341 struct libusb_device
*dev
, *parent_dev
;
1342 struct windows_device_priv
*priv
, *parent_priv
;
1343 char* dev_interface_path
= NULL
;
1344 char* dev_id_path
= NULL
;
1345 unsigned long session_id
;
1346 DWORD size
, reg_type
, port_nr
, install_state
;
1348 WCHAR guid_string_w
[MAX_GUID_STRING_LENGTH
];
1351 // Keep a list of newly allocated devs to unref
1352 libusb_device
** unref_list
;
1353 unsigned int unref_size
= 64;
1354 unsigned int unref_cur
= 0;
1356 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1357 // PASS 2 : (re)enumerate HUBS
1358 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1359 // and list additional USB device interface GUIDs to explore
1360 // PASS 4 : (re)enumerate master USB devices that have a device interface
1361 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1362 // set the device interfaces.
1364 // Init the GUID table
1365 guid
[HCD_PASS
] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER
;
1366 guid
[HUB_PASS
] = &GUID_DEVINTERFACE_USB_HUB
;
1367 guid
[GEN_PASS
] = NULL
;
1368 guid
[DEV_PASS
] = &GUID_DEVINTERFACE_USB_DEVICE
;
1369 HidD_GetHidGuid(&hid_guid
);
1370 guid
[HID_PASS
] = &hid_guid
;
1371 nb_guids
= HID_PASS
+1;
1373 unref_list
= (libusb_device
**) calloc(unref_size
, sizeof(libusb_device
*));
1374 if (unref_list
== NULL
) {
1375 return LIBUSB_ERROR_NO_MEM
;
1378 for (pass
= 0; ((pass
< nb_guids
) && (r
== LIBUSB_SUCCESS
)); pass
++) {
1379 //#define ENUM_DEBUG
1381 const char *passname
[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1382 usbi_dbg("\n#### PROCESSING %ss %s", passname
[(pass
<=HID_PASS
)?pass
:HID_PASS
+1],
1383 (pass
!=GEN_PASS
)?guid_to_string(guid
[pass
]):"");
1385 for (i
= 0; ; i
++) {
1386 // safe loop: free up any (unprotected) dynamic resource
1387 // NB: this is always executed before breaking the loop
1388 safe_free(dev_interface_details
);
1389 safe_free(dev_interface_path
);
1390 safe_free(dev_id_path
);
1391 priv
= parent_priv
= NULL
;
1392 dev
= parent_dev
= NULL
;
1394 // Safe loop: end of loop conditions
1395 if (r
!= LIBUSB_SUCCESS
) {
1398 if ((pass
== HCD_PASS
) && (i
== UINT8_MAX
)) {
1399 usbi_warn(ctx
, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX
);
1402 if (pass
!= GEN_PASS
) {
1403 // Except for GEN, all passes deal with device interfaces
1404 dev_interface_details
= get_interface_details(ctx
, &dev_info
, &dev_info_data
, guid
[pass
], i
);
1405 if (dev_interface_details
== NULL
) {
1408 dev_interface_path
= sanitize_path(dev_interface_details
->DevicePath
);
1409 if (dev_interface_path
== NULL
) {
1410 usbi_warn(ctx
, "could not sanitize device interface path for '%s'", dev_interface_details
->DevicePath
);
1415 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1416 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1417 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1418 for (; class_index
< ARRAYSIZE(usb_class
); class_index
++) {
1419 if (get_devinfo_data(ctx
, &dev_info
, &dev_info_data
, usb_class
[class_index
], i
))
1423 if (class_index
>= ARRAYSIZE(usb_class
))
1427 // Read the Device ID path. This is what we'll use as UID
1428 // Note that if the device is plugged in a different port or hub, the Device ID changes
1429 if (CM_Get_Device_IDA(dev_info_data
.DevInst
, path
, sizeof(path
), 0) != CR_SUCCESS
) {
1430 usbi_warn(ctx
, "could not read the device id path for devinst %X, skipping",
1431 dev_info_data
.DevInst
);
1434 dev_id_path
= sanitize_path(path
);
1435 if (dev_id_path
== NULL
) {
1436 usbi_warn(ctx
, "could not sanitize device id path for devinst %X, skipping",
1437 dev_info_data
.DevInst
);
1441 usbi_dbg("PRO: %s", dev_id_path
);
1444 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1446 if ((pass
>= HUB_PASS
) && (pass
<= GEN_PASS
)) {
1447 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_ADDRESS
,
1448 ®_type
, (BYTE
*)&port_nr
, 4, &size
))
1450 usbi_warn(ctx
, "could not retrieve port number for device '%s', skipping: %s",
1451 dev_id_path
, windows_error_str(0));
1456 // Set API to use or get additional data from generic pass
1457 api
= USB_API_UNSUPPORTED
;
1458 sub_api
= SUB_API_NOTSET
;
1463 // We use the GEN pass to detect driverless devices...
1464 size
= sizeof(strbuf
);
1465 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_DRIVER
,
1466 ®_type
, (BYTE
*)strbuf
, size
, &size
)) {
1467 usbi_info(ctx
, "The following device has no driver: '%s'", dev_id_path
);
1468 usbi_info(ctx
, "libusbx will not be able to access it.");
1470 // ...and to add the additional device interface GUIDs
1471 key
= pSetupDiOpenDevRegKey(dev_info
, &dev_info_data
, DICS_FLAG_GLOBAL
, 0, DIREG_DEV
, KEY_READ
);
1472 if (key
!= INVALID_HANDLE_VALUE
) {
1473 size
= sizeof(guid_string_w
);
1474 s
= pRegQueryValueExW(key
, L
"DeviceInterfaceGUIDs", NULL
, ®_type
,
1475 (BYTE
*)guid_string_w
, &size
);
1477 if (s
== ERROR_SUCCESS
) {
1478 if (nb_guids
>= MAX_ENUM_GUIDS
) {
1479 // If this assert is ever reported, grow a GUID table dynamically
1480 usbi_err(ctx
, "program assertion failed: too many GUIDs");
1481 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW
);
1483 if_guid
= (GUID
*) calloc(1, sizeof(GUID
));
1484 pCLSIDFromString(guid_string_w
, if_guid
);
1485 guid
[nb_guids
++] = if_guid
;
1486 usbi_dbg("extra GUID: %s", guid_to_string(if_guid
));
1494 // Get the API type (after checking that the driver installation is OK)
1495 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_INSTALL_STATE
,
1496 ®_type
, (BYTE
*)&install_state
, 4, &size
))
1498 usbi_warn(ctx
, "could not detect installation state of driver for '%s': %s",
1499 dev_id_path
, windows_error_str(0));
1500 } else if (install_state
!= 0) {
1501 usbi_warn(ctx
, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1502 dev_id_path
, install_state
);
1505 get_api_type(ctx
, &dev_info
, &dev_info_data
, &api
, &sub_api
);
1509 // Find parent device (for the passes that need it)
1516 // Go through the ancestors until we see a face we recognize
1518 for (ancestor
= 1; parent_dev
== NULL
; ancestor
++) {
1519 session_id
= get_ancestor_session_id(dev_info_data
.DevInst
, ancestor
);
1520 if (session_id
== 0) {
1523 parent_dev
= usbi_get_device_by_session_id(ctx
, session_id
);
1525 if (parent_dev
== NULL
) {
1526 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path
);
1529 parent_priv
= _device_priv(parent_dev
);
1530 // virtual USB devices are also listed during GEN - don't process these yet
1531 if ( (pass
== GEN_PASS
) && (parent_priv
->apib
->id
!= USB_API_HUB
) ) {
1537 // Create new or match existing device, using the (hashed) device_id as session id
1538 if (pass
<= DEV_PASS
) { // For subsequent passes, we'll lookup the parent
1539 // These are the passes that create "new" devices
1540 session_id
= htab_hash(dev_id_path
);
1541 dev
= usbi_get_device_by_session_id(ctx
, session_id
);
1543 if (pass
== DEV_PASS
) {
1544 // This can occur if the OS only reports a newly plugged device after we started enum
1545 usbi_warn(ctx
, "'%s' was only detected in late pass (newly connected device?)"
1546 " - ignoring", dev_id_path
);
1549 usbi_dbg("allocating new device for session [%X]", session_id
);
1550 if ((dev
= usbi_alloc_device(ctx
, session_id
)) == NULL
) {
1551 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1553 windows_device_priv_init(dev
);
1554 // Keep track of devices that need unref
1555 unref_list
[unref_cur
++] = dev
;
1556 if (unref_cur
>= unref_size
) {
1558 unref_list
= usbi_reallocf(unref_list
, unref_size
*sizeof(libusb_device
*));
1559 if (unref_list
== NULL
) {
1560 usbi_err(ctx
, "could not realloc list for unref - aborting.");
1561 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1565 usbi_dbg("found existing device for session [%X] (%d.%d)",
1566 session_id
, dev
->bus_number
, dev
->device_address
);
1568 priv
= _device_priv(dev
);
1574 dev
->bus_number
= (uint8_t)(i
+ 1); // bus 0 is reserved for disconnected
1575 dev
->device_address
= 0;
1576 dev
->num_configurations
= 0;
1577 priv
->apib
= &usb_api_backend
[USB_API_HUB
];
1578 priv
->sub_api
= SUB_API_NOTSET
;
1579 priv
->depth
= UINT8_MAX
; // Overflow to 0 for HCD Hubs
1580 priv
->path
= dev_interface_path
; dev_interface_path
= NULL
;
1584 // If the device has already been setup, don't do it again
1585 if (priv
->path
!= NULL
)
1587 // Take care of API initialization
1588 priv
->path
= dev_interface_path
; dev_interface_path
= NULL
;
1589 priv
->apib
= &usb_api_backend
[api
];
1590 priv
->sub_api
= sub_api
;
1592 case USB_API_COMPOSITE
:
1596 priv
->hid
= calloc(1, sizeof(struct hid_device_priv
));
1597 if (priv
->hid
== NULL
) {
1598 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1600 priv
->hid
->nb_interfaces
= 0;
1603 // For other devices, the first interface is the same as the device
1604 priv
->usb_interface
[0].path
= (char*) calloc(safe_strlen(priv
->path
)+1, 1);
1605 if (priv
->usb_interface
[0].path
!= NULL
) {
1606 safe_strcpy(priv
->usb_interface
[0].path
, safe_strlen(priv
->path
)+1, priv
->path
);
1608 usbi_warn(ctx
, "could not duplicate interface path '%s'", priv
->path
);
1610 // The following is needed if we want API calls to work for both simple
1611 // and composite devices.
1612 for(j
=0; j
<USB_MAXINTERFACES
; j
++) {
1613 priv
->usb_interface
[j
].apib
= &usb_api_backend
[api
];
1619 r
= init_device(dev
, parent_dev
, (uint8_t)port_nr
, dev_id_path
, dev_info_data
.DevInst
);
1620 if (r
== LIBUSB_SUCCESS
) {
1621 // Append device to the list of discovered devices
1622 discdevs
= discovered_devs_append(*_discdevs
, dev
);
1624 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1626 *_discdevs
= discdevs
;
1627 } else if (r
== LIBUSB_ERROR_NO_DEVICE
) {
1628 // This can occur if the device was disconnected but Windows hasn't
1629 // refreshed its enumeration yet - in that case, we ignore the device
1633 default: // HID_PASS and later
1634 if (parent_priv
->apib
->id
== USB_API_HID
) {
1635 usbi_dbg("setting HID interface for [%lX]:", parent_dev
->session_data
);
1636 r
= set_hid_interface(ctx
, parent_dev
, dev_interface_path
);
1637 if (r
!= LIBUSB_SUCCESS
) LOOP_BREAK(r
);
1638 dev_interface_path
= NULL
;
1639 } else if (parent_priv
->apib
->id
== USB_API_COMPOSITE
) {
1640 usbi_dbg("setting composite interface for [%lX]:", parent_dev
->session_data
);
1641 switch (set_composite_interface(ctx
, parent_dev
, dev_interface_path
, dev_id_path
, api
, sub_api
)) {
1642 case LIBUSB_SUCCESS
:
1643 dev_interface_path
= NULL
;
1645 case LIBUSB_ERROR_ACCESS
:
1646 // interface has already been set => make sure dev_interface_path is freed then
1658 // Free any additional GUIDs
1659 for (pass
= HID_PASS
+1; pass
< nb_guids
; pass
++) {
1660 safe_free(guid
[pass
]);
1663 // Unref newly allocated devs
1664 for (i
=0; i
<unref_cur
; i
++) {
1665 safe_unref_device(unref_list
[i
]);
1667 safe_free(unref_list
);
1673 * exit: libusbx backend deinitialization function
1675 static void windows_exit(void)
1679 char sem_name
[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1681 sprintf(sem_name
, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1682 semaphore
= CreateSemaphoreA(NULL
, 1, 1, sem_name
);
1683 if (semaphore
== NULL
) {
1687 // A successful wait brings our semaphore count to 0 (unsignaled)
1688 // => any concurent wait stalls until the semaphore release
1689 if (WaitForSingleObject(semaphore
, INFINITE
) != WAIT_OBJECT_0
) {
1690 CloseHandle(semaphore
);
1694 // Only works if exits and inits are balanced exactly
1695 if (--concurrent_usage
< 0) { // Last exit
1696 for (i
=0; i
<USB_API_MAX
; i
++) {
1697 usb_api_backend
[i
].exit(SUB_API_NOTSET
);
1702 SetEvent(timer_request
[1]); // actually the signal to quit the thread.
1703 if (WAIT_OBJECT_0
!= WaitForSingleObject(timer_thread
, INFINITE
)) {
1704 usbi_dbg("could not wait for timer thread to quit");
1705 TerminateThread(timer_thread
, 1);
1707 CloseHandle(timer_thread
);
1708 timer_thread
= NULL
;
1710 for (i
= 0; i
< 2; i
++) {
1711 if (timer_request
[i
]) {
1712 CloseHandle(timer_request
[i
]);
1713 timer_request
[i
] = NULL
;
1716 if (timer_response
) {
1717 CloseHandle(timer_response
);
1718 timer_response
= NULL
;
1721 CloseHandle(timer_mutex
);
1727 ReleaseSemaphore(semaphore
, 1, NULL
); // increase count back to 1
1728 CloseHandle(semaphore
);
1731 static int windows_get_device_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, int *host_endian
)
1733 struct windows_device_priv
*priv
= _device_priv(dev
);
1735 memcpy(buffer
, &(priv
->dev_descriptor
), DEVICE_DESC_LENGTH
);
1738 return LIBUSB_SUCCESS
;
1741 static int windows_get_config_descriptor(struct libusb_device
*dev
, uint8_t config_index
, unsigned char *buffer
, size_t len
, int *host_endian
)
1743 struct windows_device_priv
*priv
= _device_priv(dev
);
1744 PUSB_CONFIGURATION_DESCRIPTOR config_header
;
1747 // config index is zero based
1748 if (config_index
>= dev
->num_configurations
)
1749 return LIBUSB_ERROR_INVALID_PARAM
;
1751 if ((priv
->config_descriptor
== NULL
) || (priv
->config_descriptor
[config_index
] == NULL
))
1752 return LIBUSB_ERROR_NOT_FOUND
;
1754 config_header
= (PUSB_CONFIGURATION_DESCRIPTOR
)priv
->config_descriptor
[config_index
];
1756 size
= min(config_header
->wTotalLength
, len
);
1757 memcpy(buffer
, priv
->config_descriptor
[config_index
], size
);
1759 return LIBUSB_SUCCESS
;
1763 * return the cached copy of the active config descriptor
1765 static int windows_get_active_config_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, size_t len
, int *host_endian
)
1767 struct windows_device_priv
*priv
= _device_priv(dev
);
1769 if (priv
->active_config
== 0)
1770 return LIBUSB_ERROR_NOT_FOUND
;
1772 // config index is zero based
1773 return windows_get_config_descriptor(dev
, (uint8_t)(priv
->active_config
-1), buffer
, len
, host_endian
);
1776 static int windows_open(struct libusb_device_handle
*dev_handle
)
1778 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1779 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
1781 if (priv
->apib
== NULL
) {
1782 usbi_err(ctx
, "program assertion failed - device is not initialized");
1783 return LIBUSB_ERROR_NO_DEVICE
;
1786 return priv
->apib
->open(SUB_API_NOTSET
, dev_handle
);
1789 static void windows_close(struct libusb_device_handle
*dev_handle
)
1791 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1793 priv
->apib
->close(SUB_API_NOTSET
, dev_handle
);
1796 static int windows_get_configuration(struct libusb_device_handle
*dev_handle
, int *config
)
1798 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1800 if (priv
->active_config
== 0) {
1802 return LIBUSB_ERROR_NOT_FOUND
;
1805 *config
= priv
->active_config
;
1806 return LIBUSB_SUCCESS
;
1810 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1811 * does not currently expose a service that allows higher-level drivers to set
1812 * the configuration."
1814 static int windows_set_configuration(struct libusb_device_handle
*dev_handle
, int config
)
1816 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1817 int r
= LIBUSB_SUCCESS
;
1819 if (config
>= USB_MAXCONFIG
)
1820 return LIBUSB_ERROR_INVALID_PARAM
;
1822 r
= libusb_control_transfer(dev_handle
, LIBUSB_ENDPOINT_OUT
|
1823 LIBUSB_REQUEST_TYPE_STANDARD
| LIBUSB_RECIPIENT_DEVICE
,
1824 LIBUSB_REQUEST_SET_CONFIGURATION
, (uint16_t)config
,
1827 if (r
== LIBUSB_SUCCESS
) {
1828 priv
->active_config
= (uint8_t)config
;
1833 static int windows_claim_interface(struct libusb_device_handle
*dev_handle
, int iface
)
1835 int r
= LIBUSB_SUCCESS
;
1836 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1838 if (iface
>= USB_MAXINTERFACES
)
1839 return LIBUSB_ERROR_INVALID_PARAM
;
1841 safe_free(priv
->usb_interface
[iface
].endpoint
);
1842 priv
->usb_interface
[iface
].nb_endpoints
= 0;
1844 r
= priv
->apib
->claim_interface(SUB_API_NOTSET
, dev_handle
, iface
);
1846 if (r
== LIBUSB_SUCCESS
) {
1847 r
= windows_assign_endpoints(dev_handle
, iface
, 0);
1853 static int windows_set_interface_altsetting(struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
1855 int r
= LIBUSB_SUCCESS
;
1856 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1858 safe_free(priv
->usb_interface
[iface
].endpoint
);
1859 priv
->usb_interface
[iface
].nb_endpoints
= 0;
1861 r
= priv
->apib
->set_interface_altsetting(SUB_API_NOTSET
, dev_handle
, iface
, altsetting
);
1863 if (r
== LIBUSB_SUCCESS
) {
1864 r
= windows_assign_endpoints(dev_handle
, iface
, altsetting
);
1870 static int windows_release_interface(struct libusb_device_handle
*dev_handle
, int iface
)
1872 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1874 return priv
->apib
->release_interface(SUB_API_NOTSET
, dev_handle
, iface
);
1877 static int windows_clear_halt(struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
1879 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1880 return priv
->apib
->clear_halt(SUB_API_NOTSET
, dev_handle
, endpoint
);
1883 static int windows_reset_device(struct libusb_device_handle
*dev_handle
)
1885 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1886 return priv
->apib
->reset_device(SUB_API_NOTSET
, dev_handle
);
1889 // The 3 functions below are unlikely to ever get supported on Windows
1890 static int windows_kernel_driver_active(struct libusb_device_handle
*dev_handle
, int iface
)
1892 return LIBUSB_ERROR_NOT_SUPPORTED
;
1895 static int windows_attach_kernel_driver(struct libusb_device_handle
*dev_handle
, int iface
)
1897 return LIBUSB_ERROR_NOT_SUPPORTED
;
1900 static int windows_detach_kernel_driver(struct libusb_device_handle
*dev_handle
, int iface
)
1902 return LIBUSB_ERROR_NOT_SUPPORTED
;
1905 static void windows_destroy_device(struct libusb_device
*dev
)
1907 windows_device_priv_release(dev
);
1910 static void windows_clear_transfer_priv(struct usbi_transfer
*itransfer
)
1912 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1914 usbi_free_fd(transfer_priv
->pollable_fd
.fd
);
1915 safe_free(transfer_priv
->hid_buffer
);
1916 // When auto claim is in use, attempt to release the auto-claimed interface
1917 auto_release(itransfer
);
1920 static int submit_bulk_transfer(struct usbi_transfer
*itransfer
)
1922 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1923 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1924 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1925 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1928 r
= priv
->apib
->submit_bulk_transfer(SUB_API_NOTSET
, itransfer
);
1929 if (r
!= LIBUSB_SUCCESS
) {
1933 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
,
1934 (short)(IS_XFERIN(transfer
) ? POLLIN
: POLLOUT
));
1936 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1937 return LIBUSB_SUCCESS
;
1940 static int submit_iso_transfer(struct usbi_transfer
*itransfer
)
1942 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1943 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1944 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1945 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1948 r
= priv
->apib
->submit_iso_transfer(SUB_API_NOTSET
, itransfer
);
1949 if (r
!= LIBUSB_SUCCESS
) {
1953 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
,
1954 (short)(IS_XFERIN(transfer
) ? POLLIN
: POLLOUT
));
1956 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1957 return LIBUSB_SUCCESS
;
1960 static int submit_control_transfer(struct usbi_transfer
*itransfer
)
1962 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1963 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1964 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1965 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1968 r
= priv
->apib
->submit_control_transfer(SUB_API_NOTSET
, itransfer
);
1969 if (r
!= LIBUSB_SUCCESS
) {
1973 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
, POLLIN
);
1975 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1976 return LIBUSB_SUCCESS
;
1980 static int windows_submit_transfer(struct usbi_transfer
*itransfer
)
1982 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1984 switch (transfer
->type
) {
1985 case LIBUSB_TRANSFER_TYPE_CONTROL
:
1986 return submit_control_transfer(itransfer
);
1987 case LIBUSB_TRANSFER_TYPE_BULK
:
1988 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
1989 if (IS_XFEROUT(transfer
) &&
1990 transfer
->flags
& LIBUSB_TRANSFER_ADD_ZERO_PACKET
)
1991 return LIBUSB_ERROR_NOT_SUPPORTED
;
1992 return submit_bulk_transfer(itransfer
);
1993 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
1994 return submit_iso_transfer(itransfer
);
1996 usbi_err(TRANSFER_CTX(transfer
), "unknown endpoint type %d", transfer
->type
);
1997 return LIBUSB_ERROR_INVALID_PARAM
;
2001 static int windows_abort_control(struct usbi_transfer
*itransfer
)
2003 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2004 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2006 return priv
->apib
->abort_control(SUB_API_NOTSET
, itransfer
);
2009 static int windows_abort_transfers(struct usbi_transfer
*itransfer
)
2011 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2012 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2014 return priv
->apib
->abort_transfers(SUB_API_NOTSET
, itransfer
);
2017 static int windows_cancel_transfer(struct usbi_transfer
*itransfer
)
2019 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2021 switch (transfer
->type
) {
2022 case LIBUSB_TRANSFER_TYPE_CONTROL
:
2023 return windows_abort_control(itransfer
);
2024 case LIBUSB_TRANSFER_TYPE_BULK
:
2025 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
2026 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
2027 return windows_abort_transfers(itransfer
);
2029 usbi_err(ITRANSFER_CTX(itransfer
), "unknown endpoint type %d", transfer
->type
);
2030 return LIBUSB_ERROR_INVALID_PARAM
;
2034 static void windows_transfer_callback(struct usbi_transfer
*itransfer
, uint32_t io_result
, uint32_t io_size
)
2036 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2037 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2038 int status
, istatus
;
2040 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result
, io_size
);
2044 status
= priv
->apib
->copy_transfer_data(SUB_API_NOTSET
, itransfer
, io_size
);
2046 case ERROR_GEN_FAILURE
:
2047 usbi_dbg("detected endpoint stall");
2048 status
= LIBUSB_TRANSFER_STALL
;
2050 case ERROR_SEM_TIMEOUT
:
2051 usbi_dbg("detected semaphore timeout");
2052 status
= LIBUSB_TRANSFER_TIMED_OUT
;
2054 case ERROR_OPERATION_ABORTED
:
2055 istatus
= priv
->apib
->copy_transfer_data(SUB_API_NOTSET
, itransfer
, io_size
);
2056 if (istatus
!= LIBUSB_TRANSFER_COMPLETED
) {
2057 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus
);
2059 if (itransfer
->flags
& USBI_TRANSFER_TIMED_OUT
) {
2060 usbi_dbg("detected timeout");
2061 status
= LIBUSB_TRANSFER_TIMED_OUT
;
2063 usbi_dbg("detected operation aborted");
2064 status
= LIBUSB_TRANSFER_CANCELLED
;
2068 usbi_err(ITRANSFER_CTX(itransfer
), "detected I/O error %d: %s", io_result
, windows_error_str(0));
2069 status
= LIBUSB_TRANSFER_ERROR
;
2072 windows_clear_transfer_priv(itransfer
); // Cancel polling
2073 usbi_handle_transfer_completion(itransfer
, (enum libusb_transfer_status
)status
);
2076 static void windows_handle_callback (struct usbi_transfer
*itransfer
, uint32_t io_result
, uint32_t io_size
)
2078 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2080 switch (transfer
->type
) {
2081 case LIBUSB_TRANSFER_TYPE_CONTROL
:
2082 case LIBUSB_TRANSFER_TYPE_BULK
:
2083 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
2084 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
2085 windows_transfer_callback (itransfer
, io_result
, io_size
);
2088 usbi_err(ITRANSFER_CTX(itransfer
), "unknown endpoint type %d", transfer
->type
);
2092 static int windows_handle_events(struct libusb_context
*ctx
, struct pollfd
*fds
, POLL_NFDS_TYPE nfds
, int num_ready
)
2094 struct windows_transfer_priv
* transfer_priv
= NULL
;
2095 POLL_NFDS_TYPE i
= 0;
2097 struct usbi_transfer
*transfer
;
2098 DWORD io_size
, io_result
;
2100 usbi_mutex_lock(&ctx
->open_devs_lock
);
2101 for (i
= 0; i
< nfds
&& num_ready
> 0; i
++) {
2103 usbi_dbg("checking fd %d with revents = %04x", fds
[i
].fd
, fds
[i
].revents
);
2105 if (!fds
[i
].revents
) {
2111 // Because a Windows OVERLAPPED is used for poll emulation,
2112 // a pollable fd is created and stored with each transfer
2113 usbi_mutex_lock(&ctx
->flying_transfers_lock
);
2114 list_for_each_entry(transfer
, &ctx
->flying_transfers
, list
, struct usbi_transfer
) {
2115 transfer_priv
= usbi_transfer_get_os_priv(transfer
);
2116 if (transfer_priv
->pollable_fd
.fd
== fds
[i
].fd
) {
2121 usbi_mutex_unlock(&ctx
->flying_transfers_lock
);
2124 // Handle async requests that completed synchronously first
2125 if (HasOverlappedIoCompletedSync(transfer_priv
->pollable_fd
.overlapped
)) {
2126 io_result
= NO_ERROR
;
2127 io_size
= (DWORD
)transfer_priv
->pollable_fd
.overlapped
->InternalHigh
;
2128 // Regular async overlapped
2129 } else if (GetOverlappedResult(transfer_priv
->pollable_fd
.handle
,
2130 transfer_priv
->pollable_fd
.overlapped
, &io_size
, false)) {
2131 io_result
= NO_ERROR
;
2133 io_result
= GetLastError();
2135 usbi_remove_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
);
2136 // let handle_callback free the event using the transfer wfd
2137 // If you don't use the transfer wfd, you run a risk of trying to free a
2138 // newly allocated wfd that took the place of the one from the transfer.
2139 windows_handle_callback(transfer
, io_result
, io_size
);
2141 usbi_err(ctx
, "could not find a matching transfer for fd %x", fds
[i
]);
2142 return LIBUSB_ERROR_NOT_FOUND
;
2146 usbi_mutex_unlock(&ctx
->open_devs_lock
);
2147 return LIBUSB_SUCCESS
;
2151 * Monotonic and real time functions
2153 unsigned __stdcall
windows_clock_gettime_threaded(void* param
)
2155 LARGE_INTEGER hires_counter
, li_frequency
;
2159 // Init - find out if we have access to a monotonic (hires) timer
2160 if (!QueryPerformanceFrequency(&li_frequency
)) {
2161 usbi_dbg("no hires timer available on this platform");
2162 hires_frequency
= 0;
2163 hires_ticks_to_ps
= UINT64_C(0);
2165 hires_frequency
= li_frequency
.QuadPart
;
2166 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2167 // to picoseconds to compute the tv_nsecs part in clock_gettime
2168 hires_ticks_to_ps
= UINT64_C(1000000000000) / hires_frequency
;
2169 usbi_dbg("hires timer available (Frequency: %"PRIu64
" Hz)", hires_frequency
);
2172 // Main loop - wait for requests
2174 timer_index
= WaitForMultipleObjects(2, timer_request
, FALSE
, INFINITE
) - WAIT_OBJECT_0
;
2175 if ( (timer_index
!= 0) && (timer_index
!= 1) ) {
2176 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2179 if (request_count
[timer_index
] == 0) {
2180 // Request already handled
2181 ResetEvent(timer_request
[timer_index
]);
2182 // There's still a possiblity that a thread sends a request between the
2183 // time we test request_count[] == 0 and we reset the event, in which case
2184 // the request would be ignored. The simple solution to that is to test
2185 // request_count again and process requests if non zero.
2186 if (request_count
[timer_index
] == 0)
2189 switch (timer_index
) {
2191 WaitForSingleObject(timer_mutex
, INFINITE
);
2192 // Requests to this thread are for hires always
2193 if (QueryPerformanceCounter(&hires_counter
) != 0) {
2194 timer_tp
.tv_sec
= (long)(hires_counter
.QuadPart
/ hires_frequency
);
2195 timer_tp
.tv_nsec
= (long)(((hires_counter
.QuadPart
% hires_frequency
)/1000) * hires_ticks_to_ps
);
2197 // Fallback to real-time if we can't get monotonic value
2198 // Note that real-time clock does not wait on the mutex or this thread.
2199 windows_clock_gettime(USBI_CLOCK_REALTIME
, &timer_tp
);
2201 ReleaseMutex(timer_mutex
);
2203 nb_responses
= InterlockedExchange((LONG
*)&request_count
[0], 0);
2205 && (ReleaseSemaphore(timer_response
, nb_responses
, NULL
) == 0) ) {
2206 usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0));
2209 case 1: // time to quit
2210 usbi_dbg("timer thread quitting");
2216 static int windows_clock_gettime(int clk_id
, struct timespec
*tp
)
2219 ULARGE_INTEGER rtime
;
2222 case USBI_CLOCK_MONOTONIC
:
2223 if (hires_frequency
!= 0) {
2225 InterlockedIncrement((LONG
*)&request_count
[0]);
2226 SetEvent(timer_request
[0]);
2227 r
= WaitForSingleObject(timer_response
, TIMER_REQUEST_RETRY_MS
);
2230 WaitForSingleObject(timer_mutex
, INFINITE
);
2232 ReleaseMutex(timer_mutex
);
2233 return LIBUSB_SUCCESS
;
2235 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2236 break; // Retry until successful
2238 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2239 return LIBUSB_ERROR_OTHER
;
2243 // Fall through and return real-time if monotonic was not detected @ timer init
2244 case USBI_CLOCK_REALTIME
:
2245 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2246 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2247 // Note however that our resolution is bounded by the Windows system time
2248 // functions and is at best of the order of 1 ms (or, usually, worse)
2249 GetSystemTimeAsFileTime(&filetime
);
2250 rtime
.LowPart
= filetime
.dwLowDateTime
;
2251 rtime
.HighPart
= filetime
.dwHighDateTime
;
2252 rtime
.QuadPart
-= epoch_time
;
2253 tp
->tv_sec
= (long)(rtime
.QuadPart
/ 10000000);
2254 tp
->tv_nsec
= (long)((rtime
.QuadPart
% 10000000)*100);
2255 return LIBUSB_SUCCESS
;
2257 return LIBUSB_ERROR_INVALID_PARAM
;
2262 // NB: MSVC6 does not support named initializers.
2263 const struct usbi_os_backend windows_backend
= {
2265 USBI_CAP_HAS_HID_ACCESS
,
2269 windows_get_device_list
,
2273 windows_get_device_descriptor
,
2274 windows_get_active_config_descriptor
,
2275 windows_get_config_descriptor
,
2277 windows_get_configuration
,
2278 windows_set_configuration
,
2279 windows_claim_interface
,
2280 windows_release_interface
,
2282 windows_set_interface_altsetting
,
2284 windows_reset_device
,
2286 windows_kernel_driver_active
,
2287 windows_detach_kernel_driver
,
2288 windows_attach_kernel_driver
,
2290 windows_destroy_device
,
2292 windows_submit_transfer
,
2293 windows_cancel_transfer
,
2294 windows_clear_transfer_priv
,
2296 windows_handle_events
,
2298 windows_clock_gettime
,
2299 #if defined(USBI_TIMERFD_AVAILABLE)
2302 sizeof(struct windows_device_priv
),
2303 sizeof(struct windows_device_handle_priv
),
2304 sizeof(struct windows_transfer_priv
),
2312 static int unsupported_init(int sub_api
, struct libusb_context
*ctx
) {
2313 return LIBUSB_SUCCESS
;
2315 static int unsupported_exit(int sub_api
) {
2316 return LIBUSB_SUCCESS
;
2318 static int unsupported_open(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2319 PRINT_UNSUPPORTED_API(open
);
2321 static void unsupported_close(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2322 usbi_dbg("unsupported API call for 'close'");
2324 static int unsupported_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2325 PRINT_UNSUPPORTED_API(configure_endpoints
);
2327 static int unsupported_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2328 PRINT_UNSUPPORTED_API(claim_interface
);
2330 static int unsupported_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
) {
2331 PRINT_UNSUPPORTED_API(set_interface_altsetting
);
2333 static int unsupported_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2334 PRINT_UNSUPPORTED_API(release_interface
);
2336 static int unsupported_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
) {
2337 PRINT_UNSUPPORTED_API(clear_halt
);
2339 static int unsupported_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2340 PRINT_UNSUPPORTED_API(reset_device
);
2342 static int unsupported_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2343 PRINT_UNSUPPORTED_API(submit_bulk_transfer
);
2345 static int unsupported_submit_iso_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2346 PRINT_UNSUPPORTED_API(submit_iso_transfer
);
2348 static int unsupported_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2349 PRINT_UNSUPPORTED_API(submit_control_transfer
);
2351 static int unsupported_abort_control(int sub_api
, struct usbi_transfer
*itransfer
) {
2352 PRINT_UNSUPPORTED_API(abort_control
);
2354 static int unsupported_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
) {
2355 PRINT_UNSUPPORTED_API(abort_transfers
);
2357 static int unsupported_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
) {
2358 PRINT_UNSUPPORTED_API(copy_transfer_data
);
2360 static int common_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2361 return LIBUSB_SUCCESS
;
2363 // These names must be uppercase
2364 const char* hub_driver_names
[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2365 const char* composite_driver_names
[] = {"USBCCGP"};
2366 const char* winusbx_driver_names
[] = WINUSBX_DRV_NAMES
;
2367 const char* hid_driver_names
[] = {"HIDUSB", "MOUHID", "KBDHID"};
2368 const struct windows_usb_api_backend usb_api_backend
[USB_API_MAX
] = {
2370 USB_API_UNSUPPORTED
,
2378 unsupported_configure_endpoints
,
2379 unsupported_claim_interface
,
2380 unsupported_set_interface_altsetting
,
2381 unsupported_release_interface
,
2382 unsupported_clear_halt
,
2383 unsupported_reset_device
,
2384 unsupported_submit_bulk_transfer
,
2385 unsupported_submit_iso_transfer
,
2386 unsupported_submit_control_transfer
,
2387 unsupported_abort_control
,
2388 unsupported_abort_transfers
,
2389 unsupported_copy_transfer_data
,
2394 ARRAYSIZE(hub_driver_names
),
2399 unsupported_configure_endpoints
,
2400 unsupported_claim_interface
,
2401 unsupported_set_interface_altsetting
,
2402 unsupported_release_interface
,
2403 unsupported_clear_halt
,
2404 unsupported_reset_device
,
2405 unsupported_submit_bulk_transfer
,
2406 unsupported_submit_iso_transfer
,
2407 unsupported_submit_control_transfer
,
2408 unsupported_abort_control
,
2409 unsupported_abort_transfers
,
2410 unsupported_copy_transfer_data
,
2414 composite_driver_names
,
2415 ARRAYSIZE(composite_driver_names
),
2420 common_configure_endpoints
,
2421 composite_claim_interface
,
2422 composite_set_interface_altsetting
,
2423 composite_release_interface
,
2424 composite_clear_halt
,
2425 composite_reset_device
,
2426 composite_submit_bulk_transfer
,
2427 composite_submit_iso_transfer
,
2428 composite_submit_control_transfer
,
2429 composite_abort_control
,
2430 composite_abort_transfers
,
2431 composite_copy_transfer_data
,
2435 winusbx_driver_names
,
2436 ARRAYSIZE(winusbx_driver_names
),
2441 winusbx_configure_endpoints
,
2442 winusbx_claim_interface
,
2443 winusbx_set_interface_altsetting
,
2444 winusbx_release_interface
,
2446 winusbx_reset_device
,
2447 winusbx_submit_bulk_transfer
,
2448 unsupported_submit_iso_transfer
,
2449 winusbx_submit_control_transfer
,
2450 winusbx_abort_control
,
2451 winusbx_abort_transfers
,
2452 winusbx_copy_transfer_data
,
2457 ARRAYSIZE(hid_driver_names
),
2462 common_configure_endpoints
,
2463 hid_claim_interface
,
2464 hid_set_interface_altsetting
,
2465 hid_release_interface
,
2468 hid_submit_bulk_transfer
,
2469 unsupported_submit_iso_transfer
,
2470 hid_submit_control_transfer
,
2471 hid_abort_transfers
,
2472 hid_abort_transfers
,
2473 hid_copy_transfer_data
,
2479 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2481 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2482 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2484 static int winusbx_init(int sub_api
, struct libusb_context
*ctx
)
2487 bool native_winusb
= false;
2489 KLIB_VERSION LibK_Version
;
2490 LibK_GetProcAddress_t pLibK_GetProcAddress
= NULL
;
2491 LibK_GetVersion_t pLibK_GetVersion
= NULL
;
2493 h
= GetModuleHandleA("libusbK");
2495 h
= LoadLibraryA("libusbK");
2498 usbi_info(ctx
, "libusbK DLL is not available, will use native WinUSB");
2499 h
= GetModuleHandleA("WinUSB");
2501 h
= LoadLibraryA("WinUSB");
2503 usbi_warn(ctx
, "WinUSB DLL is not available either,\n"
2504 "you will not be able to access devices outside of enumeration");
2505 return LIBUSB_ERROR_NOT_FOUND
;
2508 usbi_dbg("using libusbK DLL for universal access");
2509 pLibK_GetVersion
= (LibK_GetVersion_t
) GetProcAddress(h
, "LibK_GetVersion");
2510 if (pLibK_GetVersion
!= NULL
) {
2511 pLibK_GetVersion(&LibK_Version
);
2512 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version
.Major
, LibK_Version
.Minor
,
2513 LibK_Version
.Micro
, LibK_Version
.Nano
);
2515 pLibK_GetProcAddress
= (LibK_GetProcAddress_t
) GetProcAddress(h
, "LibK_GetProcAddress");
2516 if (pLibK_GetProcAddress
== NULL
) {
2517 usbi_err(ctx
, "LibK_GetProcAddress() not found in libusbK DLL");
2518 return LIBUSB_ERROR_NOT_FOUND
;
2521 native_winusb
= (pLibK_GetProcAddress
== NULL
);
2522 for (i
=SUB_API_LIBUSBK
; i
<SUB_API_MAX
; i
++) {
2523 WinUSBX_Set(AbortPipe
);
2524 WinUSBX_Set(ControlTransfer
);
2525 WinUSBX_Set(FlushPipe
);
2527 WinUSBX_Set(GetAssociatedInterface
);
2528 WinUSBX_Set(GetCurrentAlternateSetting
);
2529 WinUSBX_Set(GetDescriptor
);
2530 WinUSBX_Set(GetOverlappedResult
);
2531 WinUSBX_Set(GetPipePolicy
);
2532 WinUSBX_Set(GetPowerPolicy
);
2533 WinUSBX_Set(Initialize
);
2534 WinUSBX_Set(QueryDeviceInformation
);
2535 WinUSBX_Set(QueryInterfaceSettings
);
2536 WinUSBX_Set(QueryPipe
);
2537 WinUSBX_Set(ReadPipe
);
2538 WinUSBX_Set(ResetPipe
);
2539 WinUSBX_Set(SetCurrentAlternateSetting
);
2540 WinUSBX_Set(SetPipePolicy
);
2541 WinUSBX_Set(SetPowerPolicy
);
2542 WinUSBX_Set(WritePipe
);
2543 if (!native_winusb
) {
2544 WinUSBX_Set(ResetDevice
);
2546 if (WinUSBX
[i
].Initialize
!= NULL
) {
2547 WinUSBX
[i
].initialized
= true;
2548 usbi_dbg("initalized sub API %s", sub_api_name
[i
]);
2550 usbi_warn(ctx
, "Failed to initalize sub API %s", sub_api_name
[i
]);
2551 WinUSBX
[i
].initialized
= false;
2554 return LIBUSB_SUCCESS
;
2557 static int winusbx_exit(int sub_api
)
2559 return LIBUSB_SUCCESS
;
2562 // NB: open and close must ensure that they only handle interface of
2563 // the right API type, as these functions can be called wholesale from
2564 // composite_open(), with interfaces belonging to different APIs
2565 static int winusbx_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
2567 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2568 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2569 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2574 CHECK_WINUSBX_AVAILABLE(sub_api
);
2576 // WinUSB requires a seperate handle for each interface
2577 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
2578 if ( (priv
->usb_interface
[i
].path
!= NULL
)
2579 && (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
) ) {
2580 file_handle
= CreateFileA(priv
->usb_interface
[i
].path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
2581 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2582 if (file_handle
== INVALID_HANDLE_VALUE
) {
2583 usbi_err(ctx
, "could not open device %s (interface %d): %s", priv
->usb_interface
[i
].path
, i
, windows_error_str(0));
2584 switch(GetLastError()) {
2585 case ERROR_FILE_NOT_FOUND
: // The device was disconnected
2586 return LIBUSB_ERROR_NO_DEVICE
;
2587 case ERROR_ACCESS_DENIED
:
2588 return LIBUSB_ERROR_ACCESS
;
2590 return LIBUSB_ERROR_IO
;
2593 handle_priv
->interface_handle
[i
].dev_handle
= file_handle
;
2597 return LIBUSB_SUCCESS
;
2600 static void winusbx_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
2602 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2603 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2607 if (sub_api
== SUB_API_NOTSET
)
2608 sub_api
= priv
->sub_api
;
2609 if (!WinUSBX
[sub_api
].initialized
)
2612 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
2613 if (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
) {
2614 file_handle
= handle_priv
->interface_handle
[i
].dev_handle
;
2615 if ( (file_handle
!= 0) && (file_handle
!= INVALID_HANDLE_VALUE
)) {
2616 CloseHandle(file_handle
);
2622 static int winusbx_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2624 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2625 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2626 HANDLE winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2629 uint8_t endpoint_address
;
2632 CHECK_WINUSBX_AVAILABLE(sub_api
);
2634 // With handle and enpoints set (in parent), we can setup the default pipe properties
2635 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2636 for (i
=-1; i
<priv
->usb_interface
[iface
].nb_endpoints
; i
++) {
2637 endpoint_address
=(i
==-1)?0:priv
->usb_interface
[iface
].endpoint
[i
];
2638 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2639 PIPE_TRANSFER_TIMEOUT
, sizeof(ULONG
), &timeout
)) {
2640 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address
);
2642 if ((i
== -1) || (sub_api
== SUB_API_LIBUSB0
)) {
2643 continue; // Other policies don't apply to control endpoint or libusb0
2646 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2647 SHORT_PACKET_TERMINATE
, sizeof(UCHAR
), &policy
)) {
2648 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address
);
2650 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2651 IGNORE_SHORT_PACKETS
, sizeof(UCHAR
), &policy
)) {
2652 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address
);
2655 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2656 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2657 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2658 ALLOW_PARTIAL_READS
, sizeof(UCHAR
), &policy
)) {
2659 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address
);
2661 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2662 AUTO_CLEAR_STALL
, sizeof(UCHAR
), &policy
)) {
2663 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address
);
2667 return LIBUSB_SUCCESS
;
2670 static int winusbx_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2672 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2673 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2674 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2675 bool is_using_usbccgp
= (priv
->apib
->id
== USB_API_COMPOSITE
);
2676 HANDLE file_handle
, winusb_handle
;
2679 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*dev_interface_details
= NULL
;
2680 HDEVINFO dev_info
= INVALID_HANDLE_VALUE
;
2681 SP_DEVINFO_DATA dev_info_data
;
2682 char* dev_path_no_guid
= NULL
;
2683 char filter_path
[] = "\\\\.\\libusb0-0000";
2684 bool found_filter
= false;
2686 CHECK_WINUSBX_AVAILABLE(sub_api
);
2688 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2689 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2690 if ((is_using_usbccgp
) || (iface
== 0)) {
2691 // composite device (independent interfaces) or interface 0
2692 file_handle
= handle_priv
->interface_handle
[iface
].dev_handle
;
2693 if ((file_handle
== 0) || (file_handle
== INVALID_HANDLE_VALUE
)) {
2694 return LIBUSB_ERROR_NOT_FOUND
;
2697 if (!WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2698 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2699 err
= GetLastError();
2701 case ERROR_BAD_COMMAND
:
2702 // The device was disconnected
2703 usbi_err(ctx
, "could not access interface %d: %s", iface
, windows_error_str(0));
2704 return LIBUSB_ERROR_NO_DEVICE
;
2706 // it may be that we're using the libusb0 filter driver.
2707 // TODO: can we move this whole business into the K/0 DLL?
2708 for (i
= 0; ; i
++) {
2709 safe_free(dev_interface_details
);
2710 safe_free(dev_path_no_guid
);
2711 dev_interface_details
= get_interface_details_filter(ctx
, &dev_info
, &dev_info_data
, &GUID_DEVINTERFACE_LIBUSB0_FILTER
, i
, filter_path
);
2712 if ((found_filter
) || (dev_interface_details
== NULL
)) {
2716 dev_path_no_guid
= sanitize_path(strtok(dev_interface_details
->DevicePath
, "{"));
2717 if (safe_strncmp(dev_path_no_guid
, priv
->usb_interface
[iface
].path
, safe_strlen(dev_path_no_guid
)) == 0) {
2718 file_handle
= CreateFileA(filter_path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
2719 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2720 if (file_handle
== INVALID_HANDLE_VALUE
) {
2721 usbi_err(ctx
, "could not open device %s: %s", filter_path
, windows_error_str(0));
2723 WinUSBX
[sub_api
].Free(winusb_handle
);
2724 if (!WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2727 found_filter
= true;
2732 if (!found_filter
) {
2733 usbi_err(ctx
, "could not access interface %d: %s", iface
, windows_error_str(err
));
2734 return LIBUSB_ERROR_ACCESS
;
2738 handle_priv
->interface_handle
[iface
].api_handle
= winusb_handle
;
2740 // For all other interfaces, use GetAssociatedInterface()
2741 winusb_handle
= handle_priv
->interface_handle
[0].api_handle
;
2742 // It is a requirement for multiple interface devices on Windows that, to you
2743 // must first claim the first interface before you claim the others
2744 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2745 file_handle
= handle_priv
->interface_handle
[0].dev_handle
;
2746 if (WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2747 handle_priv
->interface_handle
[0].api_handle
= winusb_handle
;
2748 usbi_warn(ctx
, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface
);
2750 usbi_warn(ctx
, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface
, windows_error_str(0));
2751 return LIBUSB_ERROR_ACCESS
;
2754 if (!WinUSBX
[sub_api
].GetAssociatedInterface(winusb_handle
, (UCHAR
)(iface
-1),
2755 &handle_priv
->interface_handle
[iface
].api_handle
)) {
2756 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2757 switch(GetLastError()) {
2758 case ERROR_NO_MORE_ITEMS
: // invalid iface
2759 return LIBUSB_ERROR_NOT_FOUND
;
2760 case ERROR_BAD_COMMAND
: // The device was disconnected
2761 return LIBUSB_ERROR_NO_DEVICE
;
2762 case ERROR_ALREADY_EXISTS
: // already claimed
2763 return LIBUSB_ERROR_BUSY
;
2765 usbi_err(ctx
, "could not claim interface %d: %s", iface
, windows_error_str(0));
2766 return LIBUSB_ERROR_ACCESS
;
2770 usbi_dbg("claimed interface %d", iface
);
2771 handle_priv
->active_interface
= iface
;
2773 return LIBUSB_SUCCESS
;
2776 static int winusbx_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2778 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2779 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2780 HANDLE winusb_handle
;
2782 CHECK_WINUSBX_AVAILABLE(sub_api
);
2784 winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2785 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2786 return LIBUSB_ERROR_NOT_FOUND
;
2789 WinUSBX
[sub_api
].Free(winusb_handle
);
2790 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2792 return LIBUSB_SUCCESS
;
2796 * Return the first valid interface (of the same API type), for control transfers
2798 static int get_valid_interface(struct libusb_device_handle
*dev_handle
, int api_id
)
2800 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2801 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2804 if ((api_id
< USB_API_WINUSBX
) || (api_id
> USB_API_HID
)) {
2805 usbi_dbg("unsupported API ID");
2809 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
2810 if ( (handle_priv
->interface_handle
[i
].dev_handle
!= 0)
2811 && (handle_priv
->interface_handle
[i
].dev_handle
!= INVALID_HANDLE_VALUE
)
2812 && (handle_priv
->interface_handle
[i
].api_handle
!= 0)
2813 && (handle_priv
->interface_handle
[i
].api_handle
!= INVALID_HANDLE_VALUE
)
2814 && (priv
->usb_interface
[i
].apib
->id
== api_id
) ) {
2822 * Lookup interface by endpoint address. -1 if not found
2824 static int interface_by_endpoint(struct windows_device_priv
*priv
,
2825 struct windows_device_handle_priv
*handle_priv
, uint8_t endpoint_address
)
2828 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
2829 if (handle_priv
->interface_handle
[i
].api_handle
== INVALID_HANDLE_VALUE
)
2831 if (handle_priv
->interface_handle
[i
].api_handle
== 0)
2833 if (priv
->usb_interface
[i
].endpoint
== NULL
)
2835 for (j
=0; j
<priv
->usb_interface
[i
].nb_endpoints
; j
++) {
2836 if (priv
->usb_interface
[i
].endpoint
[j
] == endpoint_address
) {
2844 static int winusbx_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
2846 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2847 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
2848 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2849 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
2850 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(
2851 transfer
->dev_handle
);
2852 WINUSB_SETUP_PACKET
*setup
= (WINUSB_SETUP_PACKET
*) transfer
->buffer
;
2854 HANDLE winusb_handle
;
2855 int current_interface
;
2858 CHECK_WINUSBX_AVAILABLE(sub_api
);
2860 transfer_priv
->pollable_fd
= INVALID_WINFD
;
2861 size
= transfer
->length
- LIBUSB_CONTROL_SETUP_SIZE
;
2863 if (size
> MAX_CTRL_BUFFER_LENGTH
)
2864 return LIBUSB_ERROR_INVALID_PARAM
;
2866 current_interface
= get_valid_interface(transfer
->dev_handle
, USB_API_WINUSBX
);
2867 if (current_interface
< 0) {
2868 if (auto_claim(transfer
, ¤t_interface
, USB_API_WINUSBX
) != LIBUSB_SUCCESS
) {
2869 return LIBUSB_ERROR_NOT_FOUND
;
2873 usbi_dbg("will use interface %d", current_interface
);
2874 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
2876 wfd
= usbi_create_fd(winusb_handle
, RW_READ
, NULL
, NULL
);
2877 // Always use the handle returned from usbi_create_fd (wfd.handle)
2879 return LIBUSB_ERROR_NO_MEM
;
2882 // Sending of set configuration control requests from WinUSB creates issues
2883 if ( ((setup
->request_type
& (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD
)
2884 && (setup
->request
== LIBUSB_REQUEST_SET_CONFIGURATION
) ) {
2885 if (setup
->value
!= priv
->active_config
) {
2886 usbi_warn(ctx
, "cannot set configuration other than the default one");
2887 usbi_free_fd(wfd
.fd
);
2888 return LIBUSB_ERROR_INVALID_PARAM
;
2890 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2891 wfd
.overlapped
->InternalHigh
= 0;
2893 if (!WinUSBX
[sub_api
].ControlTransfer(wfd
.handle
, *setup
, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, size
, NULL
, wfd
.overlapped
)) {
2894 if(GetLastError() != ERROR_IO_PENDING
) {
2895 usbi_warn(ctx
, "ControlTransfer failed: %s", windows_error_str(0));
2896 usbi_free_fd(wfd
.fd
);
2897 return LIBUSB_ERROR_IO
;
2900 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2901 wfd
.overlapped
->InternalHigh
= (DWORD
)size
;
2905 // Use priv_transfer to store data needed for async polling
2906 transfer_priv
->pollable_fd
= wfd
;
2907 transfer_priv
->interface_number
= (uint8_t)current_interface
;
2909 return LIBUSB_SUCCESS
;
2912 static int winusbx_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
2914 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2915 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2916 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2917 HANDLE winusb_handle
;
2919 CHECK_WINUSBX_AVAILABLE(sub_api
);
2921 if (altsetting
> 255) {
2922 return LIBUSB_ERROR_INVALID_PARAM
;
2925 winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2926 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2927 usbi_err(ctx
, "interface must be claimed first");
2928 return LIBUSB_ERROR_NOT_FOUND
;
2931 if (!WinUSBX
[sub_api
].SetCurrentAlternateSetting(winusb_handle
, (UCHAR
)altsetting
)) {
2932 usbi_err(ctx
, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2933 return LIBUSB_ERROR_IO
;
2936 return LIBUSB_SUCCESS
;
2939 static int winusbx_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
2941 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2942 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
2943 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
2944 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
2945 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2946 HANDLE winusb_handle
;
2948 int current_interface
;
2951 CHECK_WINUSBX_AVAILABLE(sub_api
);
2953 transfer_priv
->pollable_fd
= INVALID_WINFD
;
2955 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
2956 if (current_interface
< 0) {
2957 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
2958 return LIBUSB_ERROR_NOT_FOUND
;
2961 usbi_dbg("matched endpoint %02X with interface %d", transfer
->endpoint
, current_interface
);
2963 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
2965 wfd
= usbi_create_fd(winusb_handle
, IS_XFERIN(transfer
) ? RW_READ
: RW_WRITE
, NULL
, NULL
);
2966 // Always use the handle returned from usbi_create_fd (wfd.handle)
2968 return LIBUSB_ERROR_NO_MEM
;
2971 if (IS_XFERIN(transfer
)) {
2972 usbi_dbg("reading %d bytes", transfer
->length
);
2973 ret
= WinUSBX
[sub_api
].ReadPipe(wfd
.handle
, transfer
->endpoint
, transfer
->buffer
, transfer
->length
, NULL
, wfd
.overlapped
);
2975 usbi_dbg("writing %d bytes", transfer
->length
);
2976 ret
= WinUSBX
[sub_api
].WritePipe(wfd
.handle
, transfer
->endpoint
, transfer
->buffer
, transfer
->length
, NULL
, wfd
.overlapped
);
2979 if(GetLastError() != ERROR_IO_PENDING
) {
2980 usbi_err(ctx
, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2981 usbi_free_fd(wfd
.fd
);
2982 return LIBUSB_ERROR_IO
;
2985 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2986 wfd
.overlapped
->InternalHigh
= (DWORD
)transfer
->length
;
2989 transfer_priv
->pollable_fd
= wfd
;
2990 transfer_priv
->interface_number
= (uint8_t)current_interface
;
2992 return LIBUSB_SUCCESS
;
2995 static int winusbx_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
2997 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2998 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2999 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3000 HANDLE winusb_handle
;
3001 int current_interface
;
3003 CHECK_WINUSBX_AVAILABLE(sub_api
);
3005 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
3006 if (current_interface
< 0) {
3007 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
3008 return LIBUSB_ERROR_NOT_FOUND
;
3011 usbi_dbg("matched endpoint %02X with interface %d", endpoint
, current_interface
);
3012 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3014 if (!WinUSBX
[sub_api
].ResetPipe(winusb_handle
, endpoint
)) {
3015 usbi_err(ctx
, "ResetPipe failed: %s", windows_error_str(0));
3016 return LIBUSB_ERROR_NO_DEVICE
;
3019 return LIBUSB_SUCCESS
;
3023 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3024 * through testing as well):
3025 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3026 * the control transfer using CancelIo"
3028 static int winusbx_abort_control(int sub_api
, struct usbi_transfer
*itransfer
)
3030 // Cancelling of the I/O is done in the parent
3031 return LIBUSB_SUCCESS
;
3034 static int winusbx_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
3036 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3037 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3038 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3039 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3040 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3041 HANDLE winusb_handle
;
3042 int current_interface
;
3044 CHECK_WINUSBX_AVAILABLE(sub_api
);
3046 current_interface
= transfer_priv
->interface_number
;
3047 if ((current_interface
< 0) || (current_interface
>= USB_MAXINTERFACES
)) {
3048 usbi_err(ctx
, "program assertion failed: invalid interface_number");
3049 return LIBUSB_ERROR_NOT_FOUND
;
3051 usbi_dbg("will use interface %d", current_interface
);
3053 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3055 if (!WinUSBX
[sub_api
].AbortPipe(winusb_handle
, transfer
->endpoint
)) {
3056 usbi_err(ctx
, "AbortPipe failed: %s", windows_error_str(0));
3057 return LIBUSB_ERROR_NO_DEVICE
;
3060 return LIBUSB_SUCCESS
;
3064 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3065 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3066 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3067 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3068 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3069 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3071 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3072 static int winusbx_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
3074 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3075 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3076 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3078 HANDLE winusb_handle
;
3081 CHECK_WINUSBX_AVAILABLE(sub_api
);
3083 // Reset any available pipe (except control)
3084 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
3085 winusb_handle
= handle_priv
->interface_handle
[i
].api_handle
;
3086 for (wfd
= handle_to_winfd(winusb_handle
); wfd
.fd
> 0;)
3088 // Cancel any pollable I/O
3089 usbi_remove_pollfd(ctx
, wfd
.fd
);
3090 usbi_free_fd(wfd
.fd
);
3091 wfd
= handle_to_winfd(winusb_handle
);
3094 if ( (winusb_handle
!= 0) && (winusb_handle
!= INVALID_HANDLE_VALUE
)) {
3095 for (j
=0; j
<priv
->usb_interface
[i
].nb_endpoints
; j
++) {
3096 usbi_dbg("resetting ep %02X", priv
->usb_interface
[i
].endpoint
[j
]);
3097 if (!WinUSBX
[sub_api
].AbortPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) {
3098 usbi_err(ctx
, "AbortPipe (pipe address %02X) failed: %s",
3099 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3101 // FlushPipe seems to fail on OUT pipes
3102 if (IS_EPIN(priv
->usb_interface
[i
].endpoint
[j
])
3103 && (!WinUSBX
[sub_api
].FlushPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) ) {
3104 usbi_err(ctx
, "FlushPipe (pipe address %02X) failed: %s",
3105 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3107 if (!WinUSBX
[sub_api
].ResetPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) {
3108 usbi_err(ctx
, "ResetPipe (pipe address %02X) failed: %s",
3109 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3115 // libusbK & libusb0 have the ability to issue an actual device reset
3116 if (WinUSBX
[sub_api
].ResetDevice
!= NULL
) {
3117 winusb_handle
= handle_priv
->interface_handle
[0].api_handle
;
3118 if ( (winusb_handle
!= 0) && (winusb_handle
!= INVALID_HANDLE_VALUE
)) {
3119 WinUSBX
[sub_api
].ResetDevice(winusb_handle
);
3122 return LIBUSB_SUCCESS
;
3125 static int winusbx_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
)
3127 itransfer
->transferred
+= io_size
;
3128 return LIBUSB_TRANSFER_COMPLETED
;
3132 * Internal HID Support functions (from libusb-win32)
3133 * Note that functions that complete data transfer synchronously must return
3134 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3136 static int _hid_get_hid_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
);
3137 static int _hid_get_report_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
);
3139 static int _hid_wcslen(WCHAR
*str
)
3142 while (str
[i
] && (str
[i
] != 0x409)) {
3148 static int _hid_get_device_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3150 struct libusb_device_descriptor d
;
3152 d
.bLength
= LIBUSB_DT_DEVICE_SIZE
;
3153 d
.bDescriptorType
= LIBUSB_DT_DEVICE
;
3154 d
.bcdUSB
= 0x0200; /* 2.00 */
3156 d
.bDeviceSubClass
= 0;
3157 d
.bDeviceProtocol
= 0;
3158 d
.bMaxPacketSize0
= 64; /* fix this! */
3159 d
.idVendor
= (uint16_t)dev
->vid
;
3160 d
.idProduct
= (uint16_t)dev
->pid
;
3161 d
.bcdDevice
= 0x0100;
3162 d
.iManufacturer
= dev
->string_index
[0];
3163 d
.iProduct
= dev
->string_index
[1];
3164 d
.iSerialNumber
= dev
->string_index
[2];
3165 d
.bNumConfigurations
= 1;
3167 if (*size
> LIBUSB_DT_DEVICE_SIZE
)
3168 *size
= LIBUSB_DT_DEVICE_SIZE
;
3169 memcpy(data
, &d
, *size
);
3170 return LIBUSB_COMPLETED
;
3173 static int _hid_get_config_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3175 char num_endpoints
= 0;
3176 size_t config_total_len
= 0;
3177 char tmp
[HID_MAX_CONFIG_DESC_SIZE
];
3178 struct libusb_config_descriptor
*cd
;
3179 struct libusb_interface_descriptor
*id
;
3180 struct libusb_hid_descriptor
*hd
;
3181 struct libusb_endpoint_descriptor
*ed
;
3184 if (dev
->input_report_size
)
3186 if (dev
->output_report_size
)
3189 config_total_len
= LIBUSB_DT_CONFIG_SIZE
+ LIBUSB_DT_INTERFACE_SIZE
3190 + LIBUSB_DT_HID_SIZE
+ num_endpoints
* LIBUSB_DT_ENDPOINT_SIZE
;
3193 cd
= (struct libusb_config_descriptor
*)tmp
;
3194 id
= (struct libusb_interface_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
);
3195 hd
= (struct libusb_hid_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
3196 + LIBUSB_DT_INTERFACE_SIZE
);
3197 ed
= (struct libusb_endpoint_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
3198 + LIBUSB_DT_INTERFACE_SIZE
3199 + LIBUSB_DT_HID_SIZE
);
3201 cd
->bLength
= LIBUSB_DT_CONFIG_SIZE
;
3202 cd
->bDescriptorType
= LIBUSB_DT_CONFIG
;
3203 cd
->wTotalLength
= (uint16_t) config_total_len
;
3204 cd
->bNumInterfaces
= 1;
3205 cd
->bConfigurationValue
= 1;
3206 cd
->iConfiguration
= 0;
3207 cd
->bmAttributes
= 1 << 7; /* bus powered */
3210 id
->bLength
= LIBUSB_DT_INTERFACE_SIZE
;
3211 id
->bDescriptorType
= LIBUSB_DT_INTERFACE
;
3212 id
->bInterfaceNumber
= 0;
3213 id
->bAlternateSetting
= 0;
3214 id
->bNumEndpoints
= num_endpoints
;
3215 id
->bInterfaceClass
= 3;
3216 id
->bInterfaceSubClass
= 0;
3217 id
->bInterfaceProtocol
= 0;
3220 tmp_size
= LIBUSB_DT_HID_SIZE
;
3221 _hid_get_hid_descriptor(dev
, hd
, &tmp_size
);
3223 if (dev
->input_report_size
) {
3224 ed
->bLength
= LIBUSB_DT_ENDPOINT_SIZE
;
3225 ed
->bDescriptorType
= LIBUSB_DT_ENDPOINT
;
3226 ed
->bEndpointAddress
= HID_IN_EP
;
3227 ed
->bmAttributes
= 3;
3228 ed
->wMaxPacketSize
= dev
->input_report_size
- 1;
3230 ed
= (struct libusb_endpoint_descriptor
*)((char*)ed
+ LIBUSB_DT_ENDPOINT_SIZE
);
3233 if (dev
->output_report_size
) {
3234 ed
->bLength
= LIBUSB_DT_ENDPOINT_SIZE
;
3235 ed
->bDescriptorType
= LIBUSB_DT_ENDPOINT
;
3236 ed
->bEndpointAddress
= HID_OUT_EP
;
3237 ed
->bmAttributes
= 3;
3238 ed
->wMaxPacketSize
= dev
->output_report_size
- 1;
3242 if (*size
> config_total_len
)
3243 *size
= config_total_len
;
3244 memcpy(data
, tmp
, *size
);
3245 return LIBUSB_COMPLETED
;
3248 static int _hid_get_string_descriptor(struct hid_device_priv
* dev
, int _index
,
3249 void *data
, size_t *size
)
3252 size_t tmp_size
= 0;
3255 /* language ID, EN-US */
3256 char string_langid
[] = {
3261 if ((*size
< 2) || (*size
> 255)) {
3262 return LIBUSB_ERROR_OVERFLOW
;
3266 tmp
= string_langid
;
3267 tmp_size
= sizeof(string_langid
)+2;
3269 for (i
=0; i
<3; i
++) {
3270 if (_index
== (dev
->string_index
[i
])) {
3271 tmp
= dev
->string
[i
];
3272 tmp_size
= (_hid_wcslen(dev
->string
[i
])+1) * sizeof(WCHAR
);
3276 if (i
== 3) { // not found
3277 return LIBUSB_ERROR_INVALID_PARAM
;
3282 return LIBUSB_ERROR_INVALID_PARAM
;
3285 if (tmp_size
< *size
) {
3289 ((uint8_t*)data
)[0] = (uint8_t)*size
;
3290 ((uint8_t*)data
)[1] = LIBUSB_DT_STRING
;
3291 memcpy((uint8_t*)data
+2, tmp
, *size
-2);
3292 return LIBUSB_COMPLETED
;
3295 static int _hid_get_hid_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3297 struct libusb_hid_descriptor d
;
3298 uint8_t tmp
[MAX_HID_DESCRIPTOR_SIZE
];
3299 size_t report_len
= MAX_HID_DESCRIPTOR_SIZE
;
3301 _hid_get_report_descriptor(dev
, tmp
, &report_len
);
3303 d
.bLength
= LIBUSB_DT_HID_SIZE
;
3304 d
.bDescriptorType
= LIBUSB_DT_HID
;
3305 d
.bcdHID
= 0x0110; /* 1.10 */
3307 d
.bNumDescriptors
= 1;
3308 d
.bClassDescriptorType
= LIBUSB_DT_REPORT
;
3309 d
.wClassDescriptorLength
= (uint16_t)report_len
;
3311 if (*size
> LIBUSB_DT_HID_SIZE
)
3312 *size
= LIBUSB_DT_HID_SIZE
;
3313 memcpy(data
, &d
, *size
);
3314 return LIBUSB_COMPLETED
;
3317 static int _hid_get_report_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3319 uint8_t d
[MAX_HID_DESCRIPTOR_SIZE
];
3322 /* usage page (0xFFA0 == vendor defined) */
3323 d
[i
++] = 0x06; d
[i
++] = 0xA0; d
[i
++] = 0xFF;
3324 /* usage (vendor defined) */
3325 d
[i
++] = 0x09; d
[i
++] = 0x01;
3326 /* start collection (application) */
3327 d
[i
++] = 0xA1; d
[i
++] = 0x01;
3329 if (dev
->input_report_size
) {
3330 /* usage (vendor defined) */
3331 d
[i
++] = 0x09; d
[i
++] = 0x01;
3332 /* logical minimum (0) */
3333 d
[i
++] = 0x15; d
[i
++] = 0x00;
3334 /* logical maximum (255) */
3335 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3336 /* report size (8 bits) */
3337 d
[i
++] = 0x75; d
[i
++] = 0x08;
3339 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->input_report_size
- 1;
3340 /* input (data, variable, absolute) */
3341 d
[i
++] = 0x81; d
[i
++] = 0x00;
3344 if (dev
->output_report_size
) {
3345 /* usage (vendor defined) */
3346 d
[i
++] = 0x09; d
[i
++] = 0x02;
3347 /* logical minimum (0) */
3348 d
[i
++] = 0x15; d
[i
++] = 0x00;
3349 /* logical maximum (255) */
3350 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3351 /* report size (8 bits) */
3352 d
[i
++] = 0x75; d
[i
++] = 0x08;
3354 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->output_report_size
- 1;
3355 /* output (data, variable, absolute) */
3356 d
[i
++] = 0x91; d
[i
++] = 0x00;
3358 /* feature report */
3359 if (dev
->feature_report_size
) {
3360 /* usage (vendor defined) */
3361 d
[i
++] = 0x09; d
[i
++] = 0x03;
3362 /* logical minimum (0) */
3363 d
[i
++] = 0x15; d
[i
++] = 0x00;
3364 /* logical maximum (255) */
3365 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3366 /* report size (8 bits) */
3367 d
[i
++] = 0x75; d
[i
++] = 0x08;
3369 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->feature_report_size
- 1;
3370 /* feature (data, variable, absolute) */
3371 d
[i
++] = 0xb2; d
[i
++] = 0x02; d
[i
++] = 0x01;
3374 /* end collection */
3379 memcpy(data
, d
, *size
);
3380 return LIBUSB_COMPLETED
;
3383 static int _hid_get_descriptor(struct hid_device_priv
* dev
, HANDLE hid_handle
, int recipient
,
3384 int type
, int _index
, void *data
, size_t *size
)
3387 case LIBUSB_DT_DEVICE
:
3388 usbi_dbg("LIBUSB_DT_DEVICE");
3389 return _hid_get_device_descriptor(dev
, data
, size
);
3390 case LIBUSB_DT_CONFIG
:
3391 usbi_dbg("LIBUSB_DT_CONFIG");
3393 return _hid_get_config_descriptor(dev
, data
, size
);
3394 return LIBUSB_ERROR_INVALID_PARAM
;
3395 case LIBUSB_DT_STRING
:
3396 usbi_dbg("LIBUSB_DT_STRING");
3397 return _hid_get_string_descriptor(dev
, _index
, data
, size
);
3399 usbi_dbg("LIBUSB_DT_HID");
3401 return _hid_get_hid_descriptor(dev
, data
, size
);
3402 return LIBUSB_ERROR_INVALID_PARAM
;
3403 case LIBUSB_DT_REPORT
:
3404 usbi_dbg("LIBUSB_DT_REPORT");
3406 return _hid_get_report_descriptor(dev
, data
, size
);
3407 return LIBUSB_ERROR_INVALID_PARAM
;
3408 case LIBUSB_DT_PHYSICAL
:
3409 usbi_dbg("LIBUSB_DT_PHYSICAL");
3410 if (HidD_GetPhysicalDescriptor(hid_handle
, data
, (ULONG
)*size
))
3411 return LIBUSB_COMPLETED
;
3412 return LIBUSB_ERROR_OTHER
;
3414 usbi_dbg("unsupported");
3415 return LIBUSB_ERROR_INVALID_PARAM
;
3418 static int _hid_get_report(struct hid_device_priv
* dev
, HANDLE hid_handle
, int id
, void *data
,
3419 struct windows_transfer_priv
*tp
, size_t *size
, OVERLAPPED
* overlapped
,
3423 DWORD ioctl_code
, read_size
, expected_size
= (DWORD
)*size
;
3424 int r
= LIBUSB_SUCCESS
;
3426 if (tp
->hid_buffer
!= NULL
) {
3427 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3430 if ((*size
== 0) || (*size
> MAX_HID_REPORT_SIZE
)) {
3431 usbi_dbg("invalid size (%d)", *size
);
3432 return LIBUSB_ERROR_INVALID_PARAM
;
3435 switch (report_type
) {
3436 case HID_REPORT_TYPE_INPUT
:
3437 ioctl_code
= IOCTL_HID_GET_INPUT_REPORT
;
3439 case HID_REPORT_TYPE_FEATURE
:
3440 ioctl_code
= IOCTL_HID_GET_FEATURE
;
3443 usbi_dbg("unknown HID report type %d", report_type
);
3444 return LIBUSB_ERROR_INVALID_PARAM
;
3447 // Add a trailing byte to detect overflows
3448 buf
= (uint8_t*)calloc(expected_size
+1, 1);
3450 return LIBUSB_ERROR_NO_MEM
;
3452 buf
[0] = (uint8_t)id
; // Must be set always
3453 usbi_dbg("report ID: 0x%02X", buf
[0]);
3455 tp
->hid_expected_size
= expected_size
;
3456 read_size
= expected_size
;
3458 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3459 if (!DeviceIoControl(hid_handle
, ioctl_code
, buf
, expected_size
+1,
3460 buf
, expected_size
+1, &read_size
, overlapped
)) {
3461 if (GetLastError() != ERROR_IO_PENDING
) {
3462 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3464 return LIBUSB_ERROR_IO
;
3466 // Asynchronous wait
3467 tp
->hid_buffer
= buf
;
3468 tp
->hid_dest
= (uint8_t*)data
; // copy dest, as not necessarily the start of the transfer buffer
3469 return LIBUSB_SUCCESS
;
3472 // Transfer completed synchronously => copy and discard extra buffer
3473 if (read_size
== 0) {
3474 usbi_warn(NULL
, "program assertion failed - read completed synchronously, but no data was read");
3478 usbi_warn(NULL
, "mismatched report ID (data is %02X, parameter is %02X)", buf
[0], id
);
3480 if ((size_t)read_size
> expected_size
) {
3481 r
= LIBUSB_ERROR_OVERFLOW
;
3482 usbi_dbg("OVERFLOW!");
3484 r
= LIBUSB_COMPLETED
;
3487 *size
= MIN((size_t)read_size
, *size
);
3489 // Discard report ID
3490 memcpy(data
, buf
+1, *size
);
3492 memcpy(data
, buf
, *size
);
3499 static int _hid_set_report(struct hid_device_priv
* dev
, HANDLE hid_handle
, int id
, void *data
,
3500 struct windows_transfer_priv
*tp
, size_t *size
, OVERLAPPED
* overlapped
,
3503 uint8_t *buf
= NULL
;
3504 DWORD ioctl_code
, write_size
= (DWORD
)*size
;
3506 if (tp
->hid_buffer
!= NULL
) {
3507 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3510 if ((*size
== 0) || (*size
> MAX_HID_REPORT_SIZE
)) {
3511 usbi_dbg("invalid size (%d)", *size
);
3512 return LIBUSB_ERROR_INVALID_PARAM
;
3515 switch (report_type
) {
3516 case HID_REPORT_TYPE_OUTPUT
:
3517 ioctl_code
= IOCTL_HID_SET_OUTPUT_REPORT
;
3519 case HID_REPORT_TYPE_FEATURE
:
3520 ioctl_code
= IOCTL_HID_SET_FEATURE
;
3523 usbi_dbg("unknown HID report type %d", report_type
);
3524 return LIBUSB_ERROR_INVALID_PARAM
;
3527 usbi_dbg("report ID: 0x%02X", id
);
3528 // When report IDs are not used (i.e. when id == 0), we must add
3529 // a null report ID. Otherwise, we just use original data buffer
3533 buf
= (uint8_t*) malloc(write_size
);
3535 return LIBUSB_ERROR_NO_MEM
;
3539 memcpy(buf
+ 1, data
, *size
);
3541 // This seems like a waste, but if we don't duplicate the
3542 // data, we'll get issues when freeing hid_buffer
3543 memcpy(buf
, data
, *size
);
3545 usbi_warn(NULL
, "mismatched report ID (data is %02X, parameter is %02X)", buf
[0], id
);
3549 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3550 if (!DeviceIoControl(hid_handle
, ioctl_code
, buf
, write_size
,
3551 buf
, write_size
, &write_size
, overlapped
)) {
3552 if (GetLastError() != ERROR_IO_PENDING
) {
3553 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3555 return LIBUSB_ERROR_IO
;
3557 tp
->hid_buffer
= buf
;
3558 tp
->hid_dest
= NULL
;
3559 return LIBUSB_SUCCESS
;
3562 // Transfer completed synchronously
3564 if (write_size
== 0) {
3565 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3568 return LIBUSB_COMPLETED
;
3571 static int _hid_class_request(struct hid_device_priv
* dev
, HANDLE hid_handle
, int request_type
,
3572 int request
, int value
, int _index
, void *data
, struct windows_transfer_priv
*tp
,
3573 size_t *size
, OVERLAPPED
* overlapped
)
3575 int report_type
= (value
>> 8) & 0xFF;
3576 int report_id
= value
& 0xFF;
3578 if ( (LIBUSB_REQ_RECIPIENT(request_type
) != LIBUSB_RECIPIENT_INTERFACE
)
3579 && (LIBUSB_REQ_RECIPIENT(request_type
) != LIBUSB_RECIPIENT_DEVICE
) )
3580 return LIBUSB_ERROR_INVALID_PARAM
;
3582 if (LIBUSB_REQ_OUT(request_type
) && request
== HID_REQ_SET_REPORT
)
3583 return _hid_set_report(dev
, hid_handle
, report_id
, data
, tp
, size
, overlapped
, report_type
);
3585 if (LIBUSB_REQ_IN(request_type
) && request
== HID_REQ_GET_REPORT
)
3586 return _hid_get_report(dev
, hid_handle
, report_id
, data
, tp
, size
, overlapped
, report_type
);
3588 return LIBUSB_ERROR_INVALID_PARAM
;
3595 static int hid_init(int sub_api
, struct libusb_context
*ctx
)
3597 DLL_LOAD(hid
.dll
, HidD_GetAttributes
, TRUE
);
3598 DLL_LOAD(hid
.dll
, HidD_GetHidGuid
, TRUE
);
3599 DLL_LOAD(hid
.dll
, HidD_GetPreparsedData
, TRUE
);
3600 DLL_LOAD(hid
.dll
, HidD_FreePreparsedData
, TRUE
);
3601 DLL_LOAD(hid
.dll
, HidD_GetManufacturerString
, TRUE
);
3602 DLL_LOAD(hid
.dll
, HidD_GetProductString
, TRUE
);
3603 DLL_LOAD(hid
.dll
, HidD_GetSerialNumberString
, TRUE
);
3604 DLL_LOAD(hid
.dll
, HidP_GetCaps
, TRUE
);
3605 DLL_LOAD(hid
.dll
, HidD_SetNumInputBuffers
, TRUE
);
3606 DLL_LOAD(hid
.dll
, HidD_SetFeature
, TRUE
);
3607 DLL_LOAD(hid
.dll
, HidD_GetFeature
, TRUE
);
3608 DLL_LOAD(hid
.dll
, HidD_GetPhysicalDescriptor
, TRUE
);
3609 DLL_LOAD(hid
.dll
, HidD_GetInputReport
, FALSE
);
3610 DLL_LOAD(hid
.dll
, HidD_SetOutputReport
, FALSE
);
3611 DLL_LOAD(hid
.dll
, HidD_FlushQueue
, TRUE
);
3612 DLL_LOAD(hid
.dll
, HidP_GetValueCaps
, TRUE
);
3614 api_hid_available
= true;
3615 return LIBUSB_SUCCESS
;
3618 static int hid_exit(int sub_api
)
3620 return LIBUSB_SUCCESS
;
3623 // NB: open and close must ensure that they only handle interface of
3624 // the right API type, as these functions can be called wholesale from
3625 // composite_open(), with interfaces belonging to different APIs
3626 static int hid_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
3628 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3629 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3630 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3632 HIDD_ATTRIBUTES hid_attributes
;
3633 PHIDP_PREPARSED_DATA preparsed_data
= NULL
;
3634 HIDP_CAPS capabilities
;
3635 HIDP_VALUE_CAPS
*value_caps
;
3637 HANDLE hid_handle
= INVALID_HANDLE_VALUE
;
3639 // report IDs handling
3641 const char* type
[3] = {"input", "output", "feature"};
3642 int nb_ids
[2]; // zero and nonzero report IDs
3644 CHECK_HID_AVAILABLE
;
3645 if (priv
->hid
== NULL
) {
3646 usbi_err(ctx
, "program assertion failed - private HID structure is unitialized");
3647 return LIBUSB_ERROR_NOT_FOUND
;
3650 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
3651 if ( (priv
->usb_interface
[i
].path
!= NULL
)
3652 && (priv
->usb_interface
[i
].apib
->id
== USB_API_HID
) ) {
3653 hid_handle
= CreateFileA(priv
->usb_interface
[i
].path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
3654 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
3656 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3657 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3658 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3659 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3660 * HidD_GetFeature (if the device supports Feature reports)."
3662 if (hid_handle
== INVALID_HANDLE_VALUE
) {
3663 usbi_warn(ctx
, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3664 hid_handle
= CreateFileA(priv
->usb_interface
[i
].path
, 0, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
3665 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
3666 if (hid_handle
== INVALID_HANDLE_VALUE
) {
3667 usbi_err(ctx
, "could not open device %s (interface %d): %s", priv
->path
, i
, windows_error_str(0));
3668 switch(GetLastError()) {
3669 case ERROR_FILE_NOT_FOUND
: // The device was disconnected
3670 return LIBUSB_ERROR_NO_DEVICE
;
3671 case ERROR_ACCESS_DENIED
:
3672 return LIBUSB_ERROR_ACCESS
;
3674 return LIBUSB_ERROR_IO
;
3677 priv
->usb_interface
[i
].restricted_functionality
= true;
3679 handle_priv
->interface_handle
[i
].api_handle
= hid_handle
;
3683 hid_attributes
.Size
= sizeof(hid_attributes
);
3685 if (!HidD_GetAttributes(hid_handle
, &hid_attributes
)) {
3686 usbi_err(ctx
, "could not gain access to HID top collection (HidD_GetAttributes)");
3690 priv
->hid
->vid
= hid_attributes
.VendorID
;
3691 priv
->hid
->pid
= hid_attributes
.ProductID
;
3693 // Set the maximum available input buffer size
3694 for (i
=32; HidD_SetNumInputBuffers(hid_handle
, i
); i
*=2);
3695 usbi_dbg("set maximum input buffer size to %d", i
/2);
3697 // Get the maximum input and output report size
3698 if (!HidD_GetPreparsedData(hid_handle
, &preparsed_data
) || !preparsed_data
) {
3699 usbi_err(ctx
, "could not read HID preparsed data (HidD_GetPreparsedData)");
3702 if (HidP_GetCaps(preparsed_data
, &capabilities
) != HIDP_STATUS_SUCCESS
) {
3703 usbi_err(ctx
, "could not parse HID capabilities (HidP_GetCaps)");
3707 // Find out if interrupt will need report IDs
3708 size
[0] = capabilities
.NumberInputValueCaps
;
3709 size
[1] = capabilities
.NumberOutputValueCaps
;
3710 size
[2] = capabilities
.NumberFeatureValueCaps
;
3711 for (j
=HidP_Input
; j
<=HidP_Feature
; j
++) {
3712 usbi_dbg("%d HID %s report value(s) found", size
[j
], type
[j
]);
3713 priv
->hid
->uses_report_ids
[j
] = false;
3715 value_caps
= (HIDP_VALUE_CAPS
*) calloc(size
[j
], sizeof(HIDP_VALUE_CAPS
));
3716 if ( (value_caps
!= NULL
)
3717 && (HidP_GetValueCaps((HIDP_REPORT_TYPE
)j
, value_caps
, &size
[j
], preparsed_data
) == HIDP_STATUS_SUCCESS
)
3718 && (size
[j
] >= 1) ) {
3721 for (i
=0; i
<(int)size
[j
]; i
++) {
3722 usbi_dbg(" Report ID: 0x%02X", value_caps
[i
].ReportID
);
3723 if (value_caps
[i
].ReportID
!= 0) {
3729 if (nb_ids
[1] != 0) {
3730 if (nb_ids
[0] != 0) {
3731 usbi_warn(ctx
, "program assertion failed: zero and nonzero report IDs used for %s",
3734 priv
->hid
->uses_report_ids
[j
] = true;
3737 usbi_warn(ctx
, " could not process %s report IDs", type
[j
]);
3739 safe_free(value_caps
);
3743 // Set the report sizes
3744 priv
->hid
->input_report_size
= capabilities
.InputReportByteLength
;
3745 priv
->hid
->output_report_size
= capabilities
.OutputReportByteLength
;
3746 priv
->hid
->feature_report_size
= capabilities
.FeatureReportByteLength
;
3748 // Fetch string descriptors
3749 priv
->hid
->string_index
[0] = priv
->dev_descriptor
.iManufacturer
;
3750 if (priv
->hid
->string_index
[0] != 0) {
3751 HidD_GetManufacturerString(hid_handle
, priv
->hid
->string
[0],
3752 sizeof(priv
->hid
->string
[0]));
3754 priv
->hid
->string
[0][0] = 0;
3756 priv
->hid
->string_index
[1] = priv
->dev_descriptor
.iProduct
;
3757 if (priv
->hid
->string_index
[1] != 0) {
3758 HidD_GetProductString(hid_handle
, priv
->hid
->string
[1],
3759 sizeof(priv
->hid
->string
[1]));
3761 priv
->hid
->string
[1][0] = 0;
3763 priv
->hid
->string_index
[2] = priv
->dev_descriptor
.iSerialNumber
;
3764 if (priv
->hid
->string_index
[2] != 0) {
3765 HidD_GetSerialNumberString(hid_handle
, priv
->hid
->string
[2],
3766 sizeof(priv
->hid
->string
[2]));
3768 priv
->hid
->string
[2][0] = 0;
3772 if (preparsed_data
) {
3773 HidD_FreePreparsedData(preparsed_data
);
3776 return LIBUSB_SUCCESS
;
3779 static void hid_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
3781 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3782 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3786 if (!api_hid_available
)
3789 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
3790 if (priv
->usb_interface
[i
].apib
->id
== USB_API_HID
) {
3791 file_handle
= handle_priv
->interface_handle
[i
].api_handle
;
3792 if ( (file_handle
!= 0) && (file_handle
!= INVALID_HANDLE_VALUE
)) {
3793 CloseHandle(file_handle
);
3799 static int hid_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
3801 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3802 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3804 CHECK_HID_AVAILABLE
;
3806 // NB: Disconnection detection is not possible in this function
3807 if (priv
->usb_interface
[iface
].path
== NULL
) {
3808 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3811 // We use dev_handle as a flag for interface claimed
3812 if (handle_priv
->interface_handle
[iface
].dev_handle
== INTERFACE_CLAIMED
) {
3813 return LIBUSB_ERROR_BUSY
; // already claimed
3816 handle_priv
->interface_handle
[iface
].dev_handle
= INTERFACE_CLAIMED
;
3818 usbi_dbg("claimed interface %d", iface
);
3819 handle_priv
->active_interface
= iface
;
3821 return LIBUSB_SUCCESS
;
3824 static int hid_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
3826 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3827 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3829 CHECK_HID_AVAILABLE
;
3831 if (priv
->usb_interface
[iface
].path
== NULL
) {
3832 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3835 if (handle_priv
->interface_handle
[iface
].dev_handle
!= INTERFACE_CLAIMED
) {
3836 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3839 handle_priv
->interface_handle
[iface
].dev_handle
= INVALID_HANDLE_VALUE
;
3841 return LIBUSB_SUCCESS
;
3844 static int hid_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
3846 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3848 CHECK_HID_AVAILABLE
;
3850 if (altsetting
> 255) {
3851 return LIBUSB_ERROR_INVALID_PARAM
;
3854 if (altsetting
!= 0) {
3855 usbi_err(ctx
, "set interface altsetting not supported for altsetting >0");
3856 return LIBUSB_ERROR_NOT_SUPPORTED
;
3859 return LIBUSB_SUCCESS
;
3862 static int hid_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
3864 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3865 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3866 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3867 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3868 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3869 WINUSB_SETUP_PACKET
*setup
= (WINUSB_SETUP_PACKET
*) transfer
->buffer
;
3872 int current_interface
, config
;
3874 int r
= LIBUSB_ERROR_INVALID_PARAM
;
3876 CHECK_HID_AVAILABLE
;
3878 transfer_priv
->pollable_fd
= INVALID_WINFD
;
3879 safe_free(transfer_priv
->hid_buffer
);
3880 transfer_priv
->hid_dest
= NULL
;
3881 size
= transfer
->length
- LIBUSB_CONTROL_SETUP_SIZE
;
3883 if (size
> MAX_CTRL_BUFFER_LENGTH
) {
3884 return LIBUSB_ERROR_INVALID_PARAM
;
3887 current_interface
= get_valid_interface(transfer
->dev_handle
, USB_API_HID
);
3888 if (current_interface
< 0) {
3889 if (auto_claim(transfer
, ¤t_interface
, USB_API_HID
) != LIBUSB_SUCCESS
) {
3890 return LIBUSB_ERROR_NOT_FOUND
;
3894 usbi_dbg("will use interface %d", current_interface
);
3895 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3896 // Always use the handle returned from usbi_create_fd (wfd.handle)
3897 wfd
= usbi_create_fd(hid_handle
, RW_READ
, NULL
, NULL
);
3899 return LIBUSB_ERROR_NOT_FOUND
;
3902 switch(LIBUSB_REQ_TYPE(setup
->request_type
)) {
3903 case LIBUSB_REQUEST_TYPE_STANDARD
:
3904 switch(setup
->request
) {
3905 case LIBUSB_REQUEST_GET_DESCRIPTOR
:
3906 r
= _hid_get_descriptor(priv
->hid
, wfd
.handle
, LIBUSB_REQ_RECIPIENT(setup
->request_type
),
3907 (setup
->value
>> 8) & 0xFF, setup
->value
& 0xFF, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, &size
);
3909 case LIBUSB_REQUEST_GET_CONFIGURATION
:
3910 r
= windows_get_configuration(transfer
->dev_handle
, &config
);
3911 if (r
== LIBUSB_SUCCESS
) {
3913 ((uint8_t*)transfer
->buffer
)[LIBUSB_CONTROL_SETUP_SIZE
] = (uint8_t)config
;
3914 r
= LIBUSB_COMPLETED
;
3917 case LIBUSB_REQUEST_SET_CONFIGURATION
:
3918 if (setup
->value
== priv
->active_config
) {
3919 r
= LIBUSB_COMPLETED
;
3921 usbi_warn(ctx
, "cannot set configuration other than the default one");
3922 r
= LIBUSB_ERROR_INVALID_PARAM
;
3925 case LIBUSB_REQUEST_GET_INTERFACE
:
3927 ((uint8_t*)transfer
->buffer
)[LIBUSB_CONTROL_SETUP_SIZE
] = 0;
3928 r
= LIBUSB_COMPLETED
;
3930 case LIBUSB_REQUEST_SET_INTERFACE
:
3931 r
= hid_set_interface_altsetting(0, transfer
->dev_handle
, setup
->index
, setup
->value
);
3932 if (r
== LIBUSB_SUCCESS
) {
3933 r
= LIBUSB_COMPLETED
;
3937 usbi_warn(ctx
, "unsupported HID control request");
3938 r
= LIBUSB_ERROR_INVALID_PARAM
;
3942 case LIBUSB_REQUEST_TYPE_CLASS
:
3943 r
=_hid_class_request(priv
->hid
, wfd
.handle
, setup
->request_type
, setup
->request
, setup
->value
,
3944 setup
->index
, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, transfer_priv
,
3945 &size
, wfd
.overlapped
);
3948 usbi_warn(ctx
, "unsupported HID control request");
3949 r
= LIBUSB_ERROR_INVALID_PARAM
;
3953 if (r
== LIBUSB_COMPLETED
) {
3954 // Force request to be completed synchronously. Transferred size has been set by previous call
3955 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
3956 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3957 // set InternalHigh to the number of bytes transferred
3958 wfd
.overlapped
->InternalHigh
= (DWORD
)size
;
3962 if (r
== LIBUSB_SUCCESS
) {
3963 // Use priv_transfer to store data needed for async polling
3964 transfer_priv
->pollable_fd
= wfd
;
3965 transfer_priv
->interface_number
= (uint8_t)current_interface
;
3967 usbi_free_fd(wfd
.fd
);
3973 static int hid_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
3974 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3975 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3976 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3977 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3978 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3981 bool direction_in
, ret
;
3982 int current_interface
, length
;
3984 int r
= LIBUSB_SUCCESS
;
3986 CHECK_HID_AVAILABLE
;
3988 transfer_priv
->pollable_fd
= INVALID_WINFD
;
3989 transfer_priv
->hid_dest
= NULL
;
3990 safe_free(transfer_priv
->hid_buffer
);
3992 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
3993 if (current_interface
< 0) {
3994 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
3995 return LIBUSB_ERROR_NOT_FOUND
;
3998 usbi_dbg("matched endpoint %02X with interface %d", transfer
->endpoint
, current_interface
);
4000 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4001 direction_in
= transfer
->endpoint
& LIBUSB_ENDPOINT_IN
;
4003 wfd
= usbi_create_fd(hid_handle
, direction_in
?RW_READ
:RW_WRITE
, NULL
, NULL
);
4004 // Always use the handle returned from usbi_create_fd (wfd.handle)
4006 return LIBUSB_ERROR_NO_MEM
;
4009 // If report IDs are not in use, an extra prefix byte must be added
4010 if ( ((direction_in
) && (!priv
->hid
->uses_report_ids
[0]))
4011 || ((!direction_in
) && (!priv
->hid
->uses_report_ids
[1])) ) {
4012 length
= transfer
->length
+1;
4014 length
= transfer
->length
;
4016 // Add a trailing byte to detect overflows on input
4017 transfer_priv
->hid_buffer
= (uint8_t*)calloc(length
+1, 1);
4018 if (transfer_priv
->hid_buffer
== NULL
) {
4019 return LIBUSB_ERROR_NO_MEM
;
4021 transfer_priv
->hid_expected_size
= length
;
4024 transfer_priv
->hid_dest
= transfer
->buffer
;
4025 usbi_dbg("reading %d bytes (report ID: 0x00)", length
);
4026 ret
= ReadFile(wfd
.handle
, transfer_priv
->hid_buffer
, length
+1, &size
, wfd
.overlapped
);
4028 if (!priv
->hid
->uses_report_ids
[1]) {
4029 memcpy(transfer_priv
->hid_buffer
+1, transfer
->buffer
, transfer
->length
);
4031 // We could actually do without the calloc and memcpy in this case
4032 memcpy(transfer_priv
->hid_buffer
, transfer
->buffer
, transfer
->length
);
4034 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length
, transfer_priv
->hid_buffer
[0]);
4035 ret
= WriteFile(wfd
.handle
, transfer_priv
->hid_buffer
, length
, &size
, wfd
.overlapped
);
4038 if (GetLastError() != ERROR_IO_PENDING
) {
4039 usbi_err(ctx
, "HID transfer failed: %s", windows_error_str(0));
4040 usbi_free_fd(wfd
.fd
);
4041 safe_free(transfer_priv
->hid_buffer
);
4042 return LIBUSB_ERROR_IO
;
4045 // Only write operations that completed synchronously need to free up
4046 // hid_buffer. For reads, copy_transfer_data() handles that process.
4047 if (!direction_in
) {
4048 safe_free(transfer_priv
->hid_buffer
);
4051 usbi_err(ctx
, "program assertion failed - no data was transferred");
4054 if (size
> (size_t)length
) {
4055 usbi_err(ctx
, "OVERFLOW!");
4056 r
= LIBUSB_ERROR_OVERFLOW
;
4058 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
4059 wfd
.overlapped
->InternalHigh
= size
;
4062 transfer_priv
->pollable_fd
= wfd
;
4063 transfer_priv
->interface_number
= (uint8_t)current_interface
;
4068 static int hid_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
4070 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4071 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
4072 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4074 int current_interface
;
4076 CHECK_HID_AVAILABLE
;
4078 current_interface
= transfer_priv
->interface_number
;
4079 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4080 CancelIo(hid_handle
);
4082 return LIBUSB_SUCCESS
;
4085 static int hid_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
4087 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4089 int current_interface
;
4091 CHECK_HID_AVAILABLE
;
4093 // Flushing the queues on all interfaces is the best we can achieve
4094 for (current_interface
= 0; current_interface
< USB_MAXINTERFACES
; current_interface
++) {
4095 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4096 if ((hid_handle
!= 0) && (hid_handle
!= INVALID_HANDLE_VALUE
)) {
4097 HidD_FlushQueue(hid_handle
);
4100 return LIBUSB_SUCCESS
;
4103 static int hid_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
4105 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
4106 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4107 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4109 int current_interface
;
4111 CHECK_HID_AVAILABLE
;
4113 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
4114 if (current_interface
< 0) {
4115 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
4116 return LIBUSB_ERROR_NOT_FOUND
;
4119 usbi_dbg("matched endpoint %02X with interface %d", endpoint
, current_interface
);
4120 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4122 // No endpoint selection with Microsoft's implementation, so we try to flush the
4123 // whole interface. Should be OK for most case scenarios
4124 if (!HidD_FlushQueue(hid_handle
)) {
4125 usbi_err(ctx
, "Flushing of HID queue failed: %s", windows_error_str(0));
4126 // Device was probably disconnected
4127 return LIBUSB_ERROR_NO_DEVICE
;
4130 return LIBUSB_SUCCESS
;
4133 // This extra function is only needed for HID
4134 static int hid_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
) {
4135 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4136 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4137 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4138 int r
= LIBUSB_TRANSFER_COMPLETED
;
4139 uint32_t corrected_size
= io_size
;
4141 if (transfer_priv
->hid_buffer
!= NULL
) {
4142 // If we have a valid hid_buffer, it means the transfer was async
4143 if (transfer_priv
->hid_dest
!= NULL
) { // Data readout
4144 // First, check for overflow
4145 if (corrected_size
> transfer_priv
->hid_expected_size
) {
4146 usbi_err(ctx
, "OVERFLOW!");
4147 corrected_size
= (uint32_t)transfer_priv
->hid_expected_size
;
4148 r
= LIBUSB_TRANSFER_OVERFLOW
;
4151 if (transfer_priv
->hid_buffer
[0] == 0) {
4152 // Discard the 1 byte report ID prefix
4154 memcpy(transfer_priv
->hid_dest
, transfer_priv
->hid_buffer
+1, corrected_size
);
4156 memcpy(transfer_priv
->hid_dest
, transfer_priv
->hid_buffer
, corrected_size
);
4158 transfer_priv
->hid_dest
= NULL
;
4160 // For write, we just need to free the hid buffer
4161 safe_free(transfer_priv
->hid_buffer
);
4163 itransfer
->transferred
+= corrected_size
;
4169 * Composite API functions
4171 static int composite_init(int sub_api
, struct libusb_context
*ctx
)
4173 return LIBUSB_SUCCESS
;
4176 static int composite_exit(int sub_api
)
4178 return LIBUSB_SUCCESS
;
4181 static int composite_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
4183 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4184 int r
= LIBUSB_ERROR_NOT_FOUND
;
4186 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4187 bool available
[SUB_API_MAX
+1] = {0};
4189 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4190 switch (priv
->usb_interface
[i
].apib
->id
) {
4191 case USB_API_WINUSBX
:
4192 if (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
)
4193 available
[priv
->usb_interface
[i
].sub_api
] = true;
4196 available
[SUB_API_MAX
] = true;
4203 for (i
=0; i
<SUB_API_MAX
; i
++) { // WinUSB-like drivers
4205 r
= usb_api_backend
[USB_API_WINUSBX
].open(i
, dev_handle
);
4206 if (r
!= LIBUSB_SUCCESS
) {
4211 if (available
[SUB_API_MAX
]) { // HID driver
4212 r
= hid_open(SUB_API_NOTSET
, dev_handle
);
4217 static void composite_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
4219 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4221 bool available
[SUB_API_MAX
];
4223 for (i
= 0; i
<SUB_API_MAX
; i
++) {
4224 available
[i
] = false;
4227 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4228 if ( (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
)
4229 && (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
) ) {
4230 available
[priv
->usb_interface
[i
].sub_api
] = true;
4234 for (i
=0; i
<SUB_API_MAX
; i
++) {
4236 usb_api_backend
[USB_API_WINUSBX
].close(i
, dev_handle
);
4241 static int composite_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
4243 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4244 return priv
->usb_interface
[iface
].apib
->
4245 claim_interface(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
);
4248 static int composite_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
4250 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4251 return priv
->usb_interface
[iface
].apib
->
4252 set_interface_altsetting(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
, altsetting
);
4255 static int composite_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
4257 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4258 return priv
->usb_interface
[iface
].apib
->
4259 release_interface(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
);
4262 static int composite_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
4264 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4265 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4266 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4269 // Interface shouldn't matter for control, but it does in practice, with Windows'
4270 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4271 for (pass
= 0; pass
< 2; pass
++) {
4272 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4273 if (priv
->usb_interface
[i
].path
!= NULL
) {
4274 if ((pass
== 0) && (priv
->usb_interface
[i
].restricted_functionality
)) {
4275 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i
);
4278 usbi_dbg("using interface %d", i
);
4279 return priv
->usb_interface
[i
].apib
->submit_control_transfer(priv
->usb_interface
[i
].sub_api
, itransfer
);
4284 usbi_err(ctx
, "no libusbx supported interfaces to complete request");
4285 return LIBUSB_ERROR_NOT_FOUND
;
4288 static int composite_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
4289 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4290 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4291 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4292 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4293 int current_interface
;
4295 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
4296 if (current_interface
< 0) {
4297 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
4298 return LIBUSB_ERROR_NOT_FOUND
;
4301 return priv
->usb_interface
[current_interface
].apib
->
4302 submit_bulk_transfer(priv
->usb_interface
[current_interface
].sub_api
, itransfer
);}
4304 static int composite_submit_iso_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
4305 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4306 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4307 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4308 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4309 int current_interface
;
4311 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
4312 if (current_interface
< 0) {
4313 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
4314 return LIBUSB_ERROR_NOT_FOUND
;
4317 return priv
->usb_interface
[current_interface
].apib
->
4318 submit_iso_transfer(priv
->usb_interface
[current_interface
].sub_api
, itransfer
);}
4320 static int composite_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
4322 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
4323 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4324 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4325 int current_interface
;
4327 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
4328 if (current_interface
< 0) {
4329 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
4330 return LIBUSB_ERROR_NOT_FOUND
;
4333 return priv
->usb_interface
[current_interface
].apib
->
4334 clear_halt(priv
->usb_interface
[current_interface
].sub_api
, dev_handle
, endpoint
);}
4336 static int composite_abort_control(int sub_api
, struct usbi_transfer
*itransfer
)
4338 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4339 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4340 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4342 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4343 abort_control(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
);}
4345 static int composite_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
4347 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4348 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4349 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4351 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4352 abort_transfers(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
);}
4354 static int composite_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
4356 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4359 bool available
[SUB_API_MAX
];
4360 for (i
= 0; i
<SUB_API_MAX
; i
++) {
4361 available
[i
] = false;
4363 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4364 if ( (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
)
4365 && (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
) ) {
4366 available
[priv
->usb_interface
[i
].sub_api
] = true;
4369 for (i
=0; i
<SUB_API_MAX
; i
++) {
4371 r
= usb_api_backend
[USB_API_WINUSBX
].reset_device(i
, dev_handle
);
4372 if (r
!= LIBUSB_SUCCESS
) {
4377 return LIBUSB_SUCCESS
;
4380 static int composite_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
)
4382 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4383 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4384 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4386 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4387 copy_transfer_data(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
, io_size
);