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
= libusb_ref_device(parent_dev
);
1115 // If the device address is already set, we can stop here
1116 if (dev
->device_address
!= 0) {
1117 return LIBUSB_SUCCESS
;
1119 memset(&conn_info
, 0, sizeof(conn_info
));
1120 if (priv
->depth
!= 0) { // Not a HCD hub
1121 handle
= CreateFileA(parent_priv
->path
, GENERIC_WRITE
, FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
1122 FILE_FLAG_OVERLAPPED
, NULL
);
1123 if (handle
== INVALID_HANDLE_VALUE
) {
1124 usbi_warn(ctx
, "could not open hub %s: %s", parent_priv
->path
, windows_error_str(0));
1125 return LIBUSB_ERROR_ACCESS
;
1127 size
= sizeof(conn_info
);
1128 conn_info
.ConnectionIndex
= (ULONG
)port_number
;
1129 if (!DeviceIoControl(handle
, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX
, &conn_info
, size
,
1130 &conn_info
, size
, &size
, NULL
)) {
1131 usbi_warn(ctx
, "could not get node connection information for device '%s': %s",
1132 device_id
, windows_error_str(0));
1133 safe_closehandle(handle
);
1134 return LIBUSB_ERROR_NO_DEVICE
;
1136 if (conn_info
.ConnectionStatus
== NoDeviceConnected
) {
1137 usbi_err(ctx
, "device '%s' is no longer connected!", device_id
);
1138 safe_closehandle(handle
);
1139 return LIBUSB_ERROR_NO_DEVICE
;
1141 memcpy(&priv
->dev_descriptor
, &(conn_info
.DeviceDescriptor
), sizeof(USB_DEVICE_DESCRIPTOR
));
1142 dev
->num_configurations
= priv
->dev_descriptor
.bNumConfigurations
;
1143 priv
->active_config
= conn_info
.CurrentConfigurationValue
;
1144 usbi_dbg("found %d configurations (active conf: %d)", dev
->num_configurations
, priv
->active_config
);
1145 // If we can't read the config descriptors, just set the number of confs to zero
1146 if (cache_config_descriptors(dev
, handle
, device_id
) != LIBUSB_SUCCESS
) {
1147 dev
->num_configurations
= 0;
1148 priv
->dev_descriptor
.bNumConfigurations
= 0;
1150 safe_closehandle(handle
);
1152 if (conn_info
.DeviceAddress
> UINT8_MAX
) {
1153 usbi_err(ctx
, "program assertion failed: device address overflow");
1155 dev
->device_address
= (uint8_t)conn_info
.DeviceAddress
+ 1;
1156 if (dev
->device_address
== 1) {
1157 usbi_err(ctx
, "program assertion failed: device address collision with root hub");
1159 switch (conn_info
.Speed
) {
1160 case 0: dev
->speed
= LIBUSB_SPEED_LOW
; break;
1161 case 1: dev
->speed
= LIBUSB_SPEED_FULL
; break;
1162 case 2: dev
->speed
= LIBUSB_SPEED_HIGH
; break;
1163 case 3: dev
->speed
= LIBUSB_SPEED_SUPER
; break;
1165 usbi_warn(ctx
, "Got unknown device speed %d", conn_info
.Speed
);
1169 dev
->device_address
= 1; // root hubs are set to use device number 1
1170 force_hcd_device_descriptor(dev
);
1173 usbi_sanitize_device(dev
);
1175 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1176 dev
->bus_number
, dev
->device_address
, priv
->depth
, priv
->port
, device_id
);
1178 return LIBUSB_SUCCESS
;
1181 // Returns the api type, or 0 if not found/unsupported
1182 static void get_api_type(struct libusb_context
*ctx
, HDEVINFO
*dev_info
,
1183 SP_DEVINFO_DATA
*dev_info_data
, int *api
, int *sub_api
)
1185 // Precedence for filter drivers vs driver is in the order of this array
1186 struct driver_lookup lookup
[3] = {
1187 {"\0\0", SPDRP_SERVICE
, "driver"},
1188 {"\0\0", SPDRP_UPPERFILTERS
, "upper filter driver"},
1189 {"\0\0", SPDRP_LOWERFILTERS
, "lower filter driver"}
1191 DWORD size
, reg_type
;
1195 *api
= USB_API_UNSUPPORTED
;
1196 *sub_api
= SUB_API_NOTSET
;
1197 // Check the service & filter names to know the API we should use
1198 for (k
=0; k
<3; k
++) {
1199 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info
, dev_info_data
, lookup
[k
].reg_prop
,
1200 ®_type
, (BYTE
*)lookup
[k
].list
, MAX_KEY_LENGTH
, &size
)) {
1201 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1202 if (lookup
[k
].reg_prop
== SPDRP_SERVICE
) {
1203 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1204 lookup
[k
].list
[safe_strlen(lookup
[k
].list
)+1] = 0;
1206 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1207 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1208 // (currently ';'), so even if an unsuported one does, it's not an issue
1209 for (l
=0; (lookup
[k
].list
[l
] != 0) || (lookup
[k
].list
[l
+1] != 0); l
++) {
1210 if (lookup
[k
].list
[l
] == 0) {
1211 lookup
[k
].list
[l
] = LIST_SEPARATOR
;
1214 usbi_dbg("%s(s): %s", lookup
[k
].designation
, lookup
[k
].list
);
1216 if (GetLastError() != ERROR_INVALID_DATA
) {
1217 usbi_dbg("could not access %s: %s", lookup
[k
].designation
, windows_error_str(0));
1219 lookup
[k
].list
[0] = 0;
1223 for (i
=1; i
<USB_API_MAX
; i
++) {
1224 for (k
=0; k
<3; k
++) {
1225 j
= get_sub_api(lookup
[k
].list
, i
);
1227 usbi_dbg("matched %s name against %s API",
1228 lookup
[k
].designation
, (i
!=USB_API_WINUSBX
)?usb_api_backend
[i
].designation
:sub_api_name
[j
]);
1237 static int set_composite_interface(struct libusb_context
* ctx
, struct libusb_device
* dev
,
1238 char* dev_interface_path
, char* device_id
, int api
, int sub_api
)
1241 struct windows_device_priv
*priv
= _device_priv(dev
);
1242 int interface_number
;
1244 if (priv
->apib
->id
!= USB_API_COMPOSITE
) {
1245 usbi_err(ctx
, "program assertion failed: '%s' is not composite", device_id
);
1246 return LIBUSB_ERROR_NO_DEVICE
;
1249 // Because MI_## are not necessarily in sequential order (some composite
1250 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1251 // interface number from the path's MI value
1252 interface_number
= 0;
1253 for (i
=0; device_id
[i
] != 0; ) {
1254 if ( (device_id
[i
++] == 'M') && (device_id
[i
++] == 'I')
1255 && (device_id
[i
++] == '_') ) {
1256 interface_number
= (device_id
[i
++] - '0')*10;
1257 interface_number
+= device_id
[i
] - '0';
1262 if (device_id
[i
] == 0) {
1263 usbi_warn(ctx
, "failure to read interface number for %s. Using default value %d",
1264 device_id
, interface_number
);
1267 if (priv
->usb_interface
[interface_number
].path
!= NULL
) {
1268 if (api
== USB_API_HID
) {
1269 // HID devices can have multiple collections (COL##) for each MI_## interface
1270 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1271 interface_number
, device_id
);
1272 return LIBUSB_ERROR_ACCESS
;
1274 // In other cases, just use the latest data
1275 safe_free(priv
->usb_interface
[interface_number
].path
);
1278 usbi_dbg("interface[%d] = %s", interface_number
, dev_interface_path
);
1279 priv
->usb_interface
[interface_number
].path
= dev_interface_path
;
1280 priv
->usb_interface
[interface_number
].apib
= &usb_api_backend
[api
];
1281 priv
->usb_interface
[interface_number
].sub_api
= sub_api
;
1282 if ((api
== USB_API_HID
) && (priv
->hid
== NULL
)) {
1283 priv
->hid
= (struct hid_device_priv
*) calloc(1, sizeof(struct hid_device_priv
));
1284 if (priv
->hid
== NULL
)
1285 return LIBUSB_ERROR_NO_MEM
;
1288 return LIBUSB_SUCCESS
;
1291 static int set_hid_interface(struct libusb_context
* ctx
, struct libusb_device
* dev
,
1292 char* dev_interface_path
)
1295 struct windows_device_priv
*priv
= _device_priv(dev
);
1297 if (priv
->hid
== NULL
) {
1298 usbi_err(ctx
, "program assertion failed: parent is not HID");
1299 return LIBUSB_ERROR_NO_DEVICE
;
1301 if (priv
->hid
->nb_interfaces
== USB_MAXINTERFACES
) {
1302 usbi_err(ctx
, "program assertion failed: max USB interfaces reached for HID device");
1303 return LIBUSB_ERROR_NO_DEVICE
;
1305 for (i
=0; i
<priv
->hid
->nb_interfaces
; i
++) {
1306 if (safe_strcmp(priv
->usb_interface
[i
].path
, dev_interface_path
) == 0) {
1307 usbi_dbg("interface[%d] already set to %s", i
, dev_interface_path
);
1308 return LIBUSB_SUCCESS
;
1312 priv
->usb_interface
[priv
->hid
->nb_interfaces
].path
= dev_interface_path
;
1313 priv
->usb_interface
[priv
->hid
->nb_interfaces
].apib
= &usb_api_backend
[USB_API_HID
];
1314 usbi_dbg("interface[%d] = %s", priv
->hid
->nb_interfaces
, dev_interface_path
);
1315 priv
->hid
->nb_interfaces
++;
1316 return LIBUSB_SUCCESS
;
1320 * get_device_list: libusbx backend device enumeration function
1322 static int windows_get_device_list(struct libusb_context
*ctx
, struct discovered_devs
**_discdevs
)
1324 struct discovered_devs
*discdevs
;
1325 HDEVINFO dev_info
= { 0 };
1326 const char* usb_class
[] = {"USB", "NUSB3", "IUSB3"};
1327 SP_DEVINFO_DATA dev_info_data
= { 0 };
1328 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*dev_interface_details
= NULL
;
1330 #define MAX_ENUM_GUIDS 64
1331 const GUID
* guid
[MAX_ENUM_GUIDS
];
1337 int r
= LIBUSB_SUCCESS
;
1339 size_t class_index
= 0;
1340 unsigned int nb_guids
, pass
, i
, j
, ancestor
;
1341 char path
[MAX_PATH_LENGTH
];
1342 char strbuf
[MAX_PATH_LENGTH
];
1343 struct libusb_device
*dev
, *parent_dev
;
1344 struct windows_device_priv
*priv
, *parent_priv
;
1345 char* dev_interface_path
= NULL
;
1346 char* dev_id_path
= NULL
;
1347 unsigned long session_id
;
1348 DWORD size
, reg_type
, port_nr
, install_state
;
1350 WCHAR guid_string_w
[MAX_GUID_STRING_LENGTH
];
1353 // Keep a list of newly allocated devs to unref
1354 libusb_device
** unref_list
;
1355 unsigned int unref_size
= 64;
1356 unsigned int unref_cur
= 0;
1358 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1359 // PASS 2 : (re)enumerate HUBS
1360 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1361 // and list additional USB device interface GUIDs to explore
1362 // PASS 4 : (re)enumerate master USB devices that have a device interface
1363 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1364 // set the device interfaces.
1366 // Init the GUID table
1367 guid
[HCD_PASS
] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER
;
1368 guid
[HUB_PASS
] = &GUID_DEVINTERFACE_USB_HUB
;
1369 guid
[GEN_PASS
] = NULL
;
1370 guid
[DEV_PASS
] = &GUID_DEVINTERFACE_USB_DEVICE
;
1371 HidD_GetHidGuid(&hid_guid
);
1372 guid
[HID_PASS
] = &hid_guid
;
1373 nb_guids
= HID_PASS
+1;
1375 unref_list
= (libusb_device
**) calloc(unref_size
, sizeof(libusb_device
*));
1376 if (unref_list
== NULL
) {
1377 return LIBUSB_ERROR_NO_MEM
;
1380 for (pass
= 0; ((pass
< nb_guids
) && (r
== LIBUSB_SUCCESS
)); pass
++) {
1381 //#define ENUM_DEBUG
1383 const char *passname
[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1384 usbi_dbg("\n#### PROCESSING %ss %s", passname
[(pass
<=HID_PASS
)?pass
:HID_PASS
+1],
1385 (pass
!=GEN_PASS
)?guid_to_string(guid
[pass
]):"");
1387 for (i
= 0; ; i
++) {
1388 // safe loop: free up any (unprotected) dynamic resource
1389 // NB: this is always executed before breaking the loop
1390 safe_free(dev_interface_details
);
1391 safe_free(dev_interface_path
);
1392 safe_free(dev_id_path
);
1393 priv
= parent_priv
= NULL
;
1394 dev
= parent_dev
= NULL
;
1396 // Safe loop: end of loop conditions
1397 if (r
!= LIBUSB_SUCCESS
) {
1400 if ((pass
== HCD_PASS
) && (i
== UINT8_MAX
)) {
1401 usbi_warn(ctx
, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX
);
1404 if (pass
!= GEN_PASS
) {
1405 // Except for GEN, all passes deal with device interfaces
1406 dev_interface_details
= get_interface_details(ctx
, &dev_info
, &dev_info_data
, guid
[pass
], i
);
1407 if (dev_interface_details
== NULL
) {
1410 dev_interface_path
= sanitize_path(dev_interface_details
->DevicePath
);
1411 if (dev_interface_path
== NULL
) {
1412 usbi_warn(ctx
, "could not sanitize device interface path for '%s'", dev_interface_details
->DevicePath
);
1417 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1418 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1419 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1420 for (; class_index
< ARRAYSIZE(usb_class
); class_index
++) {
1421 if (get_devinfo_data(ctx
, &dev_info
, &dev_info_data
, usb_class
[class_index
], i
))
1425 if (class_index
>= ARRAYSIZE(usb_class
))
1429 // Read the Device ID path. This is what we'll use as UID
1430 // Note that if the device is plugged in a different port or hub, the Device ID changes
1431 if (CM_Get_Device_IDA(dev_info_data
.DevInst
, path
, sizeof(path
), 0) != CR_SUCCESS
) {
1432 usbi_warn(ctx
, "could not read the device id path for devinst %X, skipping",
1433 dev_info_data
.DevInst
);
1436 dev_id_path
= sanitize_path(path
);
1437 if (dev_id_path
== NULL
) {
1438 usbi_warn(ctx
, "could not sanitize device id path for devinst %X, skipping",
1439 dev_info_data
.DevInst
);
1443 usbi_dbg("PRO: %s", dev_id_path
);
1446 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1448 if ((pass
>= HUB_PASS
) && (pass
<= GEN_PASS
)) {
1449 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_ADDRESS
,
1450 ®_type
, (BYTE
*)&port_nr
, 4, &size
))
1452 usbi_warn(ctx
, "could not retrieve port number for device '%s', skipping: %s",
1453 dev_id_path
, windows_error_str(0));
1458 // Set API to use or get additional data from generic pass
1459 api
= USB_API_UNSUPPORTED
;
1460 sub_api
= SUB_API_NOTSET
;
1465 // We use the GEN pass to detect driverless devices...
1466 size
= sizeof(strbuf
);
1467 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_DRIVER
,
1468 ®_type
, (BYTE
*)strbuf
, size
, &size
)) {
1469 usbi_info(ctx
, "The following device has no driver: '%s'", dev_id_path
);
1470 usbi_info(ctx
, "libusbx will not be able to access it.");
1472 // ...and to add the additional device interface GUIDs
1473 key
= pSetupDiOpenDevRegKey(dev_info
, &dev_info_data
, DICS_FLAG_GLOBAL
, 0, DIREG_DEV
, KEY_READ
);
1474 if (key
!= INVALID_HANDLE_VALUE
) {
1475 size
= sizeof(guid_string_w
);
1476 s
= pRegQueryValueExW(key
, L
"DeviceInterfaceGUIDs", NULL
, ®_type
,
1477 (BYTE
*)guid_string_w
, &size
);
1479 if (s
== ERROR_SUCCESS
) {
1480 if (nb_guids
>= MAX_ENUM_GUIDS
) {
1481 // If this assert is ever reported, grow a GUID table dynamically
1482 usbi_err(ctx
, "program assertion failed: too many GUIDs");
1483 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW
);
1485 if_guid
= (GUID
*) calloc(1, sizeof(GUID
));
1486 pCLSIDFromString(guid_string_w
, if_guid
);
1487 guid
[nb_guids
++] = if_guid
;
1488 usbi_dbg("extra GUID: %s", guid_to_string(if_guid
));
1496 // Get the API type (after checking that the driver installation is OK)
1497 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info
, &dev_info_data
, SPDRP_INSTALL_STATE
,
1498 ®_type
, (BYTE
*)&install_state
, 4, &size
))
1500 usbi_warn(ctx
, "could not detect installation state of driver for '%s': %s",
1501 dev_id_path
, windows_error_str(0));
1502 } else if (install_state
!= 0) {
1503 usbi_warn(ctx
, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1504 dev_id_path
, install_state
);
1507 get_api_type(ctx
, &dev_info
, &dev_info_data
, &api
, &sub_api
);
1511 // Find parent device (for the passes that need it)
1518 // Go through the ancestors until we see a face we recognize
1520 for (ancestor
= 1; parent_dev
== NULL
; ancestor
++) {
1521 session_id
= get_ancestor_session_id(dev_info_data
.DevInst
, ancestor
);
1522 if (session_id
== 0) {
1525 parent_dev
= usbi_get_device_by_session_id(ctx
, session_id
);
1527 if (parent_dev
== NULL
) {
1528 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path
);
1531 parent_priv
= _device_priv(parent_dev
);
1532 // virtual USB devices are also listed during GEN - don't process these yet
1533 if ( (pass
== GEN_PASS
) && (parent_priv
->apib
->id
!= USB_API_HUB
) ) {
1539 // Create new or match existing device, using the (hashed) device_id as session id
1540 if (pass
<= DEV_PASS
) { // For subsequent passes, we'll lookup the parent
1541 // These are the passes that create "new" devices
1542 session_id
= htab_hash(dev_id_path
);
1543 dev
= usbi_get_device_by_session_id(ctx
, session_id
);
1545 if (pass
== DEV_PASS
) {
1546 // This can occur if the OS only reports a newly plugged device after we started enum
1547 usbi_warn(ctx
, "'%s' was only detected in late pass (newly connected device?)"
1548 " - ignoring", dev_id_path
);
1551 usbi_dbg("allocating new device for session [%X]", session_id
);
1552 if ((dev
= usbi_alloc_device(ctx
, session_id
)) == NULL
) {
1553 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1555 windows_device_priv_init(dev
);
1556 // Keep track of devices that need unref
1557 unref_list
[unref_cur
++] = dev
;
1558 if (unref_cur
>= unref_size
) {
1560 unref_list
= usbi_reallocf(unref_list
, unref_size
*sizeof(libusb_device
*));
1561 if (unref_list
== NULL
) {
1562 usbi_err(ctx
, "could not realloc list for unref - aborting.");
1563 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1567 usbi_dbg("found existing device for session [%X] (%d.%d)",
1568 session_id
, dev
->bus_number
, dev
->device_address
);
1570 priv
= _device_priv(dev
);
1576 dev
->bus_number
= (uint8_t)(i
+ 1); // bus 0 is reserved for disconnected
1577 dev
->device_address
= 0;
1578 dev
->num_configurations
= 0;
1579 priv
->apib
= &usb_api_backend
[USB_API_HUB
];
1580 priv
->sub_api
= SUB_API_NOTSET
;
1581 priv
->depth
= UINT8_MAX
; // Overflow to 0 for HCD Hubs
1582 priv
->path
= dev_interface_path
; dev_interface_path
= NULL
;
1586 // If the device has already been setup, don't do it again
1587 if (priv
->path
!= NULL
)
1589 // Take care of API initialization
1590 priv
->path
= dev_interface_path
; dev_interface_path
= NULL
;
1591 priv
->apib
= &usb_api_backend
[api
];
1592 priv
->sub_api
= sub_api
;
1594 case USB_API_COMPOSITE
:
1598 priv
->hid
= calloc(1, sizeof(struct hid_device_priv
));
1599 if (priv
->hid
== NULL
) {
1600 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1602 priv
->hid
->nb_interfaces
= 0;
1605 // For other devices, the first interface is the same as the device
1606 priv
->usb_interface
[0].path
= (char*) calloc(safe_strlen(priv
->path
)+1, 1);
1607 if (priv
->usb_interface
[0].path
!= NULL
) {
1608 safe_strcpy(priv
->usb_interface
[0].path
, safe_strlen(priv
->path
)+1, priv
->path
);
1610 usbi_warn(ctx
, "could not duplicate interface path '%s'", priv
->path
);
1612 // The following is needed if we want API calls to work for both simple
1613 // and composite devices.
1614 for(j
=0; j
<USB_MAXINTERFACES
; j
++) {
1615 priv
->usb_interface
[j
].apib
= &usb_api_backend
[api
];
1621 r
= init_device(dev
, parent_dev
, (uint8_t)port_nr
, dev_id_path
, dev_info_data
.DevInst
);
1622 if (r
== LIBUSB_SUCCESS
) {
1623 // Append device to the list of discovered devices
1624 discdevs
= discovered_devs_append(*_discdevs
, dev
);
1626 LOOP_BREAK(LIBUSB_ERROR_NO_MEM
);
1628 *_discdevs
= discdevs
;
1629 } else if (r
== LIBUSB_ERROR_NO_DEVICE
) {
1630 // This can occur if the device was disconnected but Windows hasn't
1631 // refreshed its enumeration yet - in that case, we ignore the device
1635 default: // HID_PASS and later
1636 if (parent_priv
->apib
->id
== USB_API_HID
) {
1637 usbi_dbg("setting HID interface for [%lX]:", parent_dev
->session_data
);
1638 r
= set_hid_interface(ctx
, parent_dev
, dev_interface_path
);
1639 if (r
!= LIBUSB_SUCCESS
) LOOP_BREAK(r
);
1640 dev_interface_path
= NULL
;
1641 } else if (parent_priv
->apib
->id
== USB_API_COMPOSITE
) {
1642 usbi_dbg("setting composite interface for [%lX]:", parent_dev
->session_data
);
1643 switch (set_composite_interface(ctx
, parent_dev
, dev_interface_path
, dev_id_path
, api
, sub_api
)) {
1644 case LIBUSB_SUCCESS
:
1645 dev_interface_path
= NULL
;
1647 case LIBUSB_ERROR_ACCESS
:
1648 // interface has already been set => make sure dev_interface_path is freed then
1660 // Free any additional GUIDs
1661 for (pass
= HID_PASS
+1; pass
< nb_guids
; pass
++) {
1662 safe_free(guid
[pass
]);
1665 // Unref newly allocated devs
1666 for (i
=0; i
<unref_cur
; i
++) {
1667 safe_unref_device(unref_list
[i
]);
1669 safe_free(unref_list
);
1675 * exit: libusbx backend deinitialization function
1677 static void windows_exit(void)
1681 char sem_name
[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1683 sprintf(sem_name
, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1684 semaphore
= CreateSemaphoreA(NULL
, 1, 1, sem_name
);
1685 if (semaphore
== NULL
) {
1689 // A successful wait brings our semaphore count to 0 (unsignaled)
1690 // => any concurent wait stalls until the semaphore release
1691 if (WaitForSingleObject(semaphore
, INFINITE
) != WAIT_OBJECT_0
) {
1692 CloseHandle(semaphore
);
1696 // Only works if exits and inits are balanced exactly
1697 if (--concurrent_usage
< 0) { // Last exit
1698 for (i
=0; i
<USB_API_MAX
; i
++) {
1699 usb_api_backend
[i
].exit(SUB_API_NOTSET
);
1704 SetEvent(timer_request
[1]); // actually the signal to quit the thread.
1705 if (WAIT_OBJECT_0
!= WaitForSingleObject(timer_thread
, INFINITE
)) {
1706 usbi_dbg("could not wait for timer thread to quit");
1707 TerminateThread(timer_thread
, 1);
1709 CloseHandle(timer_thread
);
1710 timer_thread
= NULL
;
1712 for (i
= 0; i
< 2; i
++) {
1713 if (timer_request
[i
]) {
1714 CloseHandle(timer_request
[i
]);
1715 timer_request
[i
] = NULL
;
1718 if (timer_response
) {
1719 CloseHandle(timer_response
);
1720 timer_response
= NULL
;
1723 CloseHandle(timer_mutex
);
1729 ReleaseSemaphore(semaphore
, 1, NULL
); // increase count back to 1
1730 CloseHandle(semaphore
);
1733 static int windows_get_device_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, int *host_endian
)
1735 struct windows_device_priv
*priv
= _device_priv(dev
);
1737 memcpy(buffer
, &(priv
->dev_descriptor
), DEVICE_DESC_LENGTH
);
1740 return LIBUSB_SUCCESS
;
1743 static int windows_get_config_descriptor(struct libusb_device
*dev
, uint8_t config_index
, unsigned char *buffer
, size_t len
, int *host_endian
)
1745 struct windows_device_priv
*priv
= _device_priv(dev
);
1746 PUSB_CONFIGURATION_DESCRIPTOR config_header
;
1749 // config index is zero based
1750 if (config_index
>= dev
->num_configurations
)
1751 return LIBUSB_ERROR_INVALID_PARAM
;
1753 if ((priv
->config_descriptor
== NULL
) || (priv
->config_descriptor
[config_index
] == NULL
))
1754 return LIBUSB_ERROR_NOT_FOUND
;
1756 config_header
= (PUSB_CONFIGURATION_DESCRIPTOR
)priv
->config_descriptor
[config_index
];
1758 size
= min(config_header
->wTotalLength
, len
);
1759 memcpy(buffer
, priv
->config_descriptor
[config_index
], size
);
1765 * return the cached copy of the active config descriptor
1767 static int windows_get_active_config_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, size_t len
, int *host_endian
)
1769 struct windows_device_priv
*priv
= _device_priv(dev
);
1771 if (priv
->active_config
== 0)
1772 return LIBUSB_ERROR_NOT_FOUND
;
1774 // config index is zero based
1775 return windows_get_config_descriptor(dev
, (uint8_t)(priv
->active_config
-1), buffer
, len
, host_endian
);
1778 static int windows_open(struct libusb_device_handle
*dev_handle
)
1780 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1781 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
1783 if (priv
->apib
== NULL
) {
1784 usbi_err(ctx
, "program assertion failed - device is not initialized");
1785 return LIBUSB_ERROR_NO_DEVICE
;
1788 return priv
->apib
->open(SUB_API_NOTSET
, dev_handle
);
1791 static void windows_close(struct libusb_device_handle
*dev_handle
)
1793 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1795 priv
->apib
->close(SUB_API_NOTSET
, dev_handle
);
1798 static int windows_get_configuration(struct libusb_device_handle
*dev_handle
, int *config
)
1800 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1802 if (priv
->active_config
== 0) {
1804 return LIBUSB_ERROR_NOT_FOUND
;
1807 *config
= priv
->active_config
;
1808 return LIBUSB_SUCCESS
;
1812 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1813 * does not currently expose a service that allows higher-level drivers to set
1814 * the configuration."
1816 static int windows_set_configuration(struct libusb_device_handle
*dev_handle
, int config
)
1818 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1819 int r
= LIBUSB_SUCCESS
;
1821 if (config
>= USB_MAXCONFIG
)
1822 return LIBUSB_ERROR_INVALID_PARAM
;
1824 r
= libusb_control_transfer(dev_handle
, LIBUSB_ENDPOINT_OUT
|
1825 LIBUSB_REQUEST_TYPE_STANDARD
| LIBUSB_RECIPIENT_DEVICE
,
1826 LIBUSB_REQUEST_SET_CONFIGURATION
, (uint16_t)config
,
1829 if (r
== LIBUSB_SUCCESS
) {
1830 priv
->active_config
= (uint8_t)config
;
1835 static int windows_claim_interface(struct libusb_device_handle
*dev_handle
, int iface
)
1837 int r
= LIBUSB_SUCCESS
;
1838 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1840 if (iface
>= USB_MAXINTERFACES
)
1841 return LIBUSB_ERROR_INVALID_PARAM
;
1843 safe_free(priv
->usb_interface
[iface
].endpoint
);
1844 priv
->usb_interface
[iface
].nb_endpoints
= 0;
1846 r
= priv
->apib
->claim_interface(SUB_API_NOTSET
, dev_handle
, iface
);
1848 if (r
== LIBUSB_SUCCESS
) {
1849 r
= windows_assign_endpoints(dev_handle
, iface
, 0);
1855 static int windows_set_interface_altsetting(struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
1857 int r
= LIBUSB_SUCCESS
;
1858 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1860 safe_free(priv
->usb_interface
[iface
].endpoint
);
1861 priv
->usb_interface
[iface
].nb_endpoints
= 0;
1863 r
= priv
->apib
->set_interface_altsetting(SUB_API_NOTSET
, dev_handle
, iface
, altsetting
);
1865 if (r
== LIBUSB_SUCCESS
) {
1866 r
= windows_assign_endpoints(dev_handle
, iface
, altsetting
);
1872 static int windows_release_interface(struct libusb_device_handle
*dev_handle
, int iface
)
1874 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1876 return priv
->apib
->release_interface(SUB_API_NOTSET
, dev_handle
, iface
);
1879 static int windows_clear_halt(struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
1881 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1882 return priv
->apib
->clear_halt(SUB_API_NOTSET
, dev_handle
, endpoint
);
1885 static int windows_reset_device(struct libusb_device_handle
*dev_handle
)
1887 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
1888 return priv
->apib
->reset_device(SUB_API_NOTSET
, dev_handle
);
1891 // The 3 functions below are unlikely to ever get supported on Windows
1892 static int windows_kernel_driver_active(struct libusb_device_handle
*dev_handle
, int iface
)
1894 return LIBUSB_ERROR_NOT_SUPPORTED
;
1897 static int windows_attach_kernel_driver(struct libusb_device_handle
*dev_handle
, int iface
)
1899 return LIBUSB_ERROR_NOT_SUPPORTED
;
1902 static int windows_detach_kernel_driver(struct libusb_device_handle
*dev_handle
, int iface
)
1904 return LIBUSB_ERROR_NOT_SUPPORTED
;
1907 static void windows_destroy_device(struct libusb_device
*dev
)
1909 windows_device_priv_release(dev
);
1912 static void windows_clear_transfer_priv(struct usbi_transfer
*itransfer
)
1914 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1916 usbi_free_fd(&transfer_priv
->pollable_fd
);
1917 safe_free(transfer_priv
->hid_buffer
);
1918 // When auto claim is in use, attempt to release the auto-claimed interface
1919 auto_release(itransfer
);
1922 static int submit_bulk_transfer(struct usbi_transfer
*itransfer
)
1924 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1925 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1926 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1927 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1930 r
= priv
->apib
->submit_bulk_transfer(SUB_API_NOTSET
, itransfer
);
1931 if (r
!= LIBUSB_SUCCESS
) {
1935 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
,
1936 (short)(IS_XFERIN(transfer
) ? POLLIN
: POLLOUT
));
1938 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1939 return LIBUSB_SUCCESS
;
1942 static int submit_iso_transfer(struct usbi_transfer
*itransfer
)
1944 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1945 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1946 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1947 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1950 r
= priv
->apib
->submit_iso_transfer(SUB_API_NOTSET
, itransfer
);
1951 if (r
!= LIBUSB_SUCCESS
) {
1955 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
,
1956 (short)(IS_XFERIN(transfer
) ? POLLIN
: POLLOUT
));
1958 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1959 return LIBUSB_SUCCESS
;
1962 static int submit_control_transfer(struct usbi_transfer
*itransfer
)
1964 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1965 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
1966 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
1967 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
1970 r
= priv
->apib
->submit_control_transfer(SUB_API_NOTSET
, itransfer
);
1971 if (r
!= LIBUSB_SUCCESS
) {
1975 usbi_add_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
, POLLIN
);
1977 itransfer
->flags
|= USBI_TRANSFER_UPDATED_FDS
;
1978 return LIBUSB_SUCCESS
;
1982 static int windows_submit_transfer(struct usbi_transfer
*itransfer
)
1984 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1986 switch (transfer
->type
) {
1987 case LIBUSB_TRANSFER_TYPE_CONTROL
:
1988 return submit_control_transfer(itransfer
);
1989 case LIBUSB_TRANSFER_TYPE_BULK
:
1990 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
1991 if (IS_XFEROUT(transfer
) &&
1992 transfer
->flags
& LIBUSB_TRANSFER_ADD_ZERO_PACKET
)
1993 return LIBUSB_ERROR_NOT_SUPPORTED
;
1994 return submit_bulk_transfer(itransfer
);
1995 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
1996 return submit_iso_transfer(itransfer
);
1998 usbi_err(TRANSFER_CTX(transfer
), "unknown endpoint type %d", transfer
->type
);
1999 return LIBUSB_ERROR_INVALID_PARAM
;
2003 static int windows_abort_control(struct usbi_transfer
*itransfer
)
2005 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2006 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2008 return priv
->apib
->abort_control(SUB_API_NOTSET
, itransfer
);
2011 static int windows_abort_transfers(struct usbi_transfer
*itransfer
)
2013 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2014 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2016 return priv
->apib
->abort_transfers(SUB_API_NOTSET
, itransfer
);
2019 static int windows_cancel_transfer(struct usbi_transfer
*itransfer
)
2021 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2023 switch (transfer
->type
) {
2024 case LIBUSB_TRANSFER_TYPE_CONTROL
:
2025 return windows_abort_control(itransfer
);
2026 case LIBUSB_TRANSFER_TYPE_BULK
:
2027 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
2028 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
2029 return windows_abort_transfers(itransfer
);
2031 usbi_err(ITRANSFER_CTX(itransfer
), "unknown endpoint type %d", transfer
->type
);
2032 return LIBUSB_ERROR_INVALID_PARAM
;
2036 static void windows_transfer_callback(struct usbi_transfer
*itransfer
, uint32_t io_result
, uint32_t io_size
)
2038 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2039 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2040 int status
, istatus
;
2042 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result
, io_size
);
2046 status
= priv
->apib
->copy_transfer_data(SUB_API_NOTSET
, itransfer
, io_size
);
2048 case ERROR_GEN_FAILURE
:
2049 usbi_dbg("detected endpoint stall");
2050 status
= LIBUSB_TRANSFER_STALL
;
2052 case ERROR_SEM_TIMEOUT
:
2053 usbi_dbg("detected semaphore timeout");
2054 status
= LIBUSB_TRANSFER_TIMED_OUT
;
2056 case ERROR_OPERATION_ABORTED
:
2057 istatus
= priv
->apib
->copy_transfer_data(SUB_API_NOTSET
, itransfer
, io_size
);
2058 if (istatus
!= LIBUSB_TRANSFER_COMPLETED
) {
2059 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus
);
2061 if (itransfer
->flags
& USBI_TRANSFER_TIMED_OUT
) {
2062 usbi_dbg("detected timeout");
2063 status
= LIBUSB_TRANSFER_TIMED_OUT
;
2065 usbi_dbg("detected operation aborted");
2066 status
= LIBUSB_TRANSFER_CANCELLED
;
2070 usbi_err(ITRANSFER_CTX(itransfer
), "detected I/O error %d: %s", io_result
, windows_error_str(0));
2071 status
= LIBUSB_TRANSFER_ERROR
;
2074 windows_clear_transfer_priv(itransfer
); // Cancel polling
2075 usbi_handle_transfer_completion(itransfer
, (enum libusb_transfer_status
)status
);
2078 static void windows_handle_callback (struct usbi_transfer
*itransfer
, uint32_t io_result
, uint32_t io_size
)
2080 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2082 switch (transfer
->type
) {
2083 case LIBUSB_TRANSFER_TYPE_CONTROL
:
2084 case LIBUSB_TRANSFER_TYPE_BULK
:
2085 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
2086 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
2087 windows_transfer_callback (itransfer
, io_result
, io_size
);
2090 usbi_err(ITRANSFER_CTX(itransfer
), "unknown endpoint type %d", transfer
->type
);
2094 static int windows_handle_events(struct libusb_context
*ctx
, struct pollfd
*fds
, POLL_NFDS_TYPE nfds
, int num_ready
)
2096 struct windows_transfer_priv
* transfer_priv
= NULL
;
2097 POLL_NFDS_TYPE i
= 0;
2099 struct usbi_transfer
*transfer
;
2100 DWORD io_size
, io_result
;
2102 usbi_mutex_lock(&ctx
->open_devs_lock
);
2103 for (i
= 0; i
< nfds
&& num_ready
> 0; i
++) {
2105 usbi_dbg("checking fd %d with revents = %04x", fds
[i
].fd
, fds
[i
].revents
);
2107 if (!fds
[i
].revents
) {
2113 // Because a Windows OVERLAPPED is used for poll emulation,
2114 // a pollable fd is created and stored with each transfer
2115 usbi_mutex_lock(&ctx
->flying_transfers_lock
);
2116 list_for_each_entry(transfer
, &ctx
->flying_transfers
, list
, struct usbi_transfer
) {
2117 transfer_priv
= usbi_transfer_get_os_priv(transfer
);
2118 if (transfer_priv
->pollable_fd
.fd
== fds
[i
].fd
) {
2123 usbi_mutex_unlock(&ctx
->flying_transfers_lock
);
2126 // Handle async requests that completed synchronously first
2127 if (HasOverlappedIoCompletedSync(transfer_priv
->pollable_fd
.overlapped
)) {
2128 io_result
= NO_ERROR
;
2129 io_size
= (DWORD
)transfer_priv
->pollable_fd
.overlapped
->InternalHigh
;
2130 // Regular async overlapped
2131 } else if (GetOverlappedResult(transfer_priv
->pollable_fd
.handle
,
2132 transfer_priv
->pollable_fd
.overlapped
, &io_size
, false)) {
2133 io_result
= NO_ERROR
;
2135 io_result
= GetLastError();
2137 usbi_remove_pollfd(ctx
, transfer_priv
->pollable_fd
.fd
);
2138 // let handle_callback free the event using the transfer wfd
2139 // If you don't use the transfer wfd, you run a risk of trying to free a
2140 // newly allocated wfd that took the place of the one from the transfer.
2141 windows_handle_callback(transfer
, io_result
, io_size
);
2143 usbi_err(ctx
, "could not find a matching transfer for fd %x", fds
[i
]);
2144 return LIBUSB_ERROR_NOT_FOUND
;
2148 usbi_mutex_unlock(&ctx
->open_devs_lock
);
2149 return LIBUSB_SUCCESS
;
2153 * Monotonic and real time functions
2155 unsigned __stdcall
windows_clock_gettime_threaded(void* param
)
2157 LARGE_INTEGER hires_counter
, li_frequency
;
2161 // Init - find out if we have access to a monotonic (hires) timer
2162 if (!QueryPerformanceFrequency(&li_frequency
)) {
2163 usbi_dbg("no hires timer available on this platform");
2164 hires_frequency
= 0;
2165 hires_ticks_to_ps
= UINT64_C(0);
2167 hires_frequency
= li_frequency
.QuadPart
;
2168 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2169 // to picoseconds to compute the tv_nsecs part in clock_gettime
2170 hires_ticks_to_ps
= UINT64_C(1000000000000) / hires_frequency
;
2171 usbi_dbg("hires timer available (Frequency: %"PRIu64
" Hz)", hires_frequency
);
2174 // Main loop - wait for requests
2176 timer_index
= WaitForMultipleObjects(2, timer_request
, FALSE
, INFINITE
) - WAIT_OBJECT_0
;
2177 if ( (timer_index
!= 0) && (timer_index
!= 1) ) {
2178 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2181 if (request_count
[timer_index
] == 0) {
2182 // Request already handled
2183 ResetEvent(timer_request
[timer_index
]);
2184 // There's still a possiblity that a thread sends a request between the
2185 // time we test request_count[] == 0 and we reset the event, in which case
2186 // the request would be ignored. The simple solution to that is to test
2187 // request_count again and process requests if non zero.
2188 if (request_count
[timer_index
] == 0)
2191 switch (timer_index
) {
2193 WaitForSingleObject(timer_mutex
, INFINITE
);
2194 // Requests to this thread are for hires always
2195 if (QueryPerformanceCounter(&hires_counter
) != 0) {
2196 timer_tp
.tv_sec
= (long)(hires_counter
.QuadPart
/ hires_frequency
);
2197 timer_tp
.tv_nsec
= (long)(((hires_counter
.QuadPart
% hires_frequency
)/1000) * hires_ticks_to_ps
);
2199 // Fallback to real-time if we can't get monotonic value
2200 // Note that real-time clock does not wait on the mutex or this thread.
2201 windows_clock_gettime(USBI_CLOCK_REALTIME
, &timer_tp
);
2203 ReleaseMutex(timer_mutex
);
2205 nb_responses
= InterlockedExchange((LONG
*)&request_count
[0], 0);
2207 && (ReleaseSemaphore(timer_response
, nb_responses
, NULL
) == 0) ) {
2208 usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0));
2211 case 1: // time to quit
2212 usbi_dbg("timer thread quitting");
2218 static int windows_clock_gettime(int clk_id
, struct timespec
*tp
)
2221 ULARGE_INTEGER rtime
;
2224 case USBI_CLOCK_MONOTONIC
:
2225 if (hires_frequency
!= 0) {
2227 InterlockedIncrement((LONG
*)&request_count
[0]);
2228 SetEvent(timer_request
[0]);
2229 r
= WaitForSingleObject(timer_response
, TIMER_REQUEST_RETRY_MS
);
2232 WaitForSingleObject(timer_mutex
, INFINITE
);
2234 ReleaseMutex(timer_mutex
);
2235 return LIBUSB_SUCCESS
;
2237 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2238 break; // Retry until successful
2240 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2241 return LIBUSB_ERROR_OTHER
;
2245 // Fall through and return real-time if monotonic was not detected @ timer init
2246 case USBI_CLOCK_REALTIME
:
2247 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2248 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2249 // Note however that our resolution is bounded by the Windows system time
2250 // functions and is at best of the order of 1 ms (or, usually, worse)
2251 GetSystemTimeAsFileTime(&filetime
);
2252 rtime
.LowPart
= filetime
.dwLowDateTime
;
2253 rtime
.HighPart
= filetime
.dwHighDateTime
;
2254 rtime
.QuadPart
-= epoch_time
;
2255 tp
->tv_sec
= (long)(rtime
.QuadPart
/ 10000000);
2256 tp
->tv_nsec
= (long)((rtime
.QuadPart
% 10000000)*100);
2257 return LIBUSB_SUCCESS
;
2259 return LIBUSB_ERROR_INVALID_PARAM
;
2264 // NB: MSVC6 does not support named initializers.
2265 const struct usbi_os_backend windows_backend
= {
2267 USBI_CAP_HAS_HID_ACCESS
,
2271 windows_get_device_list
,
2275 windows_get_device_descriptor
,
2276 windows_get_active_config_descriptor
,
2277 windows_get_config_descriptor
,
2278 NULL
, /* get_config_descriptor_by_value() */
2280 windows_get_configuration
,
2281 windows_set_configuration
,
2282 windows_claim_interface
,
2283 windows_release_interface
,
2285 windows_set_interface_altsetting
,
2287 windows_reset_device
,
2289 windows_kernel_driver_active
,
2290 windows_detach_kernel_driver
,
2291 windows_attach_kernel_driver
,
2293 windows_destroy_device
,
2295 windows_submit_transfer
,
2296 windows_cancel_transfer
,
2297 windows_clear_transfer_priv
,
2299 windows_handle_events
,
2301 windows_clock_gettime
,
2302 #if defined(USBI_TIMERFD_AVAILABLE)
2305 sizeof(struct windows_device_priv
),
2306 sizeof(struct windows_device_handle_priv
),
2307 sizeof(struct windows_transfer_priv
),
2315 static int unsupported_init(int sub_api
, struct libusb_context
*ctx
) {
2316 return LIBUSB_SUCCESS
;
2318 static int unsupported_exit(int sub_api
) {
2319 return LIBUSB_SUCCESS
;
2321 static int unsupported_open(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2322 PRINT_UNSUPPORTED_API(open
);
2324 static void unsupported_close(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2325 usbi_dbg("unsupported API call for 'close'");
2327 static int unsupported_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2328 PRINT_UNSUPPORTED_API(configure_endpoints
);
2330 static int unsupported_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2331 PRINT_UNSUPPORTED_API(claim_interface
);
2333 static int unsupported_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
) {
2334 PRINT_UNSUPPORTED_API(set_interface_altsetting
);
2336 static int unsupported_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2337 PRINT_UNSUPPORTED_API(release_interface
);
2339 static int unsupported_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
) {
2340 PRINT_UNSUPPORTED_API(clear_halt
);
2342 static int unsupported_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
) {
2343 PRINT_UNSUPPORTED_API(reset_device
);
2345 static int unsupported_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2346 PRINT_UNSUPPORTED_API(submit_bulk_transfer
);
2348 static int unsupported_submit_iso_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2349 PRINT_UNSUPPORTED_API(submit_iso_transfer
);
2351 static int unsupported_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
2352 PRINT_UNSUPPORTED_API(submit_control_transfer
);
2354 static int unsupported_abort_control(int sub_api
, struct usbi_transfer
*itransfer
) {
2355 PRINT_UNSUPPORTED_API(abort_control
);
2357 static int unsupported_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
) {
2358 PRINT_UNSUPPORTED_API(abort_transfers
);
2360 static int unsupported_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
) {
2361 PRINT_UNSUPPORTED_API(copy_transfer_data
);
2363 static int common_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
) {
2364 return LIBUSB_SUCCESS
;
2366 // These names must be uppercase
2367 const char* hub_driver_names
[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2368 const char* composite_driver_names
[] = {"USBCCGP"};
2369 const char* winusbx_driver_names
[] = WINUSBX_DRV_NAMES
;
2370 const char* hid_driver_names
[] = {"HIDUSB", "MOUHID", "KBDHID"};
2371 const struct windows_usb_api_backend usb_api_backend
[USB_API_MAX
] = {
2373 USB_API_UNSUPPORTED
,
2381 unsupported_configure_endpoints
,
2382 unsupported_claim_interface
,
2383 unsupported_set_interface_altsetting
,
2384 unsupported_release_interface
,
2385 unsupported_clear_halt
,
2386 unsupported_reset_device
,
2387 unsupported_submit_bulk_transfer
,
2388 unsupported_submit_iso_transfer
,
2389 unsupported_submit_control_transfer
,
2390 unsupported_abort_control
,
2391 unsupported_abort_transfers
,
2392 unsupported_copy_transfer_data
,
2397 ARRAYSIZE(hub_driver_names
),
2402 unsupported_configure_endpoints
,
2403 unsupported_claim_interface
,
2404 unsupported_set_interface_altsetting
,
2405 unsupported_release_interface
,
2406 unsupported_clear_halt
,
2407 unsupported_reset_device
,
2408 unsupported_submit_bulk_transfer
,
2409 unsupported_submit_iso_transfer
,
2410 unsupported_submit_control_transfer
,
2411 unsupported_abort_control
,
2412 unsupported_abort_transfers
,
2413 unsupported_copy_transfer_data
,
2417 composite_driver_names
,
2418 ARRAYSIZE(composite_driver_names
),
2423 common_configure_endpoints
,
2424 composite_claim_interface
,
2425 composite_set_interface_altsetting
,
2426 composite_release_interface
,
2427 composite_clear_halt
,
2428 composite_reset_device
,
2429 composite_submit_bulk_transfer
,
2430 composite_submit_iso_transfer
,
2431 composite_submit_control_transfer
,
2432 composite_abort_control
,
2433 composite_abort_transfers
,
2434 composite_copy_transfer_data
,
2438 winusbx_driver_names
,
2439 ARRAYSIZE(winusbx_driver_names
),
2444 winusbx_configure_endpoints
,
2445 winusbx_claim_interface
,
2446 winusbx_set_interface_altsetting
,
2447 winusbx_release_interface
,
2449 winusbx_reset_device
,
2450 winusbx_submit_bulk_transfer
,
2451 unsupported_submit_iso_transfer
,
2452 winusbx_submit_control_transfer
,
2453 winusbx_abort_control
,
2454 winusbx_abort_transfers
,
2455 winusbx_copy_transfer_data
,
2460 ARRAYSIZE(hid_driver_names
),
2465 common_configure_endpoints
,
2466 hid_claim_interface
,
2467 hid_set_interface_altsetting
,
2468 hid_release_interface
,
2471 hid_submit_bulk_transfer
,
2472 unsupported_submit_iso_transfer
,
2473 hid_submit_control_transfer
,
2474 hid_abort_transfers
,
2475 hid_abort_transfers
,
2476 hid_copy_transfer_data
,
2482 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2484 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2485 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2487 static int winusbx_init(int sub_api
, struct libusb_context
*ctx
)
2490 bool native_winusb
= false;
2492 KLIB_VERSION LibK_Version
;
2493 LibK_GetProcAddress_t pLibK_GetProcAddress
= NULL
;
2494 LibK_GetVersion_t pLibK_GetVersion
= NULL
;
2496 h
= GetModuleHandleA("libusbK");
2498 h
= LoadLibraryA("libusbK");
2501 usbi_info(ctx
, "libusbK DLL is not available, will use native WinUSB");
2502 h
= GetModuleHandleA("WinUSB");
2504 h
= LoadLibraryA("WinUSB");
2506 usbi_warn(ctx
, "WinUSB DLL is not available either,\n"
2507 "you will not be able to access devices outside of enumeration");
2508 return LIBUSB_ERROR_NOT_FOUND
;
2511 usbi_dbg("using libusbK DLL for universal access");
2512 pLibK_GetVersion
= (LibK_GetVersion_t
) GetProcAddress(h
, "LibK_GetVersion");
2513 if (pLibK_GetVersion
!= NULL
) {
2514 pLibK_GetVersion(&LibK_Version
);
2515 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version
.Major
, LibK_Version
.Minor
,
2516 LibK_Version
.Micro
, LibK_Version
.Nano
);
2518 pLibK_GetProcAddress
= (LibK_GetProcAddress_t
) GetProcAddress(h
, "LibK_GetProcAddress");
2519 if (pLibK_GetProcAddress
== NULL
) {
2520 usbi_err(ctx
, "LibK_GetProcAddress() not found in libusbK DLL");
2521 return LIBUSB_ERROR_NOT_FOUND
;
2524 native_winusb
= (pLibK_GetProcAddress
== NULL
);
2525 for (i
=SUB_API_LIBUSBK
; i
<SUB_API_MAX
; i
++) {
2526 WinUSBX_Set(AbortPipe
);
2527 WinUSBX_Set(ControlTransfer
);
2528 WinUSBX_Set(FlushPipe
);
2530 WinUSBX_Set(GetAssociatedInterface
);
2531 WinUSBX_Set(GetCurrentAlternateSetting
);
2532 WinUSBX_Set(GetDescriptor
);
2533 WinUSBX_Set(GetOverlappedResult
);
2534 WinUSBX_Set(GetPipePolicy
);
2535 WinUSBX_Set(GetPowerPolicy
);
2536 WinUSBX_Set(Initialize
);
2537 WinUSBX_Set(QueryDeviceInformation
);
2538 WinUSBX_Set(QueryInterfaceSettings
);
2539 WinUSBX_Set(QueryPipe
);
2540 WinUSBX_Set(ReadPipe
);
2541 WinUSBX_Set(ResetPipe
);
2542 WinUSBX_Set(SetCurrentAlternateSetting
);
2543 WinUSBX_Set(SetPipePolicy
);
2544 WinUSBX_Set(SetPowerPolicy
);
2545 WinUSBX_Set(WritePipe
);
2546 if (!native_winusb
) {
2547 WinUSBX_Set(ResetDevice
);
2549 if (WinUSBX
[i
].Initialize
!= NULL
) {
2550 WinUSBX
[i
].initialized
= true;
2551 usbi_dbg("initalized sub API %s", sub_api_name
[i
]);
2553 usbi_warn(ctx
, "Failed to initalize sub API %s", sub_api_name
[i
]);
2554 WinUSBX
[i
].initialized
= false;
2557 return LIBUSB_SUCCESS
;
2560 static int winusbx_exit(int sub_api
)
2562 return LIBUSB_SUCCESS
;
2565 // NB: open and close must ensure that they only handle interface of
2566 // the right API type, as these functions can be called wholesale from
2567 // composite_open(), with interfaces belonging to different APIs
2568 static int winusbx_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
2570 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2571 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2572 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2577 CHECK_WINUSBX_AVAILABLE(sub_api
);
2579 // WinUSB requires a seperate handle for each interface
2580 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
2581 if ( (priv
->usb_interface
[i
].path
!= NULL
)
2582 && (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
) ) {
2583 file_handle
= CreateFileA(priv
->usb_interface
[i
].path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
2584 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2585 if (file_handle
== INVALID_HANDLE_VALUE
) {
2586 usbi_err(ctx
, "could not open device %s (interface %d): %s", priv
->usb_interface
[i
].path
, i
, windows_error_str(0));
2587 switch(GetLastError()) {
2588 case ERROR_FILE_NOT_FOUND
: // The device was disconnected
2589 return LIBUSB_ERROR_NO_DEVICE
;
2590 case ERROR_ACCESS_DENIED
:
2591 return LIBUSB_ERROR_ACCESS
;
2593 return LIBUSB_ERROR_IO
;
2596 handle_priv
->interface_handle
[i
].dev_handle
= file_handle
;
2600 return LIBUSB_SUCCESS
;
2603 static void winusbx_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
2605 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2606 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2610 if (sub_api
== SUB_API_NOTSET
)
2611 sub_api
= priv
->sub_api
;
2612 if (!WinUSBX
[sub_api
].initialized
)
2615 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
2616 if (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
) {
2617 file_handle
= handle_priv
->interface_handle
[i
].dev_handle
;
2618 if ( (file_handle
!= 0) && (file_handle
!= INVALID_HANDLE_VALUE
)) {
2619 CloseHandle(file_handle
);
2625 static int winusbx_configure_endpoints(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2627 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2628 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2629 HANDLE winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2632 uint8_t endpoint_address
;
2635 CHECK_WINUSBX_AVAILABLE(sub_api
);
2637 // With handle and enpoints set (in parent), we can setup the default pipe properties
2638 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2639 for (i
=-1; i
<priv
->usb_interface
[iface
].nb_endpoints
; i
++) {
2640 endpoint_address
=(i
==-1)?0:priv
->usb_interface
[iface
].endpoint
[i
];
2641 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2642 PIPE_TRANSFER_TIMEOUT
, sizeof(ULONG
), &timeout
)) {
2643 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address
);
2645 if ((i
== -1) || (sub_api
== SUB_API_LIBUSB0
)) {
2646 continue; // Other policies don't apply to control endpoint or libusb0
2649 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2650 SHORT_PACKET_TERMINATE
, sizeof(UCHAR
), &policy
)) {
2651 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address
);
2653 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2654 IGNORE_SHORT_PACKETS
, sizeof(UCHAR
), &policy
)) {
2655 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address
);
2658 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2659 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2660 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2661 ALLOW_PARTIAL_READS
, sizeof(UCHAR
), &policy
)) {
2662 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address
);
2664 if (!WinUSBX
[sub_api
].SetPipePolicy(winusb_handle
, endpoint_address
,
2665 AUTO_CLEAR_STALL
, sizeof(UCHAR
), &policy
)) {
2666 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address
);
2670 return LIBUSB_SUCCESS
;
2673 static int winusbx_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2675 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2676 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2677 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2678 bool is_using_usbccgp
= (priv
->apib
->id
== USB_API_COMPOSITE
);
2679 HANDLE file_handle
, winusb_handle
;
2682 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*dev_interface_details
= NULL
;
2683 HDEVINFO dev_info
= INVALID_HANDLE_VALUE
;
2684 SP_DEVINFO_DATA dev_info_data
;
2685 char* dev_path_no_guid
= NULL
;
2686 char filter_path
[] = "\\\\.\\libusb0-0000";
2687 bool found_filter
= false;
2689 CHECK_WINUSBX_AVAILABLE(sub_api
);
2691 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2692 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2693 if ((is_using_usbccgp
) || (iface
== 0)) {
2694 // composite device (independent interfaces) or interface 0
2695 file_handle
= handle_priv
->interface_handle
[iface
].dev_handle
;
2696 if ((file_handle
== 0) || (file_handle
== INVALID_HANDLE_VALUE
)) {
2697 return LIBUSB_ERROR_NOT_FOUND
;
2700 if (!WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2701 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2702 err
= GetLastError();
2704 case ERROR_BAD_COMMAND
:
2705 // The device was disconnected
2706 usbi_err(ctx
, "could not access interface %d: %s", iface
, windows_error_str(0));
2707 return LIBUSB_ERROR_NO_DEVICE
;
2709 // it may be that we're using the libusb0 filter driver.
2710 // TODO: can we move this whole business into the K/0 DLL?
2711 for (i
= 0; ; i
++) {
2712 safe_free(dev_interface_details
);
2713 safe_free(dev_path_no_guid
);
2714 dev_interface_details
= get_interface_details_filter(ctx
, &dev_info
, &dev_info_data
, &GUID_DEVINTERFACE_LIBUSB0_FILTER
, i
, filter_path
);
2715 if ((found_filter
) || (dev_interface_details
== NULL
)) {
2719 dev_path_no_guid
= sanitize_path(strtok(dev_interface_details
->DevicePath
, "{"));
2720 if (safe_strncmp(dev_path_no_guid
, priv
->usb_interface
[iface
].path
, safe_strlen(dev_path_no_guid
)) == 0) {
2721 file_handle
= CreateFileA(filter_path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
2722 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2723 if (file_handle
== INVALID_HANDLE_VALUE
) {
2724 usbi_err(ctx
, "could not open device %s: %s", filter_path
, windows_error_str(0));
2726 WinUSBX
[sub_api
].Free(winusb_handle
);
2727 if (!WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2730 found_filter
= true;
2735 if (!found_filter
) {
2736 usbi_err(ctx
, "could not access interface %d: %s", iface
, windows_error_str(err
));
2737 return LIBUSB_ERROR_ACCESS
;
2741 handle_priv
->interface_handle
[iface
].api_handle
= winusb_handle
;
2743 // For all other interfaces, use GetAssociatedInterface()
2744 winusb_handle
= handle_priv
->interface_handle
[0].api_handle
;
2745 // It is a requirement for multiple interface devices on Windows that, to you
2746 // must first claim the first interface before you claim the others
2747 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2748 file_handle
= handle_priv
->interface_handle
[0].dev_handle
;
2749 if (WinUSBX
[sub_api
].Initialize(file_handle
, &winusb_handle
)) {
2750 handle_priv
->interface_handle
[0].api_handle
= winusb_handle
;
2751 usbi_warn(ctx
, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface
);
2753 usbi_warn(ctx
, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface
, windows_error_str(0));
2754 return LIBUSB_ERROR_ACCESS
;
2757 if (!WinUSBX
[sub_api
].GetAssociatedInterface(winusb_handle
, (UCHAR
)(iface
-1),
2758 &handle_priv
->interface_handle
[iface
].api_handle
)) {
2759 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2760 switch(GetLastError()) {
2761 case ERROR_NO_MORE_ITEMS
: // invalid iface
2762 return LIBUSB_ERROR_NOT_FOUND
;
2763 case ERROR_BAD_COMMAND
: // The device was disconnected
2764 return LIBUSB_ERROR_NO_DEVICE
;
2765 case ERROR_ALREADY_EXISTS
: // already claimed
2766 return LIBUSB_ERROR_BUSY
;
2768 usbi_err(ctx
, "could not claim interface %d: %s", iface
, windows_error_str(0));
2769 return LIBUSB_ERROR_ACCESS
;
2773 usbi_dbg("claimed interface %d", iface
);
2774 handle_priv
->active_interface
= iface
;
2776 return LIBUSB_SUCCESS
;
2779 static int winusbx_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
2781 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2782 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2783 HANDLE winusb_handle
;
2785 CHECK_WINUSBX_AVAILABLE(sub_api
);
2787 winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2788 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2789 return LIBUSB_ERROR_NOT_FOUND
;
2792 WinUSBX
[sub_api
].Free(winusb_handle
);
2793 handle_priv
->interface_handle
[iface
].api_handle
= INVALID_HANDLE_VALUE
;
2795 return LIBUSB_SUCCESS
;
2799 * Return the first valid interface (of the same API type), for control transfers
2801 static int get_valid_interface(struct libusb_device_handle
*dev_handle
, int api_id
)
2803 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2804 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2807 if ((api_id
< USB_API_WINUSBX
) || (api_id
> USB_API_HID
)) {
2808 usbi_dbg("unsupported API ID");
2812 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
2813 if ( (handle_priv
->interface_handle
[i
].dev_handle
!= 0)
2814 && (handle_priv
->interface_handle
[i
].dev_handle
!= INVALID_HANDLE_VALUE
)
2815 && (handle_priv
->interface_handle
[i
].api_handle
!= 0)
2816 && (handle_priv
->interface_handle
[i
].api_handle
!= INVALID_HANDLE_VALUE
)
2817 && (priv
->usb_interface
[i
].apib
->id
== api_id
) ) {
2825 * Lookup interface by endpoint address. -1 if not found
2827 static int interface_by_endpoint(struct windows_device_priv
*priv
,
2828 struct windows_device_handle_priv
*handle_priv
, uint8_t endpoint_address
)
2831 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
2832 if (handle_priv
->interface_handle
[i
].api_handle
== INVALID_HANDLE_VALUE
)
2834 if (handle_priv
->interface_handle
[i
].api_handle
== 0)
2836 if (priv
->usb_interface
[i
].endpoint
== NULL
)
2838 for (j
=0; j
<priv
->usb_interface
[i
].nb_endpoints
; j
++) {
2839 if (priv
->usb_interface
[i
].endpoint
[j
] == endpoint_address
) {
2847 static int winusbx_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
2849 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2850 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
2851 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2852 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
2853 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(
2854 transfer
->dev_handle
);
2855 WINUSB_SETUP_PACKET
*setup
= (WINUSB_SETUP_PACKET
*) transfer
->buffer
;
2857 HANDLE winusb_handle
;
2858 int current_interface
;
2861 CHECK_WINUSBX_AVAILABLE(sub_api
);
2863 transfer_priv
->pollable_fd
= INVALID_WINFD
;
2864 size
= transfer
->length
- LIBUSB_CONTROL_SETUP_SIZE
;
2866 if (size
> MAX_CTRL_BUFFER_LENGTH
)
2867 return LIBUSB_ERROR_INVALID_PARAM
;
2869 current_interface
= get_valid_interface(transfer
->dev_handle
, USB_API_WINUSBX
);
2870 if (current_interface
< 0) {
2871 if (auto_claim(transfer
, ¤t_interface
, USB_API_WINUSBX
) != LIBUSB_SUCCESS
) {
2872 return LIBUSB_ERROR_NOT_FOUND
;
2876 usbi_dbg("will use interface %d", current_interface
);
2877 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
2879 wfd
= usbi_create_fd(winusb_handle
, RW_READ
, NULL
, NULL
);
2880 // Always use the handle returned from usbi_create_fd (wfd.handle)
2882 return LIBUSB_ERROR_NO_MEM
;
2885 // Sending of set configuration control requests from WinUSB creates issues
2886 if ( ((setup
->request_type
& (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD
)
2887 && (setup
->request
== LIBUSB_REQUEST_SET_CONFIGURATION
) ) {
2888 if (setup
->value
!= priv
->active_config
) {
2889 usbi_warn(ctx
, "cannot set configuration other than the default one");
2891 return LIBUSB_ERROR_INVALID_PARAM
;
2893 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2894 wfd
.overlapped
->InternalHigh
= 0;
2896 if (!WinUSBX
[sub_api
].ControlTransfer(wfd
.handle
, *setup
, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, size
, NULL
, wfd
.overlapped
)) {
2897 if(GetLastError() != ERROR_IO_PENDING
) {
2898 usbi_warn(ctx
, "ControlTransfer failed: %s", windows_error_str(0));
2900 return LIBUSB_ERROR_IO
;
2903 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2904 wfd
.overlapped
->InternalHigh
= (DWORD
)size
;
2908 // Use priv_transfer to store data needed for async polling
2909 transfer_priv
->pollable_fd
= wfd
;
2910 transfer_priv
->interface_number
= (uint8_t)current_interface
;
2912 return LIBUSB_SUCCESS
;
2915 static int winusbx_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
2917 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
2918 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
2919 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
2920 HANDLE winusb_handle
;
2922 CHECK_WINUSBX_AVAILABLE(sub_api
);
2924 if (altsetting
> 255) {
2925 return LIBUSB_ERROR_INVALID_PARAM
;
2928 winusb_handle
= handle_priv
->interface_handle
[iface
].api_handle
;
2929 if ((winusb_handle
== 0) || (winusb_handle
== INVALID_HANDLE_VALUE
)) {
2930 usbi_err(ctx
, "interface must be claimed first");
2931 return LIBUSB_ERROR_NOT_FOUND
;
2934 if (!WinUSBX
[sub_api
].SetCurrentAlternateSetting(winusb_handle
, (UCHAR
)altsetting
)) {
2935 usbi_err(ctx
, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2936 return LIBUSB_ERROR_IO
;
2939 return LIBUSB_SUCCESS
;
2942 static int winusbx_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
2944 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
2945 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
2946 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
2947 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
2948 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
2949 HANDLE winusb_handle
;
2951 int current_interface
;
2954 CHECK_WINUSBX_AVAILABLE(sub_api
);
2956 transfer_priv
->pollable_fd
= INVALID_WINFD
;
2958 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
2959 if (current_interface
< 0) {
2960 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
2961 return LIBUSB_ERROR_NOT_FOUND
;
2964 usbi_dbg("matched endpoint %02X with interface %d", transfer
->endpoint
, current_interface
);
2966 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
2968 wfd
= usbi_create_fd(winusb_handle
, IS_XFERIN(transfer
) ? RW_READ
: RW_WRITE
, NULL
, NULL
);
2969 // Always use the handle returned from usbi_create_fd (wfd.handle)
2971 return LIBUSB_ERROR_NO_MEM
;
2974 if (IS_XFERIN(transfer
)) {
2975 usbi_dbg("reading %d bytes", transfer
->length
);
2976 ret
= WinUSBX
[sub_api
].ReadPipe(wfd
.handle
, transfer
->endpoint
, transfer
->buffer
, transfer
->length
, NULL
, wfd
.overlapped
);
2978 usbi_dbg("writing %d bytes", transfer
->length
);
2979 ret
= WinUSBX
[sub_api
].WritePipe(wfd
.handle
, transfer
->endpoint
, transfer
->buffer
, transfer
->length
, NULL
, wfd
.overlapped
);
2982 if(GetLastError() != ERROR_IO_PENDING
) {
2983 usbi_err(ctx
, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2985 return LIBUSB_ERROR_IO
;
2988 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
2989 wfd
.overlapped
->InternalHigh
= (DWORD
)transfer
->length
;
2992 transfer_priv
->pollable_fd
= wfd
;
2993 transfer_priv
->interface_number
= (uint8_t)current_interface
;
2995 return LIBUSB_SUCCESS
;
2998 static int winusbx_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
3000 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3001 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3002 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3003 HANDLE winusb_handle
;
3004 int current_interface
;
3006 CHECK_WINUSBX_AVAILABLE(sub_api
);
3008 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
3009 if (current_interface
< 0) {
3010 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
3011 return LIBUSB_ERROR_NOT_FOUND
;
3014 usbi_dbg("matched endpoint %02X with interface %d", endpoint
, current_interface
);
3015 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3017 if (!WinUSBX
[sub_api
].ResetPipe(winusb_handle
, endpoint
)) {
3018 usbi_err(ctx
, "ResetPipe failed: %s", windows_error_str(0));
3019 return LIBUSB_ERROR_NO_DEVICE
;
3022 return LIBUSB_SUCCESS
;
3026 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3027 * through testing as well):
3028 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3029 * the control transfer using CancelIo"
3031 static int winusbx_abort_control(int sub_api
, struct usbi_transfer
*itransfer
)
3033 // Cancelling of the I/O is done in the parent
3034 return LIBUSB_SUCCESS
;
3037 static int winusbx_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
3039 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3040 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3041 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3042 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3043 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3044 HANDLE winusb_handle
;
3045 int current_interface
;
3047 CHECK_WINUSBX_AVAILABLE(sub_api
);
3049 current_interface
= transfer_priv
->interface_number
;
3050 if ((current_interface
< 0) || (current_interface
>= USB_MAXINTERFACES
)) {
3051 usbi_err(ctx
, "program assertion failed: invalid interface_number");
3052 return LIBUSB_ERROR_NOT_FOUND
;
3054 usbi_dbg("will use interface %d", current_interface
);
3056 winusb_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3058 if (!WinUSBX
[sub_api
].AbortPipe(winusb_handle
, transfer
->endpoint
)) {
3059 usbi_err(ctx
, "AbortPipe failed: %s", windows_error_str(0));
3060 return LIBUSB_ERROR_NO_DEVICE
;
3063 return LIBUSB_SUCCESS
;
3067 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3068 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3069 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3070 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3071 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3072 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3074 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3075 static int winusbx_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
3077 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3078 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3079 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3081 HANDLE winusb_handle
;
3084 CHECK_WINUSBX_AVAILABLE(sub_api
);
3086 // Reset any available pipe (except control)
3087 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
3088 winusb_handle
= handle_priv
->interface_handle
[i
].api_handle
;
3089 for (wfd
= handle_to_winfd(winusb_handle
); wfd
.fd
> 0;)
3091 // Cancel any pollable I/O
3092 usbi_remove_pollfd(ctx
, wfd
.fd
);
3094 wfd
= handle_to_winfd(winusb_handle
);
3097 if ( (winusb_handle
!= 0) && (winusb_handle
!= INVALID_HANDLE_VALUE
)) {
3098 for (j
=0; j
<priv
->usb_interface
[i
].nb_endpoints
; j
++) {
3099 usbi_dbg("resetting ep %02X", priv
->usb_interface
[i
].endpoint
[j
]);
3100 if (!WinUSBX
[sub_api
].AbortPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) {
3101 usbi_err(ctx
, "AbortPipe (pipe address %02X) failed: %s",
3102 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3104 // FlushPipe seems to fail on OUT pipes
3105 if (IS_EPIN(priv
->usb_interface
[i
].endpoint
[j
])
3106 && (!WinUSBX
[sub_api
].FlushPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) ) {
3107 usbi_err(ctx
, "FlushPipe (pipe address %02X) failed: %s",
3108 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3110 if (!WinUSBX
[sub_api
].ResetPipe(winusb_handle
, priv
->usb_interface
[i
].endpoint
[j
])) {
3111 usbi_err(ctx
, "ResetPipe (pipe address %02X) failed: %s",
3112 priv
->usb_interface
[i
].endpoint
[j
], windows_error_str(0));
3118 // libusbK & libusb0 have the ability to issue an actual device reset
3119 if (WinUSBX
[sub_api
].ResetDevice
!= NULL
) {
3120 winusb_handle
= handle_priv
->interface_handle
[0].api_handle
;
3121 if ( (winusb_handle
!= 0) && (winusb_handle
!= INVALID_HANDLE_VALUE
)) {
3122 WinUSBX
[sub_api
].ResetDevice(winusb_handle
);
3125 return LIBUSB_SUCCESS
;
3128 static int winusbx_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
)
3130 itransfer
->transferred
+= io_size
;
3131 return LIBUSB_TRANSFER_COMPLETED
;
3135 * Internal HID Support functions (from libusb-win32)
3136 * Note that functions that complete data transfer synchronously must return
3137 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3139 static int _hid_get_hid_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
);
3140 static int _hid_get_report_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
);
3142 static int _hid_wcslen(WCHAR
*str
)
3145 while (str
[i
] && (str
[i
] != 0x409)) {
3151 static int _hid_get_device_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3153 struct libusb_device_descriptor d
;
3155 d
.bLength
= LIBUSB_DT_DEVICE_SIZE
;
3156 d
.bDescriptorType
= LIBUSB_DT_DEVICE
;
3157 d
.bcdUSB
= 0x0200; /* 2.00 */
3159 d
.bDeviceSubClass
= 0;
3160 d
.bDeviceProtocol
= 0;
3161 d
.bMaxPacketSize0
= 64; /* fix this! */
3162 d
.idVendor
= (uint16_t)dev
->vid
;
3163 d
.idProduct
= (uint16_t)dev
->pid
;
3164 d
.bcdDevice
= 0x0100;
3165 d
.iManufacturer
= dev
->string_index
[0];
3166 d
.iProduct
= dev
->string_index
[1];
3167 d
.iSerialNumber
= dev
->string_index
[2];
3168 d
.bNumConfigurations
= 1;
3170 if (*size
> LIBUSB_DT_DEVICE_SIZE
)
3171 *size
= LIBUSB_DT_DEVICE_SIZE
;
3172 memcpy(data
, &d
, *size
);
3173 return LIBUSB_COMPLETED
;
3176 static int _hid_get_config_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3178 char num_endpoints
= 0;
3179 size_t config_total_len
= 0;
3180 char tmp
[HID_MAX_CONFIG_DESC_SIZE
];
3181 struct libusb_config_descriptor
*cd
;
3182 struct libusb_interface_descriptor
*id
;
3183 struct libusb_hid_descriptor
*hd
;
3184 struct libusb_endpoint_descriptor
*ed
;
3187 if (dev
->input_report_size
)
3189 if (dev
->output_report_size
)
3192 config_total_len
= LIBUSB_DT_CONFIG_SIZE
+ LIBUSB_DT_INTERFACE_SIZE
3193 + LIBUSB_DT_HID_SIZE
+ num_endpoints
* LIBUSB_DT_ENDPOINT_SIZE
;
3196 cd
= (struct libusb_config_descriptor
*)tmp
;
3197 id
= (struct libusb_interface_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
);
3198 hd
= (struct libusb_hid_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
3199 + LIBUSB_DT_INTERFACE_SIZE
);
3200 ed
= (struct libusb_endpoint_descriptor
*)(tmp
+ LIBUSB_DT_CONFIG_SIZE
3201 + LIBUSB_DT_INTERFACE_SIZE
3202 + LIBUSB_DT_HID_SIZE
);
3204 cd
->bLength
= LIBUSB_DT_CONFIG_SIZE
;
3205 cd
->bDescriptorType
= LIBUSB_DT_CONFIG
;
3206 cd
->wTotalLength
= (uint16_t) config_total_len
;
3207 cd
->bNumInterfaces
= 1;
3208 cd
->bConfigurationValue
= 1;
3209 cd
->iConfiguration
= 0;
3210 cd
->bmAttributes
= 1 << 7; /* bus powered */
3213 id
->bLength
= LIBUSB_DT_INTERFACE_SIZE
;
3214 id
->bDescriptorType
= LIBUSB_DT_INTERFACE
;
3215 id
->bInterfaceNumber
= 0;
3216 id
->bAlternateSetting
= 0;
3217 id
->bNumEndpoints
= num_endpoints
;
3218 id
->bInterfaceClass
= 3;
3219 id
->bInterfaceSubClass
= 0;
3220 id
->bInterfaceProtocol
= 0;
3223 tmp_size
= LIBUSB_DT_HID_SIZE
;
3224 _hid_get_hid_descriptor(dev
, hd
, &tmp_size
);
3226 if (dev
->input_report_size
) {
3227 ed
->bLength
= LIBUSB_DT_ENDPOINT_SIZE
;
3228 ed
->bDescriptorType
= LIBUSB_DT_ENDPOINT
;
3229 ed
->bEndpointAddress
= HID_IN_EP
;
3230 ed
->bmAttributes
= 3;
3231 ed
->wMaxPacketSize
= dev
->input_report_size
- 1;
3233 ed
= (struct libusb_endpoint_descriptor
*)((char*)ed
+ LIBUSB_DT_ENDPOINT_SIZE
);
3236 if (dev
->output_report_size
) {
3237 ed
->bLength
= LIBUSB_DT_ENDPOINT_SIZE
;
3238 ed
->bDescriptorType
= LIBUSB_DT_ENDPOINT
;
3239 ed
->bEndpointAddress
= HID_OUT_EP
;
3240 ed
->bmAttributes
= 3;
3241 ed
->wMaxPacketSize
= dev
->output_report_size
- 1;
3245 if (*size
> config_total_len
)
3246 *size
= config_total_len
;
3247 memcpy(data
, tmp
, *size
);
3248 return LIBUSB_COMPLETED
;
3251 static int _hid_get_string_descriptor(struct hid_device_priv
* dev
, int _index
,
3252 void *data
, size_t *size
)
3255 size_t tmp_size
= 0;
3258 /* language ID, EN-US */
3259 char string_langid
[] = {
3264 if ((*size
< 2) || (*size
> 255)) {
3265 return LIBUSB_ERROR_OVERFLOW
;
3269 tmp
= string_langid
;
3270 tmp_size
= sizeof(string_langid
)+2;
3272 for (i
=0; i
<3; i
++) {
3273 if (_index
== (dev
->string_index
[i
])) {
3274 tmp
= dev
->string
[i
];
3275 tmp_size
= (_hid_wcslen(dev
->string
[i
])+1) * sizeof(WCHAR
);
3279 if (i
== 3) { // not found
3280 return LIBUSB_ERROR_INVALID_PARAM
;
3285 return LIBUSB_ERROR_INVALID_PARAM
;
3288 if (tmp_size
< *size
) {
3292 ((uint8_t*)data
)[0] = (uint8_t)*size
;
3293 ((uint8_t*)data
)[1] = LIBUSB_DT_STRING
;
3294 memcpy((uint8_t*)data
+2, tmp
, *size
-2);
3295 return LIBUSB_COMPLETED
;
3298 static int _hid_get_hid_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3300 struct libusb_hid_descriptor d
;
3301 uint8_t tmp
[MAX_HID_DESCRIPTOR_SIZE
];
3302 size_t report_len
= MAX_HID_DESCRIPTOR_SIZE
;
3304 _hid_get_report_descriptor(dev
, tmp
, &report_len
);
3306 d
.bLength
= LIBUSB_DT_HID_SIZE
;
3307 d
.bDescriptorType
= LIBUSB_DT_HID
;
3308 d
.bcdHID
= 0x0110; /* 1.10 */
3310 d
.bNumDescriptors
= 1;
3311 d
.bClassDescriptorType
= LIBUSB_DT_REPORT
;
3312 d
.wClassDescriptorLength
= (uint16_t)report_len
;
3314 if (*size
> LIBUSB_DT_HID_SIZE
)
3315 *size
= LIBUSB_DT_HID_SIZE
;
3316 memcpy(data
, &d
, *size
);
3317 return LIBUSB_COMPLETED
;
3320 static int _hid_get_report_descriptor(struct hid_device_priv
* dev
, void *data
, size_t *size
)
3322 uint8_t d
[MAX_HID_DESCRIPTOR_SIZE
];
3325 /* usage page (0xFFA0 == vendor defined) */
3326 d
[i
++] = 0x06; d
[i
++] = 0xA0; d
[i
++] = 0xFF;
3327 /* usage (vendor defined) */
3328 d
[i
++] = 0x09; d
[i
++] = 0x01;
3329 /* start collection (application) */
3330 d
[i
++] = 0xA1; d
[i
++] = 0x01;
3332 if (dev
->input_report_size
) {
3333 /* usage (vendor defined) */
3334 d
[i
++] = 0x09; d
[i
++] = 0x01;
3335 /* logical minimum (0) */
3336 d
[i
++] = 0x15; d
[i
++] = 0x00;
3337 /* logical maximum (255) */
3338 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3339 /* report size (8 bits) */
3340 d
[i
++] = 0x75; d
[i
++] = 0x08;
3342 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->input_report_size
- 1;
3343 /* input (data, variable, absolute) */
3344 d
[i
++] = 0x81; d
[i
++] = 0x00;
3347 if (dev
->output_report_size
) {
3348 /* usage (vendor defined) */
3349 d
[i
++] = 0x09; d
[i
++] = 0x02;
3350 /* logical minimum (0) */
3351 d
[i
++] = 0x15; d
[i
++] = 0x00;
3352 /* logical maximum (255) */
3353 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3354 /* report size (8 bits) */
3355 d
[i
++] = 0x75; d
[i
++] = 0x08;
3357 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->output_report_size
- 1;
3358 /* output (data, variable, absolute) */
3359 d
[i
++] = 0x91; d
[i
++] = 0x00;
3361 /* feature report */
3362 if (dev
->feature_report_size
) {
3363 /* usage (vendor defined) */
3364 d
[i
++] = 0x09; d
[i
++] = 0x03;
3365 /* logical minimum (0) */
3366 d
[i
++] = 0x15; d
[i
++] = 0x00;
3367 /* logical maximum (255) */
3368 d
[i
++] = 0x25; d
[i
++] = 0xFF;
3369 /* report size (8 bits) */
3370 d
[i
++] = 0x75; d
[i
++] = 0x08;
3372 d
[i
++] = 0x95; d
[i
++] = (uint8_t)dev
->feature_report_size
- 1;
3373 /* feature (data, variable, absolute) */
3374 d
[i
++] = 0xb2; d
[i
++] = 0x02; d
[i
++] = 0x01;
3377 /* end collection */
3382 memcpy(data
, d
, *size
);
3383 return LIBUSB_COMPLETED
;
3386 static int _hid_get_descriptor(struct hid_device_priv
* dev
, HANDLE hid_handle
, int recipient
,
3387 int type
, int _index
, void *data
, size_t *size
)
3390 case LIBUSB_DT_DEVICE
:
3391 usbi_dbg("LIBUSB_DT_DEVICE");
3392 return _hid_get_device_descriptor(dev
, data
, size
);
3393 case LIBUSB_DT_CONFIG
:
3394 usbi_dbg("LIBUSB_DT_CONFIG");
3396 return _hid_get_config_descriptor(dev
, data
, size
);
3397 return LIBUSB_ERROR_INVALID_PARAM
;
3398 case LIBUSB_DT_STRING
:
3399 usbi_dbg("LIBUSB_DT_STRING");
3400 return _hid_get_string_descriptor(dev
, _index
, data
, size
);
3402 usbi_dbg("LIBUSB_DT_HID");
3404 return _hid_get_hid_descriptor(dev
, data
, size
);
3405 return LIBUSB_ERROR_INVALID_PARAM
;
3406 case LIBUSB_DT_REPORT
:
3407 usbi_dbg("LIBUSB_DT_REPORT");
3409 return _hid_get_report_descriptor(dev
, data
, size
);
3410 return LIBUSB_ERROR_INVALID_PARAM
;
3411 case LIBUSB_DT_PHYSICAL
:
3412 usbi_dbg("LIBUSB_DT_PHYSICAL");
3413 if (HidD_GetPhysicalDescriptor(hid_handle
, data
, (ULONG
)*size
))
3414 return LIBUSB_COMPLETED
;
3415 return LIBUSB_ERROR_OTHER
;
3417 usbi_dbg("unsupported");
3418 return LIBUSB_ERROR_INVALID_PARAM
;
3421 static int _hid_get_report(struct hid_device_priv
* dev
, HANDLE hid_handle
, int id
, void *data
,
3422 struct windows_transfer_priv
*tp
, size_t *size
, OVERLAPPED
* overlapped
,
3426 DWORD ioctl_code
, read_size
, expected_size
= (DWORD
)*size
;
3427 int r
= LIBUSB_SUCCESS
;
3429 if (tp
->hid_buffer
!= NULL
) {
3430 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3433 if ((*size
== 0) || (*size
> MAX_HID_REPORT_SIZE
)) {
3434 usbi_dbg("invalid size (%d)", *size
);
3435 return LIBUSB_ERROR_INVALID_PARAM
;
3438 switch (report_type
) {
3439 case HID_REPORT_TYPE_INPUT
:
3440 ioctl_code
= IOCTL_HID_GET_INPUT_REPORT
;
3442 case HID_REPORT_TYPE_FEATURE
:
3443 ioctl_code
= IOCTL_HID_GET_FEATURE
;
3446 usbi_dbg("unknown HID report type %d", report_type
);
3447 return LIBUSB_ERROR_INVALID_PARAM
;
3450 // Add a trailing byte to detect overflows
3451 buf
= (uint8_t*)calloc(expected_size
+1, 1);
3453 return LIBUSB_ERROR_NO_MEM
;
3455 buf
[0] = (uint8_t)id
; // Must be set always
3456 usbi_dbg("report ID: 0x%02X", buf
[0]);
3458 tp
->hid_expected_size
= expected_size
;
3459 read_size
= expected_size
;
3461 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3462 if (!DeviceIoControl(hid_handle
, ioctl_code
, buf
, expected_size
+1,
3463 buf
, expected_size
+1, &read_size
, overlapped
)) {
3464 if (GetLastError() != ERROR_IO_PENDING
) {
3465 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3467 return LIBUSB_ERROR_IO
;
3469 // Asynchronous wait
3470 tp
->hid_buffer
= buf
;
3471 tp
->hid_dest
= (uint8_t*)data
; // copy dest, as not necessarily the start of the transfer buffer
3472 return LIBUSB_SUCCESS
;
3475 // Transfer completed synchronously => copy and discard extra buffer
3476 if (read_size
== 0) {
3477 usbi_warn(NULL
, "program assertion failed - read completed synchronously, but no data was read");
3481 usbi_warn(NULL
, "mismatched report ID (data is %02X, parameter is %02X)", buf
[0], id
);
3483 if ((size_t)read_size
> expected_size
) {
3484 r
= LIBUSB_ERROR_OVERFLOW
;
3485 usbi_dbg("OVERFLOW!");
3487 r
= LIBUSB_COMPLETED
;
3490 *size
= MIN((size_t)read_size
, *size
);
3492 // Discard report ID
3493 memcpy(data
, buf
+1, *size
);
3495 memcpy(data
, buf
, *size
);
3502 static int _hid_set_report(struct hid_device_priv
* dev
, HANDLE hid_handle
, int id
, void *data
,
3503 struct windows_transfer_priv
*tp
, size_t *size
, OVERLAPPED
* overlapped
,
3506 uint8_t *buf
= NULL
;
3507 DWORD ioctl_code
, write_size
= (DWORD
)*size
;
3509 if (tp
->hid_buffer
!= NULL
) {
3510 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3513 if ((*size
== 0) || (*size
> MAX_HID_REPORT_SIZE
)) {
3514 usbi_dbg("invalid size (%d)", *size
);
3515 return LIBUSB_ERROR_INVALID_PARAM
;
3518 switch (report_type
) {
3519 case HID_REPORT_TYPE_OUTPUT
:
3520 ioctl_code
= IOCTL_HID_SET_OUTPUT_REPORT
;
3522 case HID_REPORT_TYPE_FEATURE
:
3523 ioctl_code
= IOCTL_HID_SET_FEATURE
;
3526 usbi_dbg("unknown HID report type %d", report_type
);
3527 return LIBUSB_ERROR_INVALID_PARAM
;
3530 usbi_dbg("report ID: 0x%02X", id
);
3531 // When report IDs are not used (i.e. when id == 0), we must add
3532 // a null report ID. Otherwise, we just use original data buffer
3536 buf
= (uint8_t*) malloc(write_size
);
3538 return LIBUSB_ERROR_NO_MEM
;
3542 memcpy(buf
+ 1, data
, *size
);
3544 // This seems like a waste, but if we don't duplicate the
3545 // data, we'll get issues when freeing hid_buffer
3546 memcpy(buf
, data
, *size
);
3548 usbi_warn(NULL
, "mismatched report ID (data is %02X, parameter is %02X)", buf
[0], id
);
3552 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3553 if (!DeviceIoControl(hid_handle
, ioctl_code
, buf
, write_size
,
3554 buf
, write_size
, &write_size
, overlapped
)) {
3555 if (GetLastError() != ERROR_IO_PENDING
) {
3556 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3558 return LIBUSB_ERROR_IO
;
3560 tp
->hid_buffer
= buf
;
3561 tp
->hid_dest
= NULL
;
3562 return LIBUSB_SUCCESS
;
3565 // Transfer completed synchronously
3567 if (write_size
== 0) {
3568 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3571 return LIBUSB_COMPLETED
;
3574 static int _hid_class_request(struct hid_device_priv
* dev
, HANDLE hid_handle
, int request_type
,
3575 int request
, int value
, int _index
, void *data
, struct windows_transfer_priv
*tp
,
3576 size_t *size
, OVERLAPPED
* overlapped
)
3578 int report_type
= (value
>> 8) & 0xFF;
3579 int report_id
= value
& 0xFF;
3581 if ( (LIBUSB_REQ_RECIPIENT(request_type
) != LIBUSB_RECIPIENT_INTERFACE
)
3582 && (LIBUSB_REQ_RECIPIENT(request_type
) != LIBUSB_RECIPIENT_DEVICE
) )
3583 return LIBUSB_ERROR_INVALID_PARAM
;
3585 if (LIBUSB_REQ_OUT(request_type
) && request
== HID_REQ_SET_REPORT
)
3586 return _hid_set_report(dev
, hid_handle
, report_id
, data
, tp
, size
, overlapped
, report_type
);
3588 if (LIBUSB_REQ_IN(request_type
) && request
== HID_REQ_GET_REPORT
)
3589 return _hid_get_report(dev
, hid_handle
, report_id
, data
, tp
, size
, overlapped
, report_type
);
3591 return LIBUSB_ERROR_INVALID_PARAM
;
3598 static int hid_init(int sub_api
, struct libusb_context
*ctx
)
3600 DLL_LOAD(hid
.dll
, HidD_GetAttributes
, TRUE
);
3601 DLL_LOAD(hid
.dll
, HidD_GetHidGuid
, TRUE
);
3602 DLL_LOAD(hid
.dll
, HidD_GetPreparsedData
, TRUE
);
3603 DLL_LOAD(hid
.dll
, HidD_FreePreparsedData
, TRUE
);
3604 DLL_LOAD(hid
.dll
, HidD_GetManufacturerString
, TRUE
);
3605 DLL_LOAD(hid
.dll
, HidD_GetProductString
, TRUE
);
3606 DLL_LOAD(hid
.dll
, HidD_GetSerialNumberString
, TRUE
);
3607 DLL_LOAD(hid
.dll
, HidP_GetCaps
, TRUE
);
3608 DLL_LOAD(hid
.dll
, HidD_SetNumInputBuffers
, TRUE
);
3609 DLL_LOAD(hid
.dll
, HidD_SetFeature
, TRUE
);
3610 DLL_LOAD(hid
.dll
, HidD_GetFeature
, TRUE
);
3611 DLL_LOAD(hid
.dll
, HidD_GetPhysicalDescriptor
, TRUE
);
3612 DLL_LOAD(hid
.dll
, HidD_GetInputReport
, FALSE
);
3613 DLL_LOAD(hid
.dll
, HidD_SetOutputReport
, FALSE
);
3614 DLL_LOAD(hid
.dll
, HidD_FlushQueue
, TRUE
);
3615 DLL_LOAD(hid
.dll
, HidP_GetValueCaps
, TRUE
);
3617 api_hid_available
= true;
3618 return LIBUSB_SUCCESS
;
3621 static int hid_exit(int sub_api
)
3623 return LIBUSB_SUCCESS
;
3626 // NB: open and close must ensure that they only handle interface of
3627 // the right API type, as these functions can be called wholesale from
3628 // composite_open(), with interfaces belonging to different APIs
3629 static int hid_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
3631 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3632 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3633 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3635 HIDD_ATTRIBUTES hid_attributes
;
3636 PHIDP_PREPARSED_DATA preparsed_data
= NULL
;
3637 HIDP_CAPS capabilities
;
3638 HIDP_VALUE_CAPS
*value_caps
;
3640 HANDLE hid_handle
= INVALID_HANDLE_VALUE
;
3642 // report IDs handling
3644 const char* type
[3] = {"input", "output", "feature"};
3645 int nb_ids
[2]; // zero and nonzero report IDs
3647 CHECK_HID_AVAILABLE
;
3648 if (priv
->hid
== NULL
) {
3649 usbi_err(ctx
, "program assertion failed - private HID structure is unitialized");
3650 return LIBUSB_ERROR_NOT_FOUND
;
3653 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
3654 if ( (priv
->usb_interface
[i
].path
!= NULL
)
3655 && (priv
->usb_interface
[i
].apib
->id
== USB_API_HID
) ) {
3656 hid_handle
= CreateFileA(priv
->usb_interface
[i
].path
, GENERIC_WRITE
| GENERIC_READ
, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
3657 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
3659 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3660 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3661 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3662 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3663 * HidD_GetFeature (if the device supports Feature reports)."
3665 if (hid_handle
== INVALID_HANDLE_VALUE
) {
3666 usbi_warn(ctx
, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3667 hid_handle
= CreateFileA(priv
->usb_interface
[i
].path
, 0, FILE_SHARE_WRITE
| FILE_SHARE_READ
,
3668 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
3669 if (hid_handle
== INVALID_HANDLE_VALUE
) {
3670 usbi_err(ctx
, "could not open device %s (interface %d): %s", priv
->path
, i
, windows_error_str(0));
3671 switch(GetLastError()) {
3672 case ERROR_FILE_NOT_FOUND
: // The device was disconnected
3673 return LIBUSB_ERROR_NO_DEVICE
;
3674 case ERROR_ACCESS_DENIED
:
3675 return LIBUSB_ERROR_ACCESS
;
3677 return LIBUSB_ERROR_IO
;
3680 priv
->usb_interface
[i
].restricted_functionality
= true;
3682 handle_priv
->interface_handle
[i
].api_handle
= hid_handle
;
3686 hid_attributes
.Size
= sizeof(hid_attributes
);
3688 if (!HidD_GetAttributes(hid_handle
, &hid_attributes
)) {
3689 usbi_err(ctx
, "could not gain access to HID top collection (HidD_GetAttributes)");
3693 priv
->hid
->vid
= hid_attributes
.VendorID
;
3694 priv
->hid
->pid
= hid_attributes
.ProductID
;
3696 // Set the maximum available input buffer size
3697 for (i
=32; HidD_SetNumInputBuffers(hid_handle
, i
); i
*=2);
3698 usbi_dbg("set maximum input buffer size to %d", i
/2);
3700 // Get the maximum input and output report size
3701 if (!HidD_GetPreparsedData(hid_handle
, &preparsed_data
) || !preparsed_data
) {
3702 usbi_err(ctx
, "could not read HID preparsed data (HidD_GetPreparsedData)");
3705 if (HidP_GetCaps(preparsed_data
, &capabilities
) != HIDP_STATUS_SUCCESS
) {
3706 usbi_err(ctx
, "could not parse HID capabilities (HidP_GetCaps)");
3710 // Find out if interrupt will need report IDs
3711 size
[0] = capabilities
.NumberInputValueCaps
;
3712 size
[1] = capabilities
.NumberOutputValueCaps
;
3713 size
[2] = capabilities
.NumberFeatureValueCaps
;
3714 for (j
=HidP_Input
; j
<=HidP_Feature
; j
++) {
3715 usbi_dbg("%d HID %s report value(s) found", size
[j
], type
[j
]);
3716 priv
->hid
->uses_report_ids
[j
] = false;
3718 value_caps
= (HIDP_VALUE_CAPS
*) calloc(size
[j
], sizeof(HIDP_VALUE_CAPS
));
3719 if ( (value_caps
!= NULL
)
3720 && (HidP_GetValueCaps((HIDP_REPORT_TYPE
)j
, value_caps
, &size
[j
], preparsed_data
) == HIDP_STATUS_SUCCESS
)
3721 && (size
[j
] >= 1) ) {
3724 for (i
=0; i
<(int)size
[j
]; i
++) {
3725 usbi_dbg(" Report ID: 0x%02X", value_caps
[i
].ReportID
);
3726 if (value_caps
[i
].ReportID
!= 0) {
3732 if (nb_ids
[1] != 0) {
3733 if (nb_ids
[0] != 0) {
3734 usbi_warn(ctx
, "program assertion failed: zero and nonzero report IDs used for %s",
3737 priv
->hid
->uses_report_ids
[j
] = true;
3740 usbi_warn(ctx
, " could not process %s report IDs", type
[j
]);
3742 safe_free(value_caps
);
3746 // Set the report sizes
3747 priv
->hid
->input_report_size
= capabilities
.InputReportByteLength
;
3748 priv
->hid
->output_report_size
= capabilities
.OutputReportByteLength
;
3749 priv
->hid
->feature_report_size
= capabilities
.FeatureReportByteLength
;
3751 // Fetch string descriptors
3752 priv
->hid
->string_index
[0] = priv
->dev_descriptor
.iManufacturer
;
3753 if (priv
->hid
->string_index
[0] != 0) {
3754 HidD_GetManufacturerString(hid_handle
, priv
->hid
->string
[0],
3755 sizeof(priv
->hid
->string
[0]));
3757 priv
->hid
->string
[0][0] = 0;
3759 priv
->hid
->string_index
[1] = priv
->dev_descriptor
.iProduct
;
3760 if (priv
->hid
->string_index
[1] != 0) {
3761 HidD_GetProductString(hid_handle
, priv
->hid
->string
[1],
3762 sizeof(priv
->hid
->string
[1]));
3764 priv
->hid
->string
[1][0] = 0;
3766 priv
->hid
->string_index
[2] = priv
->dev_descriptor
.iSerialNumber
;
3767 if (priv
->hid
->string_index
[2] != 0) {
3768 HidD_GetSerialNumberString(hid_handle
, priv
->hid
->string
[2],
3769 sizeof(priv
->hid
->string
[2]));
3771 priv
->hid
->string
[2][0] = 0;
3775 if (preparsed_data
) {
3776 HidD_FreePreparsedData(preparsed_data
);
3779 return LIBUSB_SUCCESS
;
3782 static void hid_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
3784 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3785 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3789 if (!api_hid_available
)
3792 for (i
= 0; i
< USB_MAXINTERFACES
; i
++) {
3793 if (priv
->usb_interface
[i
].apib
->id
== USB_API_HID
) {
3794 file_handle
= handle_priv
->interface_handle
[i
].api_handle
;
3795 if ( (file_handle
!= 0) && (file_handle
!= INVALID_HANDLE_VALUE
)) {
3796 CloseHandle(file_handle
);
3802 static int hid_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
3804 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3805 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3807 CHECK_HID_AVAILABLE
;
3809 // NB: Disconnection detection is not possible in this function
3810 if (priv
->usb_interface
[iface
].path
== NULL
) {
3811 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3814 // We use dev_handle as a flag for interface claimed
3815 if (handle_priv
->interface_handle
[iface
].dev_handle
== INTERFACE_CLAIMED
) {
3816 return LIBUSB_ERROR_BUSY
; // already claimed
3819 handle_priv
->interface_handle
[iface
].dev_handle
= INTERFACE_CLAIMED
;
3821 usbi_dbg("claimed interface %d", iface
);
3822 handle_priv
->active_interface
= iface
;
3824 return LIBUSB_SUCCESS
;
3827 static int hid_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
3829 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
3830 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
3832 CHECK_HID_AVAILABLE
;
3834 if (priv
->usb_interface
[iface
].path
== NULL
) {
3835 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3838 if (handle_priv
->interface_handle
[iface
].dev_handle
!= INTERFACE_CLAIMED
) {
3839 return LIBUSB_ERROR_NOT_FOUND
; // invalid iface
3842 handle_priv
->interface_handle
[iface
].dev_handle
= INVALID_HANDLE_VALUE
;
3844 return LIBUSB_SUCCESS
;
3847 static int hid_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
3849 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
3851 CHECK_HID_AVAILABLE
;
3853 if (altsetting
> 255) {
3854 return LIBUSB_ERROR_INVALID_PARAM
;
3857 if (altsetting
!= 0) {
3858 usbi_err(ctx
, "set interface altsetting not supported for altsetting >0");
3859 return LIBUSB_ERROR_NOT_SUPPORTED
;
3862 return LIBUSB_SUCCESS
;
3865 static int hid_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
3867 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3868 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3869 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3870 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3871 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3872 WINUSB_SETUP_PACKET
*setup
= (WINUSB_SETUP_PACKET
*) transfer
->buffer
;
3875 int current_interface
, config
;
3877 int r
= LIBUSB_ERROR_INVALID_PARAM
;
3879 CHECK_HID_AVAILABLE
;
3881 transfer_priv
->pollable_fd
= INVALID_WINFD
;
3882 safe_free(transfer_priv
->hid_buffer
);
3883 transfer_priv
->hid_dest
= NULL
;
3884 size
= transfer
->length
- LIBUSB_CONTROL_SETUP_SIZE
;
3886 if (size
> MAX_CTRL_BUFFER_LENGTH
) {
3887 return LIBUSB_ERROR_INVALID_PARAM
;
3890 current_interface
= get_valid_interface(transfer
->dev_handle
, USB_API_HID
);
3891 if (current_interface
< 0) {
3892 if (auto_claim(transfer
, ¤t_interface
, USB_API_HID
) != LIBUSB_SUCCESS
) {
3893 return LIBUSB_ERROR_NOT_FOUND
;
3897 usbi_dbg("will use interface %d", current_interface
);
3898 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
3899 // Always use the handle returned from usbi_create_fd (wfd.handle)
3900 wfd
= usbi_create_fd(hid_handle
, RW_READ
, NULL
, NULL
);
3902 return LIBUSB_ERROR_NOT_FOUND
;
3905 switch(LIBUSB_REQ_TYPE(setup
->request_type
)) {
3906 case LIBUSB_REQUEST_TYPE_STANDARD
:
3907 switch(setup
->request
) {
3908 case LIBUSB_REQUEST_GET_DESCRIPTOR
:
3909 r
= _hid_get_descriptor(priv
->hid
, wfd
.handle
, LIBUSB_REQ_RECIPIENT(setup
->request_type
),
3910 (setup
->value
>> 8) & 0xFF, setup
->value
& 0xFF, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, &size
);
3912 case LIBUSB_REQUEST_GET_CONFIGURATION
:
3913 r
= windows_get_configuration(transfer
->dev_handle
, &config
);
3914 if (r
== LIBUSB_SUCCESS
) {
3916 ((uint8_t*)transfer
->buffer
)[LIBUSB_CONTROL_SETUP_SIZE
] = (uint8_t)config
;
3917 r
= LIBUSB_COMPLETED
;
3920 case LIBUSB_REQUEST_SET_CONFIGURATION
:
3921 if (setup
->value
== priv
->active_config
) {
3922 r
= LIBUSB_COMPLETED
;
3924 usbi_warn(ctx
, "cannot set configuration other than the default one");
3925 r
= LIBUSB_ERROR_INVALID_PARAM
;
3928 case LIBUSB_REQUEST_GET_INTERFACE
:
3930 ((uint8_t*)transfer
->buffer
)[LIBUSB_CONTROL_SETUP_SIZE
] = 0;
3931 r
= LIBUSB_COMPLETED
;
3933 case LIBUSB_REQUEST_SET_INTERFACE
:
3934 r
= hid_set_interface_altsetting(0, transfer
->dev_handle
, setup
->index
, setup
->value
);
3935 if (r
== LIBUSB_SUCCESS
) {
3936 r
= LIBUSB_COMPLETED
;
3940 usbi_warn(ctx
, "unsupported HID control request");
3941 r
= LIBUSB_ERROR_INVALID_PARAM
;
3945 case LIBUSB_REQUEST_TYPE_CLASS
:
3946 r
=_hid_class_request(priv
->hid
, wfd
.handle
, setup
->request_type
, setup
->request
, setup
->value
,
3947 setup
->index
, transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
, transfer_priv
,
3948 &size
, wfd
.overlapped
);
3951 usbi_warn(ctx
, "unsupported HID control request");
3952 r
= LIBUSB_ERROR_INVALID_PARAM
;
3956 if (r
== LIBUSB_COMPLETED
) {
3957 // Force request to be completed synchronously. Transferred size has been set by previous call
3958 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
3959 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3960 // set InternalHigh to the number of bytes transferred
3961 wfd
.overlapped
->InternalHigh
= (DWORD
)size
;
3965 if (r
== LIBUSB_SUCCESS
) {
3966 // Use priv_transfer to store data needed for async polling
3967 transfer_priv
->pollable_fd
= wfd
;
3968 transfer_priv
->interface_number
= (uint8_t)current_interface
;
3976 static int hid_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
3977 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
3978 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
3979 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
3980 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
3981 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
3984 bool direction_in
, ret
;
3985 int current_interface
, length
;
3987 int r
= LIBUSB_SUCCESS
;
3989 CHECK_HID_AVAILABLE
;
3991 transfer_priv
->pollable_fd
= INVALID_WINFD
;
3992 transfer_priv
->hid_dest
= NULL
;
3993 safe_free(transfer_priv
->hid_buffer
);
3995 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
3996 if (current_interface
< 0) {
3997 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
3998 return LIBUSB_ERROR_NOT_FOUND
;
4001 usbi_dbg("matched endpoint %02X with interface %d", transfer
->endpoint
, current_interface
);
4003 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4004 direction_in
= transfer
->endpoint
& LIBUSB_ENDPOINT_IN
;
4006 wfd
= usbi_create_fd(hid_handle
, direction_in
?RW_READ
:RW_WRITE
, NULL
, NULL
);
4007 // Always use the handle returned from usbi_create_fd (wfd.handle)
4009 return LIBUSB_ERROR_NO_MEM
;
4012 // If report IDs are not in use, an extra prefix byte must be added
4013 if ( ((direction_in
) && (!priv
->hid
->uses_report_ids
[0]))
4014 || ((!direction_in
) && (!priv
->hid
->uses_report_ids
[1])) ) {
4015 length
= transfer
->length
+1;
4017 length
= transfer
->length
;
4019 // Add a trailing byte to detect overflows on input
4020 transfer_priv
->hid_buffer
= (uint8_t*)calloc(length
+1, 1);
4021 if (transfer_priv
->hid_buffer
== NULL
) {
4022 return LIBUSB_ERROR_NO_MEM
;
4024 transfer_priv
->hid_expected_size
= length
;
4027 transfer_priv
->hid_dest
= transfer
->buffer
;
4028 usbi_dbg("reading %d bytes (report ID: 0x00)", length
);
4029 ret
= ReadFile(wfd
.handle
, transfer_priv
->hid_buffer
, length
+1, &size
, wfd
.overlapped
);
4031 if (!priv
->hid
->uses_report_ids
[1]) {
4032 memcpy(transfer_priv
->hid_buffer
+1, transfer
->buffer
, transfer
->length
);
4034 // We could actually do without the calloc and memcpy in this case
4035 memcpy(transfer_priv
->hid_buffer
, transfer
->buffer
, transfer
->length
);
4037 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length
, transfer_priv
->hid_buffer
[0]);
4038 ret
= WriteFile(wfd
.handle
, transfer_priv
->hid_buffer
, length
, &size
, wfd
.overlapped
);
4041 if (GetLastError() != ERROR_IO_PENDING
) {
4042 usbi_err(ctx
, "HID transfer failed: %s", windows_error_str(0));
4044 safe_free(transfer_priv
->hid_buffer
);
4045 return LIBUSB_ERROR_IO
;
4048 // Only write operations that completed synchronously need to free up
4049 // hid_buffer. For reads, copy_transfer_data() handles that process.
4050 if (!direction_in
) {
4051 safe_free(transfer_priv
->hid_buffer
);
4054 usbi_err(ctx
, "program assertion failed - no data was transferred");
4057 if (size
> (size_t)length
) {
4058 usbi_err(ctx
, "OVERFLOW!");
4059 r
= LIBUSB_ERROR_OVERFLOW
;
4061 wfd
.overlapped
->Internal
= STATUS_COMPLETED_SYNCHRONOUSLY
;
4062 wfd
.overlapped
->InternalHigh
= size
;
4065 transfer_priv
->pollable_fd
= wfd
;
4066 transfer_priv
->interface_number
= (uint8_t)current_interface
;
4071 static int hid_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
4073 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4074 struct windows_transfer_priv
*transfer_priv
= (struct windows_transfer_priv
*)usbi_transfer_get_os_priv(itransfer
);
4075 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4077 int current_interface
;
4079 CHECK_HID_AVAILABLE
;
4081 current_interface
= transfer_priv
->interface_number
;
4082 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4083 CancelIo(hid_handle
);
4085 return LIBUSB_SUCCESS
;
4088 static int hid_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
4090 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4092 int current_interface
;
4094 CHECK_HID_AVAILABLE
;
4096 // Flushing the queues on all interfaces is the best we can achieve
4097 for (current_interface
= 0; current_interface
< USB_MAXINTERFACES
; current_interface
++) {
4098 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4099 if ((hid_handle
!= 0) && (hid_handle
!= INVALID_HANDLE_VALUE
)) {
4100 HidD_FlushQueue(hid_handle
);
4103 return LIBUSB_SUCCESS
;
4106 static int hid_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
4108 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
4109 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4110 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4112 int current_interface
;
4114 CHECK_HID_AVAILABLE
;
4116 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
4117 if (current_interface
< 0) {
4118 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
4119 return LIBUSB_ERROR_NOT_FOUND
;
4122 usbi_dbg("matched endpoint %02X with interface %d", endpoint
, current_interface
);
4123 hid_handle
= handle_priv
->interface_handle
[current_interface
].api_handle
;
4125 // No endpoint selection with Microsoft's implementation, so we try to flush the
4126 // whole interface. Should be OK for most case scenarios
4127 if (!HidD_FlushQueue(hid_handle
)) {
4128 usbi_err(ctx
, "Flushing of HID queue failed: %s", windows_error_str(0));
4129 // Device was probably disconnected
4130 return LIBUSB_ERROR_NO_DEVICE
;
4133 return LIBUSB_SUCCESS
;
4136 // This extra function is only needed for HID
4137 static int hid_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
) {
4138 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4139 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4140 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4141 int r
= LIBUSB_TRANSFER_COMPLETED
;
4142 uint32_t corrected_size
= io_size
;
4144 if (transfer_priv
->hid_buffer
!= NULL
) {
4145 // If we have a valid hid_buffer, it means the transfer was async
4146 if (transfer_priv
->hid_dest
!= NULL
) { // Data readout
4147 // First, check for overflow
4148 if (corrected_size
> transfer_priv
->hid_expected_size
) {
4149 usbi_err(ctx
, "OVERFLOW!");
4150 corrected_size
= (uint32_t)transfer_priv
->hid_expected_size
;
4151 r
= LIBUSB_TRANSFER_OVERFLOW
;
4154 if (transfer_priv
->hid_buffer
[0] == 0) {
4155 // Discard the 1 byte report ID prefix
4157 memcpy(transfer_priv
->hid_dest
, transfer_priv
->hid_buffer
+1, corrected_size
);
4159 memcpy(transfer_priv
->hid_dest
, transfer_priv
->hid_buffer
, corrected_size
);
4161 transfer_priv
->hid_dest
= NULL
;
4163 // For write, we just need to free the hid buffer
4164 safe_free(transfer_priv
->hid_buffer
);
4166 itransfer
->transferred
+= corrected_size
;
4172 * Composite API functions
4174 static int composite_init(int sub_api
, struct libusb_context
*ctx
)
4176 return LIBUSB_SUCCESS
;
4179 static int composite_exit(int sub_api
)
4181 return LIBUSB_SUCCESS
;
4184 static int composite_open(int sub_api
, struct libusb_device_handle
*dev_handle
)
4186 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4187 int r
= LIBUSB_ERROR_NOT_FOUND
;
4189 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4190 bool available
[SUB_API_MAX
+1] = {0};
4192 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4193 switch (priv
->usb_interface
[i
].apib
->id
) {
4194 case USB_API_WINUSBX
:
4195 if (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
)
4196 available
[priv
->usb_interface
[i
].sub_api
] = true;
4199 available
[SUB_API_MAX
] = true;
4206 for (i
=0; i
<SUB_API_MAX
; i
++) { // WinUSB-like drivers
4208 r
= usb_api_backend
[USB_API_WINUSBX
].open(i
, dev_handle
);
4209 if (r
!= LIBUSB_SUCCESS
) {
4214 if (available
[SUB_API_MAX
]) { // HID driver
4215 r
= hid_open(SUB_API_NOTSET
, dev_handle
);
4220 static void composite_close(int sub_api
, struct libusb_device_handle
*dev_handle
)
4222 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4224 bool available
[SUB_API_MAX
];
4226 for (i
= 0; i
<SUB_API_MAX
; i
++) {
4227 available
[i
] = false;
4230 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4231 if ( (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
)
4232 && (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
) ) {
4233 available
[priv
->usb_interface
[i
].sub_api
] = true;
4237 for (i
=0; i
<SUB_API_MAX
; i
++) {
4239 usb_api_backend
[USB_API_WINUSBX
].close(i
, dev_handle
);
4244 static int composite_claim_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
4246 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4247 return priv
->usb_interface
[iface
].apib
->
4248 claim_interface(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
);
4251 static int composite_set_interface_altsetting(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
)
4253 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4254 return priv
->usb_interface
[iface
].apib
->
4255 set_interface_altsetting(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
, altsetting
);
4258 static int composite_release_interface(int sub_api
, struct libusb_device_handle
*dev_handle
, int iface
)
4260 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4261 return priv
->usb_interface
[iface
].apib
->
4262 release_interface(priv
->usb_interface
[iface
].sub_api
, dev_handle
, iface
);
4265 static int composite_submit_control_transfer(int sub_api
, struct usbi_transfer
*itransfer
)
4267 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4268 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4269 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4272 // Interface shouldn't matter for control, but it does in practice, with Windows'
4273 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4274 for (pass
= 0; pass
< 2; pass
++) {
4275 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4276 if (priv
->usb_interface
[i
].path
!= NULL
) {
4277 if ((pass
== 0) && (priv
->usb_interface
[i
].restricted_functionality
)) {
4278 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i
);
4281 usbi_dbg("using interface %d", i
);
4282 return priv
->usb_interface
[i
].apib
->submit_control_transfer(priv
->usb_interface
[i
].sub_api
, itransfer
);
4287 usbi_err(ctx
, "no libusbx supported interfaces to complete request");
4288 return LIBUSB_ERROR_NOT_FOUND
;
4291 static int composite_submit_bulk_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
4292 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4293 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4294 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4295 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4296 int current_interface
;
4298 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
4299 if (current_interface
< 0) {
4300 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
4301 return LIBUSB_ERROR_NOT_FOUND
;
4304 return priv
->usb_interface
[current_interface
].apib
->
4305 submit_bulk_transfer(priv
->usb_interface
[current_interface
].sub_api
, itransfer
);}
4307 static int composite_submit_iso_transfer(int sub_api
, struct usbi_transfer
*itransfer
) {
4308 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4309 struct libusb_context
*ctx
= DEVICE_CTX(transfer
->dev_handle
->dev
);
4310 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(transfer
->dev_handle
);
4311 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4312 int current_interface
;
4314 current_interface
= interface_by_endpoint(priv
, handle_priv
, transfer
->endpoint
);
4315 if (current_interface
< 0) {
4316 usbi_err(ctx
, "unable to match endpoint to an open interface - cancelling transfer");
4317 return LIBUSB_ERROR_NOT_FOUND
;
4320 return priv
->usb_interface
[current_interface
].apib
->
4321 submit_iso_transfer(priv
->usb_interface
[current_interface
].sub_api
, itransfer
);}
4323 static int composite_clear_halt(int sub_api
, struct libusb_device_handle
*dev_handle
, unsigned char endpoint
)
4325 struct libusb_context
*ctx
= DEVICE_CTX(dev_handle
->dev
);
4326 struct windows_device_handle_priv
*handle_priv
= _device_handle_priv(dev_handle
);
4327 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4328 int current_interface
;
4330 current_interface
= interface_by_endpoint(priv
, handle_priv
, endpoint
);
4331 if (current_interface
< 0) {
4332 usbi_err(ctx
, "unable to match endpoint to an open interface - cannot clear");
4333 return LIBUSB_ERROR_NOT_FOUND
;
4336 return priv
->usb_interface
[current_interface
].apib
->
4337 clear_halt(priv
->usb_interface
[current_interface
].sub_api
, dev_handle
, endpoint
);}
4339 static int composite_abort_control(int sub_api
, struct usbi_transfer
*itransfer
)
4341 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4342 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4343 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4345 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4346 abort_control(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
);}
4348 static int composite_abort_transfers(int sub_api
, struct usbi_transfer
*itransfer
)
4350 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4351 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4352 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4354 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4355 abort_transfers(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
);}
4357 static int composite_reset_device(int sub_api
, struct libusb_device_handle
*dev_handle
)
4359 struct windows_device_priv
*priv
= _device_priv(dev_handle
->dev
);
4362 bool available
[SUB_API_MAX
];
4363 for (i
= 0; i
<SUB_API_MAX
; i
++) {
4364 available
[i
] = false;
4366 for (i
=0; i
<USB_MAXINTERFACES
; i
++) {
4367 if ( (priv
->usb_interface
[i
].apib
->id
== USB_API_WINUSBX
)
4368 && (priv
->usb_interface
[i
].sub_api
!= SUB_API_NOTSET
) ) {
4369 available
[priv
->usb_interface
[i
].sub_api
] = true;
4372 for (i
=0; i
<SUB_API_MAX
; i
++) {
4374 r
= usb_api_backend
[USB_API_WINUSBX
].reset_device(i
, dev_handle
);
4375 if (r
!= LIBUSB_SUCCESS
) {
4380 return LIBUSB_SUCCESS
;
4383 static int composite_copy_transfer_data(int sub_api
, struct usbi_transfer
*itransfer
, uint32_t io_size
)
4385 struct libusb_transfer
*transfer
= USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
4386 struct windows_transfer_priv
*transfer_priv
= usbi_transfer_get_os_priv(itransfer
);
4387 struct windows_device_priv
*priv
= _device_priv(transfer
->dev_handle
->dev
);
4389 return priv
->usb_interface
[transfer_priv
->interface_number
].apib
->
4390 copy_transfer_data(priv
->usb_interface
[transfer_priv
->interface_number
].sub_api
, itransfer
, io_size
);