1 /*
2 * windows backend for libusbx 1.0
3 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4 * With contributions from Michael Plante, Orin Eman et al.
5 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
6 * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
7 * Hash table functions adapted from glibc, by Ulrich Drepper et al.
8 * Major code testing contribution by Xiaofan Chen
9 *
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.
14 *
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.
19 *
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
23 */
24
25 #include <config.h>
26 #include <windows.h>
27 #include <setupapi.h>
28 #include <ctype.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <process.h>
32 #include <stdio.h>
33 #include <inttypes.h>
34 #include <objbase.h>
35 #include <winioctl.h>
36
37 #include "libusbi.h"
38 #include "poll_windows.h"
39 #include "windows_usb.h"
40
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; }
44
45 // Helper prototypes
46 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian);
47 static int windows_clock_gettime(int clk_id, struct timespec *tp);
48 unsigned __stdcall windows_clock_gettime_threaded(void* param);
49 // Common calls
50 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
51
52 // WinUSB-like API prototypes
53 static int winusbx_init(int sub_api, struct libusb_context *ctx);
54 static int winusbx_exit(int sub_api);
55 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle);
56 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle);
57 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
58 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
59 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
60 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
61 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
62 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
63 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
64 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
65 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer);
66 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
67 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
68 // HID API prototypes
69 static int hid_init(int sub_api, struct libusb_context *ctx);
70 static int hid_exit(int sub_api);
71 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle);
72 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle);
73 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
74 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
75 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
76 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
77 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
78 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
79 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
80 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
81 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
82 // Composite API prototypes
83 static int composite_init(int sub_api, struct libusb_context *ctx);
84 static int composite_exit(int sub_api);
85 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle);
86 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle);
87 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
88 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
89 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
90 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
91 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
92 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
93 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
94 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
95 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer);
96 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
97 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
98
99
100 // Global variables
101 uint64_t hires_frequency, hires_ticks_to_ps;
102 const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
103 enum windows_version windows_version = WINDOWS_UNSUPPORTED;
104 // Concurrency
105 static int concurrent_usage = -1;
106 usbi_mutex_t autoclaim_lock;
107 // Timer thread
108 // NB: index 0 is for monotonic and 1 is for the thread exit event
109 HANDLE timer_thread = NULL;
110 HANDLE timer_mutex = NULL;
111 struct timespec timer_tp;
112 volatile LONG request_count[2] = {0, 1}; // last one must be > 0
113 HANDLE timer_request[2] = { NULL, NULL };
114 HANDLE timer_response = NULL;
115 // API globals
116 #define CHECK_WINUSBX_AVAILABLE(sub_api) do { if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; \
117 if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0)
118 static struct winusb_interface WinUSBX[SUB_API_MAX];
119 const char* sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES;
120 bool api_hid_available = false;
121 #define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0)
122
guid_eq(const GUID * guid1,const GUID * guid2)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);
126 }
127 return false;
128 }
129
130 #if defined(ENABLE_LOGGING)
guid_to_string(const GUID * guid)131 static char* guid_to_string(const GUID* guid)
132 {
133 static char guid_string[MAX_GUID_STRING_LENGTH];
134
135 if (guid == NULL) return NULL;
136 sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
137 (unsigned int)guid->Data1, guid->Data2, guid->Data3,
138 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
139 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
140 return guid_string;
141 }
142 #endif
143
144 /*
145 * Converts a windows error to human readable string
146 * uses retval as errorcode, or, if 0, use GetLastError()
147 */
148 #if defined(ENABLE_LOGGING)
windows_error_str(uint32_t retval)149 static char *windows_error_str(uint32_t retval)
150 {
151 static char err_string[ERR_BUFFER_SIZE];
152
153 DWORD size;
154 ssize_t i;
155 uint32_t error_code, format_error;
156
157 error_code = retval?retval:GetLastError();
158
159 safe_sprintf(err_string, ERR_BUFFER_SIZE, "[%u] ", error_code);
160
161 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
162 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
163 ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
164 if (size == 0) {
165 format_error = GetLastError();
166 if (format_error)
167 safe_sprintf(err_string, ERR_BUFFER_SIZE,
168 "Windows error code %u (FormatMessage error code %u)", error_code, format_error);
169 else
170 safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
171 } else {
172 // Remove CR/LF terminators
173 for (i=safe_strlen(err_string)-1; (i>=0) && ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
174 err_string[i] = 0;
175 }
176 }
177 return err_string;
178 }
179 #endif
180
181 /*
182 * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
183 * Return an allocated sanitized string or NULL on error.
184 */
sanitize_path(const char * path)185 static char* sanitize_path(const char* path)
186 {
187 const char root_prefix[] = "\\\\.\\";
188 size_t j, size, root_size;
189 char* ret_path = NULL;
190 size_t add_root = 0;
191
192 if (path == NULL)
193 return NULL;
194
195 size = safe_strlen(path)+1;
196 root_size = sizeof(root_prefix)-1;
197
198 // Microsoft indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
199 if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
200 ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
201 add_root = root_size;
202 size += add_root;
203 }
204
205 if ((ret_path = (char*) calloc(size, 1)) == NULL)
206 return NULL;
207
208 safe_strcpy(&ret_path[add_root], size-add_root, path);
209
210 // Ensure consistancy with root prefix
211 for (j=0; j<root_size; j++)
212 ret_path[j] = root_prefix[j];
213
214 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
215 for(j=root_size; j<size; j++) {
216 ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
217 if (ret_path[j] == '\\')
218 ret_path[j] = '#';
219 }
220
221 return ret_path;
222 }
223
224 /*
225 * Cfgmgr32, OLE32 and SetupAPI DLL functions
226 */
init_dlls(void)227 static int init_dlls(void)
228 {
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;
246 }
247
248 /*
249 * enumerate interfaces for the whole USB class
250 *
251 * Parameters:
252 * dev_info: a pointer to a dev_info list
253 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
254 * usb_class: the generic USB class for which to retrieve interface details
255 * index: zero based index of the interface in the device info list
256 *
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.
260 */
get_devinfo_data(struct libusb_context * ctx,HDEVINFO * dev_info,SP_DEVINFO_DATA * dev_info_data,const char * usb_class,unsigned _index)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)
263 {
264 if (_index <= 0) {
265 *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
266 if (*dev_info == INVALID_HANDLE_VALUE) {
267 return false;
268 }
269 }
270
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));
276 }
277 pSetupDiDestroyDeviceInfoList(*dev_info);
278 *dev_info = INVALID_HANDLE_VALUE;
279 return false;
280 }
281 return true;
282 }
283
284 /*
285 * enumerate interfaces for a specific GUID
286 *
287 * Parameters:
288 * dev_info: a pointer to a dev_info list
289 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
290 * guid: the GUID for which to retrieve interface details
291 * index: zero based index of the interface in the device info list
292 *
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.
296 */
get_interface_details(struct libusb_context * ctx,HDEVINFO * dev_info,SP_DEVINFO_DATA * dev_info_data,const GUID * guid,unsigned _index)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)
299 {
300 SP_DEVICE_INTERFACE_DATA dev_interface_data;
301 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
302 DWORD size;
303
304 if (_index <= 0) {
305 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
306 }
307
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));
314 }
315 pSetupDiDestroyDeviceInfoList(*dev_info);
316 *dev_info = INVALID_HANDLE_VALUE;
317 return NULL;
318 }
319 }
320
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));
326 }
327 pSetupDiDestroyDeviceInfoList(*dev_info);
328 *dev_info = INVALID_HANDLE_VALUE;
329 return NULL;
330 }
331
332 // Read interface data (dummy + actual) to access the device path
333 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
334 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
335 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
336 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
337 _index, windows_error_str(0));
338 goto err_exit;
339 }
340 } else {
341 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
342 goto err_exit;
343 }
344
345 if ((dev_interface_details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) calloc(size, 1)) == NULL) {
346 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
347 goto err_exit;
348 }
349
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));
355 }
356
357 return dev_interface_details;
358
359 err_exit:
360 pSetupDiDestroyDeviceInfoList(*dev_info);
361 *dev_info = INVALID_HANDLE_VALUE;
362 return NULL;
363 }
364
365 /* For libusb0 filter */
get_interface_details_filter(struct libusb_context * ctx,HDEVINFO * dev_info,SP_DEVINFO_DATA * dev_info_data,const GUID * guid,unsigned _index,char * filter_path)366 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
367 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index, char* filter_path){
368 SP_DEVICE_INTERFACE_DATA dev_interface_data;
369 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
370 DWORD size;
371 if (_index <= 0) {
372 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
373 }
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));
380 }
381 pSetupDiDestroyDeviceInfoList(*dev_info);
382 *dev_info = INVALID_HANDLE_VALUE;
383 return NULL;
384 }
385 }
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));
391 }
392 pSetupDiDestroyDeviceInfoList(*dev_info);
393 *dev_info = INVALID_HANDLE_VALUE;
394 return NULL;
395 }
396 // Read interface data (dummy + actual) to access the device path
397 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
398 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
399 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
400 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
401 _index, windows_error_str(0));
402 goto err_exit;
403 }
404 } else {
405 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
406 goto err_exit;
407 }
408 if ((dev_interface_details = malloc(size)) == NULL) {
409 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
410 goto err_exit;
411 }
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));
417 }
418 // [trobinso] lookup the libusb0 symbolic index.
419 if (dev_interface_details) {
420 HKEY hkey_device_interface=pSetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ);
421 if (hkey_device_interface != INVALID_HANDLE_VALUE) {
422 DWORD libusb0_symboliclink_index=0;
423 DWORD value_length=sizeof(DWORD);
424 DWORD value_type=0;
425 LONG status;
426 status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type,
427 (LPBYTE) &libusb0_symboliclink_index, &value_length);
428 if (status == ERROR_SUCCESS) {
429 if (libusb0_symboliclink_index < 256) {
430 // libusb0.sys is connected to this device instance.
431 // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
432 safe_sprintf(filter_path, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index);
433 usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
434 } else {
435 // libusb0.sys was connected to this device instance at one time; but not anymore.
436 }
437 }
438 pRegCloseKey(hkey_device_interface);
439 }
440 }
441 return dev_interface_details;
442 err_exit:
443 pSetupDiDestroyDeviceInfoList(*dev_info);
444 *dev_info = INVALID_HANDLE_VALUE;
445 return NULL;}
446
447 /* Hash table functions - modified From glibc 2.3.2:
448 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
449 [Knuth] The Art of Computer Programming, part 3 (6.4) */
450 typedef struct htab_entry {
451 unsigned long used;
452 char* str;
453 } htab_entry;
454 htab_entry* htab_table = NULL;
455 usbi_mutex_t htab_write_mutex = NULL;
456 unsigned long htab_size, htab_filled;
457
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 */
isprime(unsigned long number)462 static int isprime(unsigned long number)
463 {
464 // no even number will be passed
465 unsigned int divider = 3;
466
467 while((divider * divider < number) && (number % divider != 0))
468 divider += 2;
469
470 return (number % divider != 0);
471 }
472
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. */
htab_create(struct libusb_context * ctx,unsigned long nel)477 static int htab_create(struct libusb_context *ctx, unsigned long nel)
478 {
479 if (htab_table != NULL) {
480 usbi_err(ctx, "hash table already allocated");
481 }
482
483 // Create a mutex
484 usbi_mutex_init(&htab_write_mutex, NULL);
485
486 // Change nel to the first prime number not smaller as nel.
487 nel |= 1;
488 while(!isprime(nel))
489 nel += 2;
490
491 htab_size = nel;
492 usbi_dbg("using %d entries hash table", nel);
493 htab_filled = 0;
494
495 // allocate memory and zero out.
496 htab_table = (htab_entry*) calloc(htab_size + 1, sizeof(htab_entry));
497 if (htab_table == NULL) {
498 usbi_err(ctx, "could not allocate space for hash table");
499 return 0;
500 }
501
502 return 1;
503 }
504
505 /* After using the hash table it has to be destroyed. */
htab_destroy(void)506 static void htab_destroy(void)
507 {
508 size_t i;
509 if (htab_table == NULL) {
510 return;
511 }
512
513 for (i=0; i<htab_size; i++) {
514 if (htab_table[i].used) {
515 safe_free(htab_table[i].str);
516 }
517 }
518 usbi_mutex_destroy(&htab_write_mutex);
519 safe_free(htab_table);
520 }
521
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. */
htab_hash(char * str)530 static unsigned long htab_hash(char* str)
531 {
532 unsigned long hval, hval2;
533 unsigned long idx;
534 unsigned long r = 5381;
535 int c;
536 char* sz = str;
537
538 if (str == NULL)
539 return 0;
540
541 // Compute main hash value (algorithm suggested by Nokia)
542 while ((c = *sz++) != 0)
543 r = ((r << 5) + r) + c;
544 if (r == 0)
545 ++r;
546
547 // compute table hash: simply take the modulus
548 hval = r % htab_size;
549 if (hval == 0)
550 ++hval;
551
552 // Try the first index
553 idx = hval;
554
555 if (htab_table[idx].used) {
556 if ( (htab_table[idx].used == hval)
557 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
558 // existing hash
559 return idx;
560 }
561 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
562
563 // Second hash function, as suggested in [Knuth]
564 hval2 = 1 + hval % (htab_size - 2);
565
566 do {
567 // Because size is prime this guarantees to step through all available indexes
568 if (idx <= hval2) {
569 idx = htab_size + idx - hval2;
570 } else {
571 idx -= hval2;
572 }
573
574 // If we visited all entries leave the loop unsuccessfully
575 if (idx == hval) {
576 break;
577 }
578
579 // If entry is found use it.
580 if ( (htab_table[idx].used == hval)
581 && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
582 return idx;
583 }
584 }
585 while (htab_table[idx].used);
586 }
587
588 // Not found => New entry
589
590 // If the table is full return an error
591 if (htab_filled >= htab_size) {
592 usbi_err(NULL, "hash table is full (%d entries)", htab_size);
593 return 0;
594 }
595
596 // Concurrent threads might be storing the same entry at the same time
597 // (eg. "simultaneous" enums from different threads) => use a mutex
598 usbi_mutex_lock(&htab_write_mutex);
599 // Just free any previously allocated string (which should be the same as
600 // new one). The possibility of concurrent threads storing a collision
601 // string (same hash, different string) at the same time is extremely low
602 safe_free(htab_table[idx].str);
603 htab_table[idx].used = hval;
604 htab_table[idx].str = (char*) malloc(safe_strlen(str)+1);
605 if (htab_table[idx].str == NULL) {
606 usbi_err(NULL, "could not duplicate string for hash table");
607 usbi_mutex_unlock(&htab_write_mutex);
608 return 0;
609 }
610 memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
611 ++htab_filled;
612 usbi_mutex_unlock(&htab_write_mutex);
613
614 return idx;
615 }
616
617 /*
618 * Returns the session ID of a device's nth level ancestor
619 * If there's no device at the nth level, return 0
620 */
get_ancestor_session_id(DWORD devinst,unsigned level)621 static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
622 {
623 DWORD parent_devinst;
624 unsigned long session_id = 0;
625 char* sanitized_path = NULL;
626 char path[MAX_PATH_LENGTH];
627 unsigned i;
628
629 if (level < 1) return 0;
630 for (i = 0; i<level; i++) {
631 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
632 return 0;
633 }
634 devinst = parent_devinst;
635 }
636 if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
637 return 0;
638 }
639 // TODO: (post hotplug): try without sanitizing
640 sanitized_path = sanitize_path(path);
641 if (sanitized_path == NULL) {
642 return 0;
643 }
644 session_id = htab_hash(sanitized_path);
645 safe_free(sanitized_path);
646 return session_id;
647 }
648
649 /*
650 * Populate the endpoints addresses of the device_priv interface helper structs
651 */
windows_assign_endpoints(struct libusb_device_handle * dev_handle,int iface,int altsetting)652 static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
653 {
654 int i, r;
655 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
656 struct libusb_config_descriptor *conf_desc;
657 const struct libusb_interface_descriptor *if_desc;
658 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
659
660 r = libusb_get_config_descriptor(dev_handle->dev, 0, &conf_desc);
661 if (r != LIBUSB_SUCCESS) {
662 usbi_warn(ctx, "could not read config descriptor: error %d", r);
663 return r;
664 }
665
666 if_desc = &conf_desc->interface[iface].altsetting[altsetting];
667 safe_free(priv->usb_interface[iface].endpoint);
668
669 if (if_desc->bNumEndpoints == 0) {
670 usbi_dbg("no endpoints found for interface %d", iface);
671 return LIBUSB_SUCCESS;
672 }
673
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;
677 }
678
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);
683 }
684 libusb_free_config_descriptor(conf_desc);
685
686 // Extra init may be required to configure endpoints
687 return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
688 }
689
690 // Lookup for a match in the list of API driver names
691 // return -1 if not found, driver match number otherwise
get_sub_api(char * driver,int api)692 static int get_sub_api(char* driver, int api){
693 int i;
694 const char sep_str[2] = {LIST_SEPARATOR, 0};
695 char *tok, *tmp_str;
696 size_t len = safe_strlen(driver);
697
698 if (len == 0) return SUB_API_NOTSET;
699 tmp_str = (char*) calloc(len+1, 1);
700 if (tmp_str == NULL) return SUB_API_NOTSET;
701 memcpy(tmp_str, driver, len+1);
702 tok = strtok(tmp_str, sep_str);
703 while (tok != NULL) {
704 for (i=0; i<usb_api_backend[api].nb_driver_names; i++) {
705 if (safe_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
706 free(tmp_str);
707 return i;
708 }
709 }
710 tok = strtok(NULL, sep_str);
711 }
712 free (tmp_str);
713 return SUB_API_NOTSET;
714 }
715
716 /*
717 * auto-claiming and auto-release helper functions
718 */
auto_claim(struct libusb_transfer * transfer,int * interface_number,int api_type)719 static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
720 {
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;
727
728 switch(api_type) {
729 case USB_API_WINUSBX:
730 case USB_API_HID:
731 break;
732 default:
733 return LIBUSB_ERROR_INVALID_PARAM;
734 }
735
736 usbi_mutex_lock(&autoclaim_lock);
737 if (current_interface < 0) // No serviceable interface was found
738 {
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");
746 }
747 handle_priv->autoclaim_count[current_interface]++;
748 break;
749 }
750 }
751 if (current_interface == USB_MAXINTERFACES) {
752 usbi_err(ctx, "could not auto-claim any interface");
753 r = LIBUSB_ERROR_NOT_FOUND;
754 }
755 } else {
756 // If we have a valid interface that was autoclaimed, we must increment
757 // its autoclaim count so that we can prevent an early release.
758 if (handle_priv->autoclaim_count[current_interface] != 0) {
759 handle_priv->autoclaim_count[current_interface]++;
760 }
761 }
762 usbi_mutex_unlock(&autoclaim_lock);
763
764 *interface_number = current_interface;
765 return r;
766
767 }
768
auto_release(struct usbi_transfer * itransfer)769 static void auto_release(struct usbi_transfer *itransfer)
770 {
771 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
772 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
773 libusb_device_handle *dev_handle = transfer->dev_handle;
774 struct windows_device_handle_priv* handle_priv = _device_handle_priv(dev_handle);
775 int r;
776
777 usbi_mutex_lock(&autoclaim_lock);
778 if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
779 handle_priv->autoclaim_count[transfer_priv->interface_number]--;
780 if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
781 r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
782 if (r == LIBUSB_SUCCESS) {
783 usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
784 } else {
785 usbi_dbg("failed to auto-release interface %d (%s)",
786 transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
787 }
788 }
789 }
790 usbi_mutex_unlock(&autoclaim_lock);
791 }
792
793 /*
794 * init: libusbx backend init function
795 *
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?)
799 */
windows_init(struct libusb_context * ctx)800 static int windows_init(struct libusb_context *ctx)
801 {
802 int i, r = LIBUSB_ERROR_OTHER;
803 OSVERSIONINFO os_version;
804 HANDLE semaphore;
805 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
806
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;
812 }
813
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;
820 }
821
822 // NB: concurrent usage supposes that init calls are equally balanced with
823 // exit calls. If init is called more than exit, we will not exit properly
824 if ( ++concurrent_usage == 0 ) { // First init?
825 // Detect OS version
826 memset(&os_version, 0, sizeof(OSVERSIONINFO));
827 os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
828 windows_version = WINDOWS_UNSUPPORTED;
829 if ((GetVersionEx(&os_version) != 0) && (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
830 if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 1)) {
831 windows_version = WINDOWS_XP;
832 } else if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 2)) {
833 windows_version = WINDOWS_2003; // also includes XP 64
834 } else if (os_version.dwMajorVersion >= 6) {
835 windows_version = WINDOWS_VISTA_AND_LATER;
836 }
837 }
838 if (windows_version == WINDOWS_UNSUPPORTED) {
839 usbi_err(ctx, "This version of Windows is NOT supported");
840 r = LIBUSB_ERROR_NOT_SUPPORTED;
841 goto init_exit;
842 }
843
844 // We need a lock for proper auto-release
845 usbi_mutex_init(&autoclaim_lock, NULL);
846
847 // Initialize pollable file descriptors
848 init_polling();
849
850 // Load DLL imports
851 if (init_dlls() != LIBUSB_SUCCESS) {
852 usbi_err(ctx, "could not resolve DLL functions");
853 return LIBUSB_ERROR_NOT_FOUND;
854 }
855
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);
859 }
860
861 // Because QueryPerformanceCounter might report different values when
862 // running on different cores, we create a separate thread for the timer
863 // calls, which we glue to the first core always to prevent timing discrepancies.
864 r = LIBUSB_ERROR_NO_MEM;
865 for (i = 0; i < 2; i++) {
866 timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
867 if (timer_request[i] == NULL) {
868 usbi_err(ctx, "could not create timer request event %d - aborting", i);
869 goto init_exit;
870 }
871 }
872 timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
873 if (timer_response == NULL) {
874 usbi_err(ctx, "could not create timer response semaphore - aborting");
875 goto init_exit;
876 }
877 timer_mutex = CreateMutex(NULL, FALSE, NULL);
878 if (timer_mutex == NULL) {
879 usbi_err(ctx, "could not create timer mutex - aborting");
880 goto init_exit;
881 }
882 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, NULL, 0, NULL);
883 if (timer_thread == NULL) {
884 usbi_err(ctx, "Unable to create timer thread - aborting");
885 goto init_exit;
886 }
887 SetThreadAffinityMask(timer_thread, 0);
888
889 // Wait for timer thread to init before continuing.
890 if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
891 usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
892 goto init_exit;
893 }
894
895 // Create a hash table to store session ids. Second parameter is better if prime
896 htab_create(ctx, HTAB_SIZE);
897 }
898 // At this stage, either we went through full init successfully, or didn't need to
899 r = LIBUSB_SUCCESS;
900
901 init_exit: // Holds semaphore here.
902 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
903 if (timer_thread) {
904 SetEvent(timer_request[1]); // actually the signal to quit the thread.
905 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
906 usbi_warn(ctx, "could not wait for timer thread to quit");
907 TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
908 // all objects it might have held anyway.
909 }
910 CloseHandle(timer_thread);
911 timer_thread = NULL;
912 }
913 for (i = 0; i < 2; i++) {
914 if (timer_request[i]) {
915 CloseHandle(timer_request[i]);
916 timer_request[i] = NULL;
917 }
918 }
919 if (timer_response) {
920 CloseHandle(timer_response);
921 timer_response = NULL;
922 }
923 if (timer_mutex) {
924 CloseHandle(timer_mutex);
925 timer_mutex = NULL;
926 }
927 htab_destroy();
928 }
929
930 if (r != LIBUSB_SUCCESS)
931 --concurrent_usage; // Not expected to call libusb_exit if we failed.
932
933 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
934 CloseHandle(semaphore);
935 return r;
936 }
937
938 /*
939 * HCD (root) hubs need to have their device descriptor manually populated
940 *
941 * Note that, like Microsoft does in the device manager, we populate the
942 * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device.
943 */
force_hcd_device_descriptor(struct libusb_device * dev)944 static int force_hcd_device_descriptor(struct libusb_device *dev)
945 {
946 struct windows_device_priv *parent_priv, *priv = _device_priv(dev);
947 struct libusb_context *ctx = DEVICE_CTX(dev);
948 int vid, pid;
949
950 dev->num_configurations = 1;
951 priv->dev_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
952 priv->dev_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
953 priv->dev_descriptor.bNumConfigurations = 1;
954 priv->active_config = 1;
955
956 if (priv->parent_dev == NULL) {
957 usbi_err(ctx, "program assertion failed - HCD hub has no parent");
958 return LIBUSB_ERROR_NO_DEVICE;
959 }
960 parent_priv = _device_priv(priv->parent_dev);
961 if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) {
962 priv->dev_descriptor.idVendor = (uint16_t)vid;
963 priv->dev_descriptor.idProduct = (uint16_t)pid;
964 } else {
965 usbi_warn(ctx, "could not infer VID/PID of HCD hub from '%s'", parent_priv->path);
966 priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub
967 priv->dev_descriptor.idProduct = 1;
968 }
969 return LIBUSB_SUCCESS;
970 }
971
972 /*
973 * fetch and cache all the config descriptors through I/O
974 */
cache_config_descriptors(struct libusb_device * dev,HANDLE hub_handle,char * device_id)975 static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char* device_id)
976 {
977 DWORD size, ret_size;
978 struct libusb_context *ctx = DEVICE_CTX(dev);
979 struct windows_device_priv *priv = _device_priv(dev);
980 int r;
981 uint8_t i;
982
983 USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
984 PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
985 PUSB_CONFIGURATION_DESCRIPTOR cd_data = NULL;
986
987 if (dev->num_configurations == 0)
988 return LIBUSB_ERROR_INVALID_PARAM;
989
990 priv->config_descriptor = (unsigned char**) calloc(dev->num_configurations, sizeof(unsigned char*));
991 if (priv->config_descriptor == NULL)
992 return LIBUSB_ERROR_NO_MEM;
993 for (i=0; i<dev->num_configurations; i++)
994 priv->config_descriptor[i] = NULL;
995
996 for (i=0, r=LIBUSB_SUCCESS; ; i++)
997 {
998 // safe loop: release all dynamic resources
999 safe_free(cd_buf_actual);
1000
1001 // safe loop: end of loop condition
1002 if ((i >= dev->num_configurations) || (r != LIBUSB_SUCCESS))
1003 break;
1004
1005 size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT);
1006 memset(&cd_buf_short, 0, size);
1007
1008 cd_buf_short.req.ConnectionIndex = (ULONG)priv->port;
1009 cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1010 cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1011 cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1012 cd_buf_short.req.SetupPacket.wIndex = i;
1013 cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1014
1015 // Dummy call to get the required data size. Initial failures are reported as info rather
1016 // than error as they can occur for non-penalizing situations, such as with some hubs.
1017 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
1018 &cd_buf_short, size, &ret_size, NULL)) {
1019 usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
1020 LOOP_BREAK(LIBUSB_ERROR_IO);
1021 }
1022
1023 if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
1024 usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
1025 LOOP_BREAK(LIBUSB_ERROR_IO);
1026 }
1027
1028 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
1029 if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
1030 usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
1031 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1032 }
1033 memset(cd_buf_actual, 0, size);
1034
1035 // Actual call
1036 cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
1037 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1038 cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1039 cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1040 cd_buf_actual->SetupPacket.wIndex = i;
1041 cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1042
1043 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1044 cd_buf_actual, size, &ret_size, NULL)) {
1045 usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1046 LOOP_BREAK(LIBUSB_ERROR_IO);
1047 }
1048
1049 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1050
1051 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1052 usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1053 LOOP_BREAK(LIBUSB_ERROR_IO);
1054 }
1055
1056 if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1057 usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1058 LOOP_BREAK(LIBUSB_ERROR_IO);
1059 }
1060
1061 usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1062 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1063
1064 // Cache the descriptor
1065 priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1066 if (priv->config_descriptor[i] == NULL)
1067 return LIBUSB_ERROR_NO_MEM;
1068 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1069 }
1070 return LIBUSB_SUCCESS;
1071 }
1072
1073 /*
1074 * Populate a libusbx device structure
1075 */
init_device(struct libusb_device * dev,struct libusb_device * parent_dev,uint8_t port_number,char * device_id,DWORD devinst)1076 static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1077 uint8_t port_number, char* device_id, DWORD devinst)
1078 {
1079 HANDLE handle;
1080 DWORD size;
1081 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1082 struct windows_device_priv *priv, *parent_priv;
1083 struct libusb_context *ctx = DEVICE_CTX(dev);
1084 struct libusb_device* tmp_dev;
1085 unsigned i;
1086
1087 if ((dev == NULL) || (parent_dev == NULL)) {
1088 return LIBUSB_ERROR_NOT_FOUND;
1089 }
1090 priv = _device_priv(dev);
1091 parent_priv = _device_priv(parent_dev);
1092 if (parent_priv->apib->id != USB_API_HUB) {
1093 usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1094 return LIBUSB_ERROR_NOT_FOUND;
1095 }
1096
1097 // It is possible for the parent hub not to have been initialized yet
1098 // If that's the case, lookup the ancestors to set the bus number
1099 if (parent_dev->bus_number == 0) {
1100 for (i=2; ; i++) {
1101 tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
1102 if (tmp_dev == NULL) break;
1103 if (tmp_dev->bus_number != 0) {
1104 usbi_dbg("got bus number from ancestor #%d", i);
1105 parent_dev->bus_number = tmp_dev->bus_number;
1106 break;
1107 }
1108 }
1109 }
1110 if (parent_dev->bus_number == 0) {
1111 usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1112 return LIBUSB_ERROR_NOT_FOUND;
1113 }
1114 dev->bus_number = parent_dev->bus_number;
1115 priv->port = port_number;
1116 dev->port_number = port_number;
1117 priv->depth = parent_priv->depth + 1;
1118 priv->parent_dev = parent_dev;
1119 dev->parent_dev = libusb_ref_device(parent_dev);
1120
1121 // If the device address is already set, we can stop here
1122 if (dev->device_address != 0) {
1123 return LIBUSB_SUCCESS;
1124 }
1125 memset(&conn_info, 0, sizeof(conn_info));
1126 if (priv->depth != 0) { // Not a HCD hub
1127 handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1128 FILE_FLAG_OVERLAPPED, NULL);
1129 if (handle == INVALID_HANDLE_VALUE) {
1130 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1131 return LIBUSB_ERROR_ACCESS;
1132 }
1133 size = sizeof(conn_info);
1134 conn_info.ConnectionIndex = (ULONG)port_number;
1135 if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1136 &conn_info, size, &size, NULL)) {
1137 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1138 device_id, windows_error_str(0));
1139 safe_closehandle(handle);
1140 return LIBUSB_ERROR_NO_DEVICE;
1141 }
1142 if (conn_info.ConnectionStatus == NoDeviceConnected) {
1143 usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1144 safe_closehandle(handle);
1145 return LIBUSB_ERROR_NO_DEVICE;
1146 }
1147 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1148 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1149 priv->active_config = conn_info.CurrentConfigurationValue;
1150 usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1151 // If we can't read the config descriptors, just set the number of confs to zero
1152 if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1153 dev->num_configurations = 0;
1154 priv->dev_descriptor.bNumConfigurations = 0;
1155 }
1156 safe_closehandle(handle);
1157
1158 if (conn_info.DeviceAddress > UINT8_MAX) {
1159 usbi_err(ctx, "program assertion failed: device address overflow");
1160 }
1161 dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1162 if (dev->device_address == 1) {
1163 usbi_err(ctx, "program assertion failed: device address collision with root hub");
1164 }
1165 switch (conn_info.Speed) {
1166 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1167 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1168 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1169 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1170 default:
1171 usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1172 break;
1173 }
1174 } else {
1175 dev->device_address = 1; // root hubs are set to use device number 1
1176 force_hcd_device_descriptor(dev);
1177 }
1178
1179 usbi_sanitize_device(dev);
1180
1181 usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1182 dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1183
1184 return LIBUSB_SUCCESS;
1185 }
1186
1187 // Returns the api type, or 0 if not found/unsupported
get_api_type(struct libusb_context * ctx,HDEVINFO * dev_info,SP_DEVINFO_DATA * dev_info_data,int * api,int * sub_api)1188 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1189 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1190 {
1191 // Precedence for filter drivers vs driver is in the order of this array
1192 struct driver_lookup lookup[3] = {
1193 {"\0\0", SPDRP_SERVICE, "driver"},
1194 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1195 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1196 };
1197 DWORD size, reg_type;
1198 unsigned k, l;
1199 int i, j;
1200
1201 *api = USB_API_UNSUPPORTED;
1202 *sub_api = SUB_API_NOTSET;
1203 // Check the service & filter names to know the API we should use
1204 for (k=0; k<3; k++) {
1205 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1206 ®_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1207 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1208 if (lookup[k].reg_prop == SPDRP_SERVICE) {
1209 // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1210 lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1211 }
1212 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1213 // NB: none of the driver names we check against contain LIST_SEPARATOR,
1214 // (currently ';'), so even if an unsuported one does, it's not an issue
1215 for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1216 if (lookup[k].list[l] == 0) {
1217 lookup[k].list[l] = LIST_SEPARATOR;
1218 }
1219 }
1220 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1221 } else {
1222 if (GetLastError() != ERROR_INVALID_DATA) {
1223 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1224 }
1225 lookup[k].list[0] = 0;
1226 }
1227 }
1228
1229 for (i=1; i<USB_API_MAX; i++) {
1230 for (k=0; k<3; k++) {
1231 j = get_sub_api(lookup[k].list, i);
1232 if (j >= 0) {
1233 usbi_dbg("matched %s name against %s API",
1234 lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1235 *api = i;
1236 *sub_api = j;
1237 return;
1238 }
1239 }
1240 }
1241 }
1242
set_composite_interface(struct libusb_context * ctx,struct libusb_device * dev,char * dev_interface_path,char * device_id,int api,int sub_api)1243 static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1244 char* dev_interface_path, char* device_id, int api, int sub_api)
1245 {
1246 unsigned i;
1247 struct windows_device_priv *priv = _device_priv(dev);
1248 int interface_number;
1249
1250 if (priv->apib->id != USB_API_COMPOSITE) {
1251 usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1252 return LIBUSB_ERROR_NO_DEVICE;
1253 }
1254
1255 // Because MI_## are not necessarily in sequential order (some composite
1256 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1257 // interface number from the path's MI value
1258 interface_number = 0;
1259 for (i=0; device_id[i] != 0; ) {
1260 if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1261 && (device_id[i++] == '_') ) {
1262 interface_number = (device_id[i++] - '0')*10;
1263 interface_number += device_id[i] - '0';
1264 break;
1265 }
1266 }
1267
1268 if (device_id[i] == 0) {
1269 usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1270 device_id, interface_number);
1271 }
1272
1273 if (priv->usb_interface[interface_number].path != NULL) {
1274 if (api == USB_API_HID) {
1275 // HID devices can have multiple collections (COL##) for each MI_## interface
1276 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1277 interface_number, device_id);
1278 return LIBUSB_ERROR_ACCESS;
1279 }
1280 // In other cases, just use the latest data
1281 safe_free(priv->usb_interface[interface_number].path);
1282 }
1283
1284 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1285 priv->usb_interface[interface_number].path = dev_interface_path;
1286 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1287 priv->usb_interface[interface_number].sub_api = sub_api;
1288 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1289 priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
1290 if (priv->hid == NULL)
1291 return LIBUSB_ERROR_NO_MEM;
1292 }
1293
1294 return LIBUSB_SUCCESS;
1295 }
1296
set_hid_interface(struct libusb_context * ctx,struct libusb_device * dev,char * dev_interface_path)1297 static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1298 char* dev_interface_path)
1299 {
1300 int i;
1301 struct windows_device_priv *priv = _device_priv(dev);
1302
1303 if (priv->hid == NULL) {
1304 usbi_err(ctx, "program assertion failed: parent is not HID");
1305 return LIBUSB_ERROR_NO_DEVICE;
1306 }
1307 if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1308 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1309 return LIBUSB_ERROR_NO_DEVICE;
1310 }
1311 for (i=0; i<priv->hid->nb_interfaces; i++) {
1312 if (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
1313 usbi_dbg("interface[%d] already set to %s", i, dev_interface_path);
1314 return LIBUSB_SUCCESS;
1315 }
1316 }
1317
1318 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1319 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1320 usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1321 priv->hid->nb_interfaces++;
1322 return LIBUSB_SUCCESS;
1323 }
1324
1325 /*
1326 * get_device_list: libusbx backend device enumeration function
1327 */
windows_get_device_list(struct libusb_context * ctx,struct discovered_devs ** _discdevs)1328 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1329 {
1330 struct discovered_devs *discdevs;
1331 HDEVINFO dev_info = { 0 };
1332 const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1333 SP_DEVINFO_DATA dev_info_data = { 0 };
1334 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1335 GUID hid_guid;
1336 #define MAX_ENUM_GUIDS 64
1337 const GUID* guid[MAX_ENUM_GUIDS];
1338 #define HCD_PASS 0
1339 #define HUB_PASS 1
1340 #define GEN_PASS 2
1341 #define DEV_PASS 3
1342 #define HID_PASS 4
1343 int r = LIBUSB_SUCCESS;
1344 int api, sub_api;
1345 size_t class_index = 0;
1346 unsigned int nb_guids, pass, i, j, ancestor;
1347 char path[MAX_PATH_LENGTH];
1348 char strbuf[MAX_PATH_LENGTH];
1349 struct libusb_device *dev, *parent_dev;
1350 struct windows_device_priv *priv, *parent_priv;
1351 char* dev_interface_path = NULL;
1352 char* dev_id_path = NULL;
1353 unsigned long session_id;
1354 DWORD size, reg_type, port_nr, install_state;
1355 HKEY key;
1356 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1357 GUID* if_guid;
1358 LONG s;
1359 // Keep a list of newly allocated devs to unref
1360 libusb_device** unref_list;
1361 unsigned int unref_size = 64;
1362 unsigned int unref_cur = 0;
1363
1364 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1365 // PASS 2 : (re)enumerate HUBS
1366 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1367 // and list additional USB device interface GUIDs to explore
1368 // PASS 4 : (re)enumerate master USB devices that have a device interface
1369 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1370 // set the device interfaces.
1371
1372 // Init the GUID table
1373 guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1374 guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1375 guid[GEN_PASS] = NULL;
1376 guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1377 HidD_GetHidGuid(&hid_guid);
1378 guid[HID_PASS] = &hid_guid;
1379 nb_guids = HID_PASS+1;
1380
1381 unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1382 if (unref_list == NULL) {
1383 return LIBUSB_ERROR_NO_MEM;
1384 }
1385
1386 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1387 //#define ENUM_DEBUG
1388 #ifdef ENUM_DEBUG
1389 const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1390 usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1391 (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1392 #endif
1393 for (i = 0; ; i++) {
1394 // safe loop: free up any (unprotected) dynamic resource
1395 // NB: this is always executed before breaking the loop
1396 safe_free(dev_interface_details);
1397 safe_free(dev_interface_path);
1398 safe_free(dev_id_path);
1399 priv = parent_priv = NULL;
1400 dev = parent_dev = NULL;
1401
1402 // Safe loop: end of loop conditions
1403 if (r != LIBUSB_SUCCESS) {
1404 break;
1405 }
1406 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1407 usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1408 break;
1409 }
1410 if (pass != GEN_PASS) {
1411 // Except for GEN, all passes deal with device interfaces
1412 dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1413 if (dev_interface_details == NULL) {
1414 break;
1415 } else {
1416 dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1417 if (dev_interface_path == NULL) {
1418 usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1419 continue;
1420 }
1421 }
1422 } else {
1423 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1424 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1425 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1426 for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1427 if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1428 break;
1429 i = 0;
1430 }
1431 if (class_index >= ARRAYSIZE(usb_class))
1432 break;
1433 }
1434
1435 // Read the Device ID path. This is what we'll use as UID
1436 // Note that if the device is plugged in a different port or hub, the Device ID changes
1437 if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1438 usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1439 dev_info_data.DevInst);
1440 continue;
1441 }
1442 dev_id_path = sanitize_path(path);
1443 if (dev_id_path == NULL) {
1444 usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1445 dev_info_data.DevInst);
1446 continue;
1447 }
1448 #ifdef ENUM_DEBUG
1449 usbi_dbg("PRO: %s", dev_id_path);
1450 #endif
1451
1452 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1453 port_nr = 0;
1454 if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1455 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1456 ®_type, (BYTE*)&port_nr, 4, &size))
1457 || (size != 4) ) {
1458 usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1459 dev_id_path, windows_error_str(0));
1460 continue;
1461 }
1462 }
1463
1464 // Set API to use or get additional data from generic pass
1465 api = USB_API_UNSUPPORTED;
1466 sub_api = SUB_API_NOTSET;
1467 switch (pass) {
1468 case HCD_PASS:
1469 break;
1470 case GEN_PASS:
1471 // We use the GEN pass to detect driverless devices...
1472 size = sizeof(strbuf);
1473 if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1474 ®_type, (BYTE*)strbuf, size, &size)) {
1475 usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1476 usbi_info(ctx, "libusbx will not be able to access it.");
1477 }
1478 // ...and to add the additional device interface GUIDs
1479 key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1480 if (key != INVALID_HANDLE_VALUE) {
1481 size = sizeof(guid_string_w);
1482 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1483 (BYTE*)guid_string_w, &size);
1484 pRegCloseKey(key);
1485 if (s == ERROR_SUCCESS) {
1486 if (nb_guids >= MAX_ENUM_GUIDS) {
1487 // If this assert is ever reported, grow a GUID table dynamically
1488 usbi_err(ctx, "program assertion failed: too many GUIDs");
1489 LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1490 }
1491 if_guid = (GUID*) calloc(1, sizeof(GUID));
1492 pCLSIDFromString(guid_string_w, if_guid);
1493 guid[nb_guids++] = if_guid;
1494 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1495 }
1496 }
1497 break;
1498 case HID_PASS:
1499 api = USB_API_HID;
1500 break;
1501 default:
1502 // Get the API type (after checking that the driver installation is OK)
1503 if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1504 ®_type, (BYTE*)&install_state, 4, &size))
1505 || (size != 4) ){
1506 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1507 dev_id_path, windows_error_str(0));
1508 } else if (install_state != 0) {
1509 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1510 dev_id_path, install_state);
1511 continue;
1512 }
1513 get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1514 break;
1515 }
1516
1517 // Find parent device (for the passes that need it)
1518 switch (pass) {
1519 case HCD_PASS:
1520 case DEV_PASS:
1521 case HUB_PASS:
1522 break;
1523 default:
1524 // Go through the ancestors until we see a face we recognize
1525 parent_dev = NULL;
1526 for (ancestor = 1; parent_dev == NULL; ancestor++) {
1527 session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1528 if (session_id == 0) {
1529 break;
1530 }
1531 parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1532 }
1533 if (parent_dev == NULL) {
1534 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1535 continue;
1536 }
1537 parent_priv = _device_priv(parent_dev);
1538 // virtual USB devices are also listed during GEN - don't process these yet
1539 if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1540 continue;
1541 }
1542 break;
1543 }
1544
1545 // Create new or match existing device, using the (hashed) device_id as session id
1546 if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1547 // These are the passes that create "new" devices
1548 session_id = htab_hash(dev_id_path);
1549 dev = usbi_get_device_by_session_id(ctx, session_id);
1550 if (dev == NULL) {
1551 if (pass == DEV_PASS) {
1552 // This can occur if the OS only reports a newly plugged device after we started enum
1553 usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1554 " - ignoring", dev_id_path);
1555 continue;
1556 }
1557 usbi_dbg("allocating new device for session [%X]", session_id);
1558 if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1559 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1560 }
1561 windows_device_priv_init(dev);
1562 // Keep track of devices that need unref
1563 unref_list[unref_cur++] = dev;
1564 if (unref_cur >= unref_size) {
1565 unref_size += 64;
1566 unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1567 if (unref_list == NULL) {
1568 usbi_err(ctx, "could not realloc list for unref - aborting.");
1569 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1570 }
1571 }
1572 } else {
1573 usbi_dbg("found existing device for session [%X] (%d.%d)",
1574 session_id, dev->bus_number, dev->device_address);
1575 }
1576 priv = _device_priv(dev);
1577 }
1578
1579 // Setup device
1580 switch (pass) {
1581 case HCD_PASS:
1582 dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1583 dev->device_address = 0;
1584 dev->num_configurations = 0;
1585 priv->apib = &usb_api_backend[USB_API_HUB];
1586 priv->sub_api = SUB_API_NOTSET;
1587 priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1588 priv->path = dev_interface_path; dev_interface_path = NULL;
1589 break;
1590 case HUB_PASS:
1591 case DEV_PASS:
1592 // If the device has already been setup, don't do it again
1593 if (priv->path != NULL)
1594 break;
1595 // Take care of API initialization
1596 priv->path = dev_interface_path; dev_interface_path = NULL;
1597 priv->apib = &usb_api_backend[api];
1598 priv->sub_api = sub_api;
1599 switch(api) {
1600 case USB_API_COMPOSITE:
1601 case USB_API_HUB:
1602 break;
1603 case USB_API_HID:
1604 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1605 if (priv->hid == NULL) {
1606 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1607 }
1608 priv->hid->nb_interfaces = 0;
1609 break;
1610 default:
1611 // For other devices, the first interface is the same as the device
1612 priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1613 if (priv->usb_interface[0].path != NULL) {
1614 safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1615 } else {
1616 usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1617 }
1618 // The following is needed if we want API calls to work for both simple
1619 // and composite devices.
1620 for(j=0; j<USB_MAXINTERFACES; j++) {
1621 priv->usb_interface[j].apib = &usb_api_backend[api];
1622 }
1623 break;
1624 }
1625 break;
1626 case GEN_PASS:
1627 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1628 if (r == LIBUSB_SUCCESS) {
1629 // Append device to the list of discovered devices
1630 discdevs = discovered_devs_append(*_discdevs, dev);
1631 if (!discdevs) {
1632 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1633 }
1634 *_discdevs = discdevs;
1635 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1636 // This can occur if the device was disconnected but Windows hasn't
1637 // refreshed its enumeration yet - in that case, we ignore the device
1638 r = LIBUSB_SUCCESS;
1639 }
1640 break;
1641 default: // HID_PASS and later
1642 if (parent_priv->apib->id == USB_API_HID) {
1643 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1644 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1645 if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1646 dev_interface_path = NULL;
1647 } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1648 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1649 switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1650 case LIBUSB_SUCCESS:
1651 dev_interface_path = NULL;
1652 break;
1653 case LIBUSB_ERROR_ACCESS:
1654 // interface has already been set => make sure dev_interface_path is freed then
1655 break;
1656 default:
1657 LOOP_BREAK(r);
1658 break;
1659 }
1660 }
1661 break;
1662 }
1663 }
1664 }
1665
1666 // Free any additional GUIDs
1667 for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1668 safe_free(guid[pass]);
1669 }
1670
1671 // Unref newly allocated devs
1672 for (i=0; i<unref_cur; i++) {
1673 safe_unref_device(unref_list[i]);
1674 }
1675 safe_free(unref_list);
1676
1677 return r;
1678 }
1679
1680 /*
1681 * exit: libusbx backend deinitialization function
1682 */
windows_exit(void)1683 static void windows_exit(void)
1684 {
1685 int i;
1686 HANDLE semaphore;
1687 char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1688
1689 sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1690 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1691 if (semaphore == NULL) {
1692 return;
1693 }
1694
1695 // A successful wait brings our semaphore count to 0 (unsignaled)
1696 // => any concurent wait stalls until the semaphore release
1697 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1698 CloseHandle(semaphore);
1699 return;
1700 }
1701
1702 // Only works if exits and inits are balanced exactly
1703 if (--concurrent_usage < 0) { // Last exit
1704 for (i=0; i<USB_API_MAX; i++) {
1705 usb_api_backend[i].exit(SUB_API_NOTSET);
1706 }
1707 exit_polling();
1708
1709 if (timer_thread) {
1710 SetEvent(timer_request[1]); // actually the signal to quit the thread.
1711 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
1712 usbi_dbg("could not wait for timer thread to quit");
1713 TerminateThread(timer_thread, 1);
1714 }
1715 CloseHandle(timer_thread);
1716 timer_thread = NULL;
1717 }
1718 for (i = 0; i < 2; i++) {
1719 if (timer_request[i]) {
1720 CloseHandle(timer_request[i]);
1721 timer_request[i] = NULL;
1722 }
1723 }
1724 if (timer_response) {
1725 CloseHandle(timer_response);
1726 timer_response = NULL;
1727 }
1728 if (timer_mutex) {
1729 CloseHandle(timer_mutex);
1730 timer_mutex = NULL;
1731 }
1732 htab_destroy();
1733 }
1734
1735 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1736 CloseHandle(semaphore);
1737 }
1738
windows_get_device_descriptor(struct libusb_device * dev,unsigned char * buffer,int * host_endian)1739 static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1740 {
1741 struct windows_device_priv *priv = _device_priv(dev);
1742
1743 memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1744 *host_endian = 0;
1745
1746 return LIBUSB_SUCCESS;
1747 }
1748
windows_get_config_descriptor(struct libusb_device * dev,uint8_t config_index,unsigned char * buffer,size_t len,int * host_endian)1749 static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1750 {
1751 struct windows_device_priv *priv = _device_priv(dev);
1752 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1753 size_t size;
1754
1755 // config index is zero based
1756 if (config_index >= dev->num_configurations)
1757 return LIBUSB_ERROR_INVALID_PARAM;
1758
1759 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1760 return LIBUSB_ERROR_NOT_FOUND;
1761
1762 config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1763
1764 size = min(config_header->wTotalLength, len);
1765 memcpy(buffer, priv->config_descriptor[config_index], size);
1766 *host_endian = 0;
1767
1768 return (int)size;
1769 }
1770
1771 /*
1772 * return the cached copy of the active config descriptor
1773 */
windows_get_active_config_descriptor(struct libusb_device * dev,unsigned char * buffer,size_t len,int * host_endian)1774 static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1775 {
1776 struct windows_device_priv *priv = _device_priv(dev);
1777
1778 if (priv->active_config == 0)
1779 return LIBUSB_ERROR_NOT_FOUND;
1780
1781 // config index is zero based
1782 return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1783 }
1784
windows_open(struct libusb_device_handle * dev_handle)1785 static int windows_open(struct libusb_device_handle *dev_handle)
1786 {
1787 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1788 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1789
1790 if (priv->apib == NULL) {
1791 usbi_err(ctx, "program assertion failed - device is not initialized");
1792 return LIBUSB_ERROR_NO_DEVICE;
1793 }
1794
1795 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1796 }
1797
windows_close(struct libusb_device_handle * dev_handle)1798 static void windows_close(struct libusb_device_handle *dev_handle)
1799 {
1800 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1801
1802 priv->apib->close(SUB_API_NOTSET, dev_handle);
1803 }
1804
windows_get_configuration(struct libusb_device_handle * dev_handle,int * config)1805 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1806 {
1807 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1808
1809 if (priv->active_config == 0) {
1810 *config = 0;
1811 return LIBUSB_ERROR_NOT_FOUND;
1812 }
1813
1814 *config = priv->active_config;
1815 return LIBUSB_SUCCESS;
1816 }
1817
1818 /*
1819 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1820 * does not currently expose a service that allows higher-level drivers to set
1821 * the configuration."
1822 */
windows_set_configuration(struct libusb_device_handle * dev_handle,int config)1823 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1824 {
1825 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1826 int r = LIBUSB_SUCCESS;
1827
1828 if (config >= USB_MAXCONFIG)
1829 return LIBUSB_ERROR_INVALID_PARAM;
1830
1831 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1832 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1833 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1834 0, NULL, 0, 1000);
1835
1836 if (r == LIBUSB_SUCCESS) {
1837 priv->active_config = (uint8_t)config;
1838 }
1839 return r;
1840 }
1841
windows_claim_interface(struct libusb_device_handle * dev_handle,int iface)1842 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1843 {
1844 int r = LIBUSB_SUCCESS;
1845 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1846
1847 if (iface >= USB_MAXINTERFACES)
1848 return LIBUSB_ERROR_INVALID_PARAM;
1849
1850 safe_free(priv->usb_interface[iface].endpoint);
1851 priv->usb_interface[iface].nb_endpoints= 0;
1852
1853 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1854
1855 if (r == LIBUSB_SUCCESS) {
1856 r = windows_assign_endpoints(dev_handle, iface, 0);
1857 }
1858
1859 return r;
1860 }
1861
windows_set_interface_altsetting(struct libusb_device_handle * dev_handle,int iface,int altsetting)1862 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1863 {
1864 int r = LIBUSB_SUCCESS;
1865 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1866
1867 safe_free(priv->usb_interface[iface].endpoint);
1868 priv->usb_interface[iface].nb_endpoints= 0;
1869
1870 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1871
1872 if (r == LIBUSB_SUCCESS) {
1873 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1874 }
1875
1876 return r;
1877 }
1878
windows_release_interface(struct libusb_device_handle * dev_handle,int iface)1879 static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
1880 {
1881 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1882
1883 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1884 }
1885
windows_clear_halt(struct libusb_device_handle * dev_handle,unsigned char endpoint)1886 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1887 {
1888 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1889 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1890 }
1891
windows_reset_device(struct libusb_device_handle * dev_handle)1892 static int windows_reset_device(struct libusb_device_handle *dev_handle)
1893 {
1894 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1895 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1896 }
1897
1898 // The 3 functions below are unlikely to ever get supported on Windows
windows_kernel_driver_active(struct libusb_device_handle * dev_handle,int iface)1899 static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
1900 {
1901 return LIBUSB_ERROR_NOT_SUPPORTED;
1902 }
1903
windows_attach_kernel_driver(struct libusb_device_handle * dev_handle,int iface)1904 static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1905 {
1906 return LIBUSB_ERROR_NOT_SUPPORTED;
1907 }
1908
windows_detach_kernel_driver(struct libusb_device_handle * dev_handle,int iface)1909 static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
1910 {
1911 return LIBUSB_ERROR_NOT_SUPPORTED;
1912 }
1913
windows_destroy_device(struct libusb_device * dev)1914 static void windows_destroy_device(struct libusb_device *dev)
1915 {
1916 windows_device_priv_release(dev);
1917 }
1918
windows_clear_transfer_priv(struct usbi_transfer * itransfer)1919 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
1920 {
1921 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1922
1923 usbi_free_fd(&transfer_priv->pollable_fd);
1924 safe_free(transfer_priv->hid_buffer);
1925 // When auto claim is in use, attempt to release the auto-claimed interface
1926 auto_release(itransfer);
1927 }
1928
submit_bulk_transfer(struct usbi_transfer * itransfer)1929 static int submit_bulk_transfer(struct usbi_transfer *itransfer)
1930 {
1931 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1932 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1933 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1934 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1935 int r;
1936
1937 r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
1938 if (r != LIBUSB_SUCCESS) {
1939 return r;
1940 }
1941
1942 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1943 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1944
1945 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1946 return LIBUSB_SUCCESS;
1947 }
1948
submit_iso_transfer(struct usbi_transfer * itransfer)1949 static int submit_iso_transfer(struct usbi_transfer *itransfer)
1950 {
1951 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1952 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1953 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1954 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1955 int r;
1956
1957 r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
1958 if (r != LIBUSB_SUCCESS) {
1959 return r;
1960 }
1961
1962 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
1963 (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
1964
1965 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1966 return LIBUSB_SUCCESS;
1967 }
1968
submit_control_transfer(struct usbi_transfer * itransfer)1969 static int submit_control_transfer(struct usbi_transfer *itransfer)
1970 {
1971 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1972 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
1973 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
1974 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1975 int r;
1976
1977 r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
1978 if (r != LIBUSB_SUCCESS) {
1979 return r;
1980 }
1981
1982 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
1983
1984 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
1985 return LIBUSB_SUCCESS;
1986
1987 }
1988
windows_submit_transfer(struct usbi_transfer * itransfer)1989 static int windows_submit_transfer(struct usbi_transfer *itransfer)
1990 {
1991 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1992
1993 switch (transfer->type) {
1994 case LIBUSB_TRANSFER_TYPE_CONTROL:
1995 return submit_control_transfer(itransfer);
1996 case LIBUSB_TRANSFER_TYPE_BULK:
1997 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1998 if (IS_XFEROUT(transfer) &&
1999 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
2000 return LIBUSB_ERROR_NOT_SUPPORTED;
2001 return submit_bulk_transfer(itransfer);
2002 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2003 return submit_iso_transfer(itransfer);
2004 default:
2005 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2006 return LIBUSB_ERROR_INVALID_PARAM;
2007 }
2008 }
2009
windows_abort_control(struct usbi_transfer * itransfer)2010 static int windows_abort_control(struct usbi_transfer *itransfer)
2011 {
2012 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2013 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2014
2015 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2016 }
2017
windows_abort_transfers(struct usbi_transfer * itransfer)2018 static int windows_abort_transfers(struct usbi_transfer *itransfer)
2019 {
2020 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2021 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2022
2023 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2024 }
2025
windows_cancel_transfer(struct usbi_transfer * itransfer)2026 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2027 {
2028 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2029
2030 switch (transfer->type) {
2031 case LIBUSB_TRANSFER_TYPE_CONTROL:
2032 return windows_abort_control(itransfer);
2033 case LIBUSB_TRANSFER_TYPE_BULK:
2034 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2035 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2036 return windows_abort_transfers(itransfer);
2037 default:
2038 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2039 return LIBUSB_ERROR_INVALID_PARAM;
2040 }
2041 }
2042
windows_transfer_callback(struct usbi_transfer * itransfer,uint32_t io_result,uint32_t io_size)2043 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2044 {
2045 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2046 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2047 int status, istatus;
2048
2049 usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
2050
2051 switch(io_result) {
2052 case NO_ERROR:
2053 status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2054 break;
2055 case ERROR_GEN_FAILURE:
2056 usbi_dbg("detected endpoint stall");
2057 status = LIBUSB_TRANSFER_STALL;
2058 break;
2059 case ERROR_SEM_TIMEOUT:
2060 usbi_dbg("detected semaphore timeout");
2061 status = LIBUSB_TRANSFER_TIMED_OUT;
2062 break;
2063 case ERROR_OPERATION_ABORTED:
2064 istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2065 if (istatus != LIBUSB_TRANSFER_COMPLETED) {
2066 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
2067 }
2068 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2069 usbi_dbg("detected timeout");
2070 status = LIBUSB_TRANSFER_TIMED_OUT;
2071 } else {
2072 usbi_dbg("detected operation aborted");
2073 status = LIBUSB_TRANSFER_CANCELLED;
2074 }
2075 break;
2076 default:
2077 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(0));
2078 status = LIBUSB_TRANSFER_ERROR;
2079 break;
2080 }
2081 windows_clear_transfer_priv(itransfer); // Cancel polling
2082 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2083 }
2084
windows_handle_callback(struct usbi_transfer * itransfer,uint32_t io_result,uint32_t io_size)2085 static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2086 {
2087 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2088
2089 switch (transfer->type) {
2090 case LIBUSB_TRANSFER_TYPE_CONTROL:
2091 case LIBUSB_TRANSFER_TYPE_BULK:
2092 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2093 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2094 windows_transfer_callback (itransfer, io_result, io_size);
2095 break;
2096 default:
2097 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2098 }
2099 }
2100
windows_handle_events(struct libusb_context * ctx,struct pollfd * fds,POLL_NFDS_TYPE nfds,int num_ready)2101 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2102 {
2103 struct windows_transfer_priv* transfer_priv = NULL;
2104 POLL_NFDS_TYPE i = 0;
2105 bool found = false;
2106 struct usbi_transfer *transfer;
2107 DWORD io_size, io_result;
2108
2109 usbi_mutex_lock(&ctx->open_devs_lock);
2110 for (i = 0; i < nfds && num_ready > 0; i++) {
2111
2112 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2113
2114 if (!fds[i].revents) {
2115 continue;
2116 }
2117
2118 num_ready--;
2119
2120 // Because a Windows OVERLAPPED is used for poll emulation,
2121 // a pollable fd is created and stored with each transfer
2122 usbi_mutex_lock(&ctx->flying_transfers_lock);
2123 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2124 transfer_priv = usbi_transfer_get_os_priv(transfer);
2125 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2126 found = true;
2127 break;
2128 }
2129 }
2130 usbi_mutex_unlock(&ctx->flying_transfers_lock);
2131
2132 if (found) {
2133 // Handle async requests that completed synchronously first
2134 if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2135 io_result = NO_ERROR;
2136 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2137 // Regular async overlapped
2138 } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2139 transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2140 io_result = NO_ERROR;
2141 } else {
2142 io_result = GetLastError();
2143 }
2144 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2145 // let handle_callback free the event using the transfer wfd
2146 // If you don't use the transfer wfd, you run a risk of trying to free a
2147 // newly allocated wfd that took the place of the one from the transfer.
2148 windows_handle_callback(transfer, io_result, io_size);
2149 } else {
2150 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2151 usbi_mutex_unlock(&ctx->open_devs_lock);
2152 return LIBUSB_ERROR_NOT_FOUND;
2153 }
2154 }
2155
2156 usbi_mutex_unlock(&ctx->open_devs_lock);
2157 return LIBUSB_SUCCESS;
2158 }
2159
2160 /*
2161 * Monotonic and real time functions
2162 */
windows_clock_gettime_threaded(void * param)2163 unsigned __stdcall windows_clock_gettime_threaded(void* param)
2164 {
2165 LARGE_INTEGER hires_counter, li_frequency;
2166 LONG nb_responses;
2167 int timer_index;
2168
2169 // Init - find out if we have access to a monotonic (hires) timer
2170 if (!QueryPerformanceFrequency(&li_frequency)) {
2171 usbi_dbg("no hires timer available on this platform");
2172 hires_frequency = 0;
2173 hires_ticks_to_ps = UINT64_C(0);
2174 } else {
2175 hires_frequency = li_frequency.QuadPart;
2176 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
2177 // to picoseconds to compute the tv_nsecs part in clock_gettime
2178 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
2179 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
2180 }
2181
2182 // Signal windows_init() that we're ready to service requests
2183 if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
2184 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2185 }
2186
2187 // Main loop - wait for requests
2188 while (1) {
2189 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
2190 if ( (timer_index != 0) && (timer_index != 1) ) {
2191 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
2192 continue;
2193 }
2194 if (request_count[timer_index] == 0) {
2195 // Request already handled
2196 ResetEvent(timer_request[timer_index]);
2197 // There's still a possiblity that a thread sends a request between the
2198 // time we test request_count[] == 0 and we reset the event, in which case
2199 // the request would be ignored. The simple solution to that is to test
2200 // request_count again and process requests if non zero.
2201 if (request_count[timer_index] == 0)
2202 continue;
2203 }
2204 switch (timer_index) {
2205 case 0:
2206 WaitForSingleObject(timer_mutex, INFINITE);
2207 // Requests to this thread are for hires always
2208 if (QueryPerformanceCounter(&hires_counter) != 0) {
2209 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2210 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
2211 } else {
2212 // Fallback to real-time if we can't get monotonic value
2213 // Note that real-time clock does not wait on the mutex or this thread.
2214 windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
2215 }
2216 ReleaseMutex(timer_mutex);
2217
2218 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
2219 if ( (nb_responses)
2220 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
2221 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
2222 }
2223 continue;
2224 case 1: // time to quit
2225 usbi_dbg("timer thread quitting");
2226 return 0;
2227 }
2228 }
2229 }
2230
windows_clock_gettime(int clk_id,struct timespec * tp)2231 static int windows_clock_gettime(int clk_id, struct timespec *tp)
2232 {
2233 FILETIME filetime;
2234 ULARGE_INTEGER rtime;
2235 DWORD r;
2236 switch(clk_id) {
2237 case USBI_CLOCK_MONOTONIC:
2238 if (hires_frequency != 0) {
2239 while (1) {
2240 InterlockedIncrement((LONG*)&request_count[0]);
2241 SetEvent(timer_request[0]);
2242 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
2243 switch(r) {
2244 case WAIT_OBJECT_0:
2245 WaitForSingleObject(timer_mutex, INFINITE);
2246 *tp = timer_tp;
2247 ReleaseMutex(timer_mutex);
2248 return LIBUSB_SUCCESS;
2249 case WAIT_TIMEOUT:
2250 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2251 break; // Retry until successful
2252 default:
2253 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
2254 return LIBUSB_ERROR_OTHER;
2255 }
2256 }
2257 }
2258 // Fall through and return real-time if monotonic was not detected @ timer init
2259 case USBI_CLOCK_REALTIME:
2260 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2261 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2262 // Note however that our resolution is bounded by the Windows system time
2263 // functions and is at best of the order of 1 ms (or, usually, worse)
2264 GetSystemTimeAsFileTime(&filetime);
2265 rtime.LowPart = filetime.dwLowDateTime;
2266 rtime.HighPart = filetime.dwHighDateTime;
2267 rtime.QuadPart -= epoch_time;
2268 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2269 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2270 return LIBUSB_SUCCESS;
2271 default:
2272 return LIBUSB_ERROR_INVALID_PARAM;
2273 }
2274 }
2275
2276
2277 // NB: MSVC6 does not support named initializers.
2278 const struct usbi_os_backend windows_backend = {
2279 "Windows",
2280 USBI_CAP_HAS_HID_ACCESS,
2281 windows_init,
2282 windows_exit,
2283
2284 windows_get_device_list,
2285 NULL, /* hotplug_poll */
2286 windows_open,
2287 windows_close,
2288
2289 windows_get_device_descriptor,
2290 windows_get_active_config_descriptor,
2291 windows_get_config_descriptor,
2292 NULL, /* get_config_descriptor_by_value() */
2293
2294 windows_get_configuration,
2295 windows_set_configuration,
2296 windows_claim_interface,
2297 windows_release_interface,
2298
2299 windows_set_interface_altsetting,
2300 windows_clear_halt,
2301 windows_reset_device,
2302
2303 windows_kernel_driver_active,
2304 windows_detach_kernel_driver,
2305 windows_attach_kernel_driver,
2306
2307 windows_destroy_device,
2308
2309 windows_submit_transfer,
2310 windows_cancel_transfer,
2311 windows_clear_transfer_priv,
2312
2313 windows_handle_events,
2314
2315 windows_clock_gettime,
2316 #if defined(USBI_TIMERFD_AVAILABLE)
2317 NULL,
2318 #endif
2319 sizeof(struct windows_device_priv),
2320 sizeof(struct windows_device_handle_priv),
2321 sizeof(struct windows_transfer_priv),
2322 0,
2323 };
2324
2325
2326 /*
2327 * USB API backends
2328 */
unsupported_init(int sub_api,struct libusb_context * ctx)2329 static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2330 return LIBUSB_SUCCESS;
2331 }
unsupported_exit(int sub_api)2332 static int unsupported_exit(int sub_api) {
2333 return LIBUSB_SUCCESS;
2334 }
unsupported_open(int sub_api,struct libusb_device_handle * dev_handle)2335 static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2336 PRINT_UNSUPPORTED_API(open);
2337 }
unsupported_close(int sub_api,struct libusb_device_handle * dev_handle)2338 static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2339 usbi_dbg("unsupported API call for 'close'");
2340 }
unsupported_configure_endpoints(int sub_api,struct libusb_device_handle * dev_handle,int iface)2341 static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2342 PRINT_UNSUPPORTED_API(configure_endpoints);
2343 }
unsupported_claim_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2344 static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2345 PRINT_UNSUPPORTED_API(claim_interface);
2346 }
unsupported_set_interface_altsetting(int sub_api,struct libusb_device_handle * dev_handle,int iface,int altsetting)2347 static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2348 PRINT_UNSUPPORTED_API(set_interface_altsetting);
2349 }
unsupported_release_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2350 static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2351 PRINT_UNSUPPORTED_API(release_interface);
2352 }
unsupported_clear_halt(int sub_api,struct libusb_device_handle * dev_handle,unsigned char endpoint)2353 static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2354 PRINT_UNSUPPORTED_API(clear_halt);
2355 }
unsupported_reset_device(int sub_api,struct libusb_device_handle * dev_handle)2356 static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2357 PRINT_UNSUPPORTED_API(reset_device);
2358 }
unsupported_submit_bulk_transfer(int sub_api,struct usbi_transfer * itransfer)2359 static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2360 PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2361 }
unsupported_submit_iso_transfer(int sub_api,struct usbi_transfer * itransfer)2362 static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2363 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2364 }
unsupported_submit_control_transfer(int sub_api,struct usbi_transfer * itransfer)2365 static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2366 PRINT_UNSUPPORTED_API(submit_control_transfer);
2367 }
unsupported_abort_control(int sub_api,struct usbi_transfer * itransfer)2368 static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2369 PRINT_UNSUPPORTED_API(abort_control);
2370 }
unsupported_abort_transfers(int sub_api,struct usbi_transfer * itransfer)2371 static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2372 PRINT_UNSUPPORTED_API(abort_transfers);
2373 }
unsupported_copy_transfer_data(int sub_api,struct usbi_transfer * itransfer,uint32_t io_size)2374 static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2375 PRINT_UNSUPPORTED_API(copy_transfer_data);
2376 }
common_configure_endpoints(int sub_api,struct libusb_device_handle * dev_handle,int iface)2377 static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2378 return LIBUSB_SUCCESS;
2379 }
2380 // These names must be uppercase
2381 const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"};
2382 const char* composite_driver_names[] = {"USBCCGP"};
2383 const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2384 const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2385 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2386 {
2387 USB_API_UNSUPPORTED,
2388 "Unsupported API",
2389 NULL,
2390 0,
2391 unsupported_init,
2392 unsupported_exit,
2393 unsupported_open,
2394 unsupported_close,
2395 unsupported_configure_endpoints,
2396 unsupported_claim_interface,
2397 unsupported_set_interface_altsetting,
2398 unsupported_release_interface,
2399 unsupported_clear_halt,
2400 unsupported_reset_device,
2401 unsupported_submit_bulk_transfer,
2402 unsupported_submit_iso_transfer,
2403 unsupported_submit_control_transfer,
2404 unsupported_abort_control,
2405 unsupported_abort_transfers,
2406 unsupported_copy_transfer_data,
2407 }, {
2408 USB_API_HUB,
2409 "HUB API",
2410 hub_driver_names,
2411 ARRAYSIZE(hub_driver_names),
2412 unsupported_init,
2413 unsupported_exit,
2414 unsupported_open,
2415 unsupported_close,
2416 unsupported_configure_endpoints,
2417 unsupported_claim_interface,
2418 unsupported_set_interface_altsetting,
2419 unsupported_release_interface,
2420 unsupported_clear_halt,
2421 unsupported_reset_device,
2422 unsupported_submit_bulk_transfer,
2423 unsupported_submit_iso_transfer,
2424 unsupported_submit_control_transfer,
2425 unsupported_abort_control,
2426 unsupported_abort_transfers,
2427 unsupported_copy_transfer_data,
2428 }, {
2429 USB_API_COMPOSITE,
2430 "Composite API",
2431 composite_driver_names,
2432 ARRAYSIZE(composite_driver_names),
2433 composite_init,
2434 composite_exit,
2435 composite_open,
2436 composite_close,
2437 common_configure_endpoints,
2438 composite_claim_interface,
2439 composite_set_interface_altsetting,
2440 composite_release_interface,
2441 composite_clear_halt,
2442 composite_reset_device,
2443 composite_submit_bulk_transfer,
2444 composite_submit_iso_transfer,
2445 composite_submit_control_transfer,
2446 composite_abort_control,
2447 composite_abort_transfers,
2448 composite_copy_transfer_data,
2449 }, {
2450 USB_API_WINUSBX,
2451 "WinUSB-like APIs",
2452 winusbx_driver_names,
2453 ARRAYSIZE(winusbx_driver_names),
2454 winusbx_init,
2455 winusbx_exit,
2456 winusbx_open,
2457 winusbx_close,
2458 winusbx_configure_endpoints,
2459 winusbx_claim_interface,
2460 winusbx_set_interface_altsetting,
2461 winusbx_release_interface,
2462 winusbx_clear_halt,
2463 winusbx_reset_device,
2464 winusbx_submit_bulk_transfer,
2465 unsupported_submit_iso_transfer,
2466 winusbx_submit_control_transfer,
2467 winusbx_abort_control,
2468 winusbx_abort_transfers,
2469 winusbx_copy_transfer_data,
2470 }, {
2471 USB_API_HID,
2472 "HID API",
2473 hid_driver_names,
2474 ARRAYSIZE(hid_driver_names),
2475 hid_init,
2476 hid_exit,
2477 hid_open,
2478 hid_close,
2479 common_configure_endpoints,
2480 hid_claim_interface,
2481 hid_set_interface_altsetting,
2482 hid_release_interface,
2483 hid_clear_halt,
2484 hid_reset_device,
2485 hid_submit_bulk_transfer,
2486 unsupported_submit_iso_transfer,
2487 hid_submit_control_transfer,
2488 hid_abort_transfers,
2489 hid_abort_transfers,
2490 hid_copy_transfer_data,
2491 },
2492 };
2493
2494
2495 /*
2496 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2497 */
2498 #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2499 else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2500
winusbx_init(int sub_api,struct libusb_context * ctx)2501 static int winusbx_init(int sub_api, struct libusb_context *ctx)
2502 {
2503 HMODULE h = NULL;
2504 bool native_winusb = false;
2505 int i;
2506 KLIB_VERSION LibK_Version;
2507 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2508 LibK_GetVersion_t pLibK_GetVersion = NULL;
2509
2510 h = GetModuleHandleA("libusbK");
2511 if (h == NULL) {
2512 h = LoadLibraryA("libusbK");
2513 }
2514 if (h == NULL) {
2515 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2516 h = GetModuleHandleA("WinUSB");
2517 if (h == NULL) {
2518 h = LoadLibraryA("WinUSB");
2519 } if (h == NULL) {
2520 usbi_warn(ctx, "WinUSB DLL is not available either,\n"
2521 "you will not be able to access devices outside of enumeration");
2522 return LIBUSB_ERROR_NOT_FOUND;
2523 }
2524 } else {
2525 usbi_dbg("using libusbK DLL for universal access");
2526 pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2527 if (pLibK_GetVersion != NULL) {
2528 pLibK_GetVersion(&LibK_Version);
2529 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2530 LibK_Version.Micro, LibK_Version.Nano);
2531 }
2532 pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2533 if (pLibK_GetProcAddress == NULL) {
2534 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2535 return LIBUSB_ERROR_NOT_FOUND;
2536 }
2537 }
2538 native_winusb = (pLibK_GetProcAddress == NULL);
2539 for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2540 WinUSBX_Set(AbortPipe);
2541 WinUSBX_Set(ControlTransfer);
2542 WinUSBX_Set(FlushPipe);
2543 WinUSBX_Set(Free);
2544 WinUSBX_Set(GetAssociatedInterface);
2545 WinUSBX_Set(GetCurrentAlternateSetting);
2546 WinUSBX_Set(GetDescriptor);
2547 WinUSBX_Set(GetOverlappedResult);
2548 WinUSBX_Set(GetPipePolicy);
2549 WinUSBX_Set(GetPowerPolicy);
2550 WinUSBX_Set(Initialize);
2551 WinUSBX_Set(QueryDeviceInformation);
2552 WinUSBX_Set(QueryInterfaceSettings);
2553 WinUSBX_Set(QueryPipe);
2554 WinUSBX_Set(ReadPipe);
2555 WinUSBX_Set(ResetPipe);
2556 WinUSBX_Set(SetCurrentAlternateSetting);
2557 WinUSBX_Set(SetPipePolicy);
2558 WinUSBX_Set(SetPowerPolicy);
2559 WinUSBX_Set(WritePipe);
2560 if (!native_winusb) {
2561 WinUSBX_Set(ResetDevice);
2562 }
2563 if (WinUSBX[i].Initialize != NULL) {
2564 WinUSBX[i].initialized = true;
2565 usbi_dbg("initalized sub API %s", sub_api_name[i]);
2566 } else {
2567 usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2568 WinUSBX[i].initialized = false;
2569 }
2570 }
2571 return LIBUSB_SUCCESS;
2572 }
2573
winusbx_exit(int sub_api)2574 static int winusbx_exit(int sub_api)
2575 {
2576 return LIBUSB_SUCCESS;
2577 }
2578
2579 // NB: open and close must ensure that they only handle interface of
2580 // the right API type, as these functions can be called wholesale from
2581 // composite_open(), with interfaces belonging to different APIs
winusbx_open(int sub_api,struct libusb_device_handle * dev_handle)2582 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2583 {
2584 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2585 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2586 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2587
2588 HANDLE file_handle;
2589 int i;
2590
2591 CHECK_WINUSBX_AVAILABLE(sub_api);
2592
2593 // WinUSB requires a seperate handle for each interface
2594 for (i = 0; i < USB_MAXINTERFACES; i++) {
2595 if ( (priv->usb_interface[i].path != NULL)
2596 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2597 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2598 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2599 if (file_handle == INVALID_HANDLE_VALUE) {
2600 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2601 switch(GetLastError()) {
2602 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2603 return LIBUSB_ERROR_NO_DEVICE;
2604 case ERROR_ACCESS_DENIED:
2605 return LIBUSB_ERROR_ACCESS;
2606 default:
2607 return LIBUSB_ERROR_IO;
2608 }
2609 }
2610 handle_priv->interface_handle[i].dev_handle = file_handle;
2611 }
2612 }
2613
2614 return LIBUSB_SUCCESS;
2615 }
2616
winusbx_close(int sub_api,struct libusb_device_handle * dev_handle)2617 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2618 {
2619 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2620 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2621 HANDLE file_handle;
2622 int i;
2623
2624 if (sub_api == SUB_API_NOTSET)
2625 sub_api = priv->sub_api;
2626 if (!WinUSBX[sub_api].initialized)
2627 return;
2628
2629 for (i = 0; i < USB_MAXINTERFACES; i++) {
2630 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2631 file_handle = handle_priv->interface_handle[i].dev_handle;
2632 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
2633 CloseHandle(file_handle);
2634 }
2635 }
2636 }
2637 }
2638
winusbx_configure_endpoints(int sub_api,struct libusb_device_handle * dev_handle,int iface)2639 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2640 {
2641 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2642 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2643 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2644 UCHAR policy;
2645 ULONG timeout = 0;
2646 uint8_t endpoint_address;
2647 int i;
2648
2649 CHECK_WINUSBX_AVAILABLE(sub_api);
2650
2651 // With handle and enpoints set (in parent), we can setup the default pipe properties
2652 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2653 for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2654 endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2655 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2656 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2657 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2658 }
2659 if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2660 continue; // Other policies don't apply to control endpoint or libusb0
2661 }
2662 policy = false;
2663 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2664 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2665 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2666 }
2667 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2668 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2669 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2670 }
2671 policy = true;
2672 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2673 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2674 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2675 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2676 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2677 }
2678 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2679 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2680 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2681 }
2682 }
2683
2684 return LIBUSB_SUCCESS;
2685 }
2686
winusbx_claim_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2687 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2688 {
2689 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2690 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2691 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2692 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2693 HANDLE file_handle, winusb_handle;
2694 DWORD err;
2695 int i;
2696 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2697 HDEVINFO dev_info = INVALID_HANDLE_VALUE;
2698 SP_DEVINFO_DATA dev_info_data;
2699 char* dev_path_no_guid = NULL;
2700 char filter_path[] = "\\\\.\\libusb0-0000";
2701 bool found_filter = false;
2702
2703 CHECK_WINUSBX_AVAILABLE(sub_api);
2704
2705 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2706 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2707 if ((is_using_usbccgp) || (iface == 0)) {
2708 // composite device (independent interfaces) or interface 0
2709 file_handle = handle_priv->interface_handle[iface].dev_handle;
2710 if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2711 return LIBUSB_ERROR_NOT_FOUND;
2712 }
2713
2714 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2715 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2716 err = GetLastError();
2717 switch(err) {
2718 case ERROR_BAD_COMMAND:
2719 // The device was disconnected
2720 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2721 return LIBUSB_ERROR_NO_DEVICE;
2722 default:
2723 // it may be that we're using the libusb0 filter driver.
2724 // TODO: can we move this whole business into the K/0 DLL?
2725 for (i = 0; ; i++) {
2726 safe_free(dev_interface_details);
2727 safe_free(dev_path_no_guid);
2728 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2729 if ((found_filter) || (dev_interface_details == NULL)) {
2730 break;
2731 }
2732 // ignore GUID part
2733 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2734 if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2735 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2736 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2737 if (file_handle == INVALID_HANDLE_VALUE) {
2738 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2739 } else {
2740 WinUSBX[sub_api].Free(winusb_handle);
2741 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2742 continue;
2743 }
2744 found_filter = true;
2745 break;
2746 }
2747 }
2748 }
2749 if (!found_filter) {
2750 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2751 return LIBUSB_ERROR_ACCESS;
2752 }
2753 }
2754 }
2755 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2756 } else {
2757 // For all other interfaces, use GetAssociatedInterface()
2758 winusb_handle = handle_priv->interface_handle[0].api_handle;
2759 // It is a requirement for multiple interface devices on Windows that, to you
2760 // must first claim the first interface before you claim the others
2761 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2762 file_handle = handle_priv->interface_handle[0].dev_handle;
2763 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2764 handle_priv->interface_handle[0].api_handle = winusb_handle;
2765 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2766 } else {
2767 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2768 return LIBUSB_ERROR_ACCESS;
2769 }
2770 }
2771 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2772 &handle_priv->interface_handle[iface].api_handle)) {
2773 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2774 switch(GetLastError()) {
2775 case ERROR_NO_MORE_ITEMS: // invalid iface
2776 return LIBUSB_ERROR_NOT_FOUND;
2777 case ERROR_BAD_COMMAND: // The device was disconnected
2778 return LIBUSB_ERROR_NO_DEVICE;
2779 case ERROR_ALREADY_EXISTS: // already claimed
2780 return LIBUSB_ERROR_BUSY;
2781 default:
2782 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2783 return LIBUSB_ERROR_ACCESS;
2784 }
2785 }
2786 }
2787 usbi_dbg("claimed interface %d", iface);
2788 handle_priv->active_interface = iface;
2789
2790 return LIBUSB_SUCCESS;
2791 }
2792
winusbx_release_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)2793 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2794 {
2795 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2796 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2797 HANDLE winusb_handle;
2798
2799 CHECK_WINUSBX_AVAILABLE(sub_api);
2800
2801 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2802 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2803 return LIBUSB_ERROR_NOT_FOUND;
2804 }
2805
2806 WinUSBX[sub_api].Free(winusb_handle);
2807 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2808
2809 return LIBUSB_SUCCESS;
2810 }
2811
2812 /*
2813 * Return the first valid interface (of the same API type), for control transfers
2814 */
get_valid_interface(struct libusb_device_handle * dev_handle,int api_id)2815 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2816 {
2817 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2818 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2819 int i;
2820
2821 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2822 usbi_dbg("unsupported API ID");
2823 return -1;
2824 }
2825
2826 for (i=0; i<USB_MAXINTERFACES; i++) {
2827 if ( (handle_priv->interface_handle[i].dev_handle != 0)
2828 && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
2829 && (handle_priv->interface_handle[i].api_handle != 0)
2830 && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
2831 && (priv->usb_interface[i].apib->id == api_id) ) {
2832 return i;
2833 }
2834 }
2835 return -1;
2836 }
2837
2838 /*
2839 * Lookup interface by endpoint address. -1 if not found
2840 */
interface_by_endpoint(struct windows_device_priv * priv,struct windows_device_handle_priv * handle_priv,uint8_t endpoint_address)2841 static int interface_by_endpoint(struct windows_device_priv *priv,
2842 struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
2843 {
2844 int i, j;
2845 for (i=0; i<USB_MAXINTERFACES; i++) {
2846 if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
2847 continue;
2848 if (handle_priv->interface_handle[i].api_handle == 0)
2849 continue;
2850 if (priv->usb_interface[i].endpoint == NULL)
2851 continue;
2852 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
2853 if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
2854 return i;
2855 }
2856 }
2857 }
2858 return -1;
2859 }
2860
winusbx_submit_control_transfer(int sub_api,struct usbi_transfer * itransfer)2861 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2862 {
2863 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2864 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2865 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2866 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2867 struct windows_device_handle_priv *handle_priv = _device_handle_priv(
2868 transfer->dev_handle);
2869 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
2870 ULONG size;
2871 HANDLE winusb_handle;
2872 int current_interface;
2873 struct winfd wfd;
2874
2875 CHECK_WINUSBX_AVAILABLE(sub_api);
2876
2877 transfer_priv->pollable_fd = INVALID_WINFD;
2878 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2879
2880 if (size > MAX_CTRL_BUFFER_LENGTH)
2881 return LIBUSB_ERROR_INVALID_PARAM;
2882
2883 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2884 if (current_interface < 0) {
2885 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
2886 return LIBUSB_ERROR_NOT_FOUND;
2887 }
2888 }
2889
2890 usbi_dbg("will use interface %d", current_interface);
2891 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2892
2893 wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
2894 // Always use the handle returned from usbi_create_fd (wfd.handle)
2895 if (wfd.fd < 0) {
2896 return LIBUSB_ERROR_NO_MEM;
2897 }
2898
2899 // Sending of set configuration control requests from WinUSB creates issues
2900 if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
2901 && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
2902 if (setup->value != priv->active_config) {
2903 usbi_warn(ctx, "cannot set configuration other than the default one");
2904 usbi_free_fd(&wfd);
2905 return LIBUSB_ERROR_INVALID_PARAM;
2906 }
2907 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2908 wfd.overlapped->InternalHigh = 0;
2909 } else {
2910 if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
2911 if(GetLastError() != ERROR_IO_PENDING) {
2912 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2913 usbi_free_fd(&wfd);
2914 return LIBUSB_ERROR_IO;
2915 }
2916 } else {
2917 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
2918 wfd.overlapped->InternalHigh = (DWORD)size;
2919 }
2920 }
2921
2922 // Use priv_transfer to store data needed for async polling
2923 transfer_priv->pollable_fd = wfd;
2924 transfer_priv->interface_number = (uint8_t)current_interface;
2925
2926 return LIBUSB_SUCCESS;
2927 }
2928
winusbx_set_interface_altsetting(int sub_api,struct libusb_device_handle * dev_handle,int iface,int altsetting)2929 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2930 {
2931 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2932 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2933 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2934 HANDLE winusb_handle;
2935
2936 CHECK_WINUSBX_AVAILABLE(sub_api);
2937
2938 if (altsetting > 255) {
2939 return LIBUSB_ERROR_INVALID_PARAM;
2940 }
2941
2942 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2943 if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2944 usbi_err(ctx, "interface must be claimed first");
2945 return LIBUSB_ERROR_NOT_FOUND;
2946 }
2947
2948 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2949 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2950 return LIBUSB_ERROR_IO;
2951 }
2952
2953 return LIBUSB_SUCCESS;
2954 }
2955
winusbx_submit_bulk_transfer(int sub_api,struct usbi_transfer * itransfer)2956 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2957 {
2958 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2959 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2960 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2961 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2962 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2963 HANDLE winusb_handle;
2964 bool ret;
2965 int current_interface;
2966 struct winfd wfd;
2967
2968 CHECK_WINUSBX_AVAILABLE(sub_api);
2969
2970 transfer_priv->pollable_fd = INVALID_WINFD;
2971
2972 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2973 if (current_interface < 0) {
2974 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2975 return LIBUSB_ERROR_NOT_FOUND;
2976 }
2977
2978 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2979
2980 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2981
2982 wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
2983 // Always use the handle returned from usbi_create_fd (wfd.handle)
2984 if (wfd.fd < 0) {
2985 return LIBUSB_ERROR_NO_MEM;
2986 }
2987
2988 if (IS_XFERIN(transfer)) {
2989 usbi_dbg("reading %d bytes", transfer->length);
2990 ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2991 } else {
2992 usbi_dbg("writing %d bytes", transfer->length);
2993 ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
2994 }
2995 if (!ret) {
2996 if(GetLastError() != ERROR_IO_PENDING) {
2997 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2998 usbi_free_fd(&wfd);
2999 return LIBUSB_ERROR_IO;
3000 }
3001 } else {
3002 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3003 wfd.overlapped->InternalHigh = (DWORD)transfer->length;
3004 }
3005
3006 transfer_priv->pollable_fd = wfd;
3007 transfer_priv->interface_number = (uint8_t)current_interface;
3008
3009 return LIBUSB_SUCCESS;
3010 }
3011
winusbx_clear_halt(int sub_api,struct libusb_device_handle * dev_handle,unsigned char endpoint)3012 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3013 {
3014 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3015 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3016 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3017 HANDLE winusb_handle;
3018 int current_interface;
3019
3020 CHECK_WINUSBX_AVAILABLE(sub_api);
3021
3022 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3023 if (current_interface < 0) {
3024 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3025 return LIBUSB_ERROR_NOT_FOUND;
3026 }
3027
3028 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3029 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3030
3031 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3032 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3033 return LIBUSB_ERROR_NO_DEVICE;
3034 }
3035
3036 return LIBUSB_SUCCESS;
3037 }
3038
3039 /*
3040 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3041 * through testing as well):
3042 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3043 * the control transfer using CancelIo"
3044 */
winusbx_abort_control(int sub_api,struct usbi_transfer * itransfer)3045 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3046 {
3047 // Cancelling of the I/O is done in the parent
3048 return LIBUSB_SUCCESS;
3049 }
3050
winusbx_abort_transfers(int sub_api,struct usbi_transfer * itransfer)3051 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3052 {
3053 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3054 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3055 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3056 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3057 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3058 HANDLE winusb_handle;
3059 int current_interface;
3060
3061 CHECK_WINUSBX_AVAILABLE(sub_api);
3062
3063 current_interface = transfer_priv->interface_number;
3064 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3065 usbi_err(ctx, "program assertion failed: invalid interface_number");
3066 return LIBUSB_ERROR_NOT_FOUND;
3067 }
3068 usbi_dbg("will use interface %d", current_interface);
3069
3070 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3071
3072 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3073 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3074 return LIBUSB_ERROR_NO_DEVICE;
3075 }
3076
3077 return LIBUSB_SUCCESS;
3078 }
3079
3080 /*
3081 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3082 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3083 * "WinUSB does not support host-initiated reset port and cycle port operations" and
3084 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3085 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3086 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3087 */
3088 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
winusbx_reset_device(int sub_api,struct libusb_device_handle * dev_handle)3089 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3090 {
3091 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3092 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3093 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3094 struct winfd wfd;
3095 HANDLE winusb_handle;
3096 int i, j;
3097
3098 CHECK_WINUSBX_AVAILABLE(sub_api);
3099
3100 // Reset any available pipe (except control)
3101 for (i=0; i<USB_MAXINTERFACES; i++) {
3102 winusb_handle = handle_priv->interface_handle[i].api_handle;
3103 for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3104 {
3105 // Cancel any pollable I/O
3106 usbi_remove_pollfd(ctx, wfd.fd);
3107 usbi_free_fd(&wfd);
3108 wfd = handle_to_winfd(winusb_handle);
3109 }
3110
3111 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3112 for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3113 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3114 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3115 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3116 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3117 }
3118 // FlushPipe seems to fail on OUT pipes
3119 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3120 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3121 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3122 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3123 }
3124 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3125 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3126 priv->usb_interface[i].endpoint[j], windows_error_str(0));
3127 }
3128 }
3129 }
3130 }
3131
3132 // libusbK & libusb0 have the ability to issue an actual device reset
3133 if (WinUSBX[sub_api].ResetDevice != NULL) {
3134 winusb_handle = handle_priv->interface_handle[0].api_handle;
3135 if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3136 WinUSBX[sub_api].ResetDevice(winusb_handle);
3137 }
3138 }
3139 return LIBUSB_SUCCESS;
3140 }
3141
winusbx_copy_transfer_data(int sub_api,struct usbi_transfer * itransfer,uint32_t io_size)3142 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3143 {
3144 itransfer->transferred += io_size;
3145 return LIBUSB_TRANSFER_COMPLETED;
3146 }
3147
3148 /*
3149 * Internal HID Support functions (from libusb-win32)
3150 * Note that functions that complete data transfer synchronously must return
3151 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3152 */
3153 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3154 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3155
_hid_wcslen(WCHAR * str)3156 static int _hid_wcslen(WCHAR *str)
3157 {
3158 int i = 0;
3159 while (str[i] && (str[i] != 0x409)) {
3160 i++;
3161 }
3162 return i;
3163 }
3164
_hid_get_device_descriptor(struct hid_device_priv * dev,void * data,size_t * size)3165 static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3166 {
3167 struct libusb_device_descriptor d;
3168
3169 d.bLength = LIBUSB_DT_DEVICE_SIZE;
3170 d.bDescriptorType = LIBUSB_DT_DEVICE;
3171 d.bcdUSB = 0x0200; /* 2.00 */
3172 d.bDeviceClass = 0;
3173 d.bDeviceSubClass = 0;
3174 d.bDeviceProtocol = 0;
3175 d.bMaxPacketSize0 = 64; /* fix this! */
3176 d.idVendor = (uint16_t)dev->vid;
3177 d.idProduct = (uint16_t)dev->pid;
3178 d.bcdDevice = 0x0100;
3179 d.iManufacturer = dev->string_index[0];
3180 d.iProduct = dev->string_index[1];
3181 d.iSerialNumber = dev->string_index[2];
3182 d.bNumConfigurations = 1;
3183
3184 if (*size > LIBUSB_DT_DEVICE_SIZE)
3185 *size = LIBUSB_DT_DEVICE_SIZE;
3186 memcpy(data, &d, *size);
3187 return LIBUSB_COMPLETED;
3188 }
3189
_hid_get_config_descriptor(struct hid_device_priv * dev,void * data,size_t * size)3190 static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3191 {
3192 char num_endpoints = 0;
3193 size_t config_total_len = 0;
3194 char tmp[HID_MAX_CONFIG_DESC_SIZE];
3195 struct libusb_config_descriptor *cd;
3196 struct libusb_interface_descriptor *id;
3197 struct libusb_hid_descriptor *hd;
3198 struct libusb_endpoint_descriptor *ed;
3199 size_t tmp_size;
3200
3201 if (dev->input_report_size)
3202 num_endpoints++;
3203 if (dev->output_report_size)
3204 num_endpoints++;
3205
3206 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3207 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3208
3209
3210 cd = (struct libusb_config_descriptor *)tmp;
3211 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3212 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3213 + LIBUSB_DT_INTERFACE_SIZE);
3214 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3215 + LIBUSB_DT_INTERFACE_SIZE
3216 + LIBUSB_DT_HID_SIZE);
3217
3218 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3219 cd->bDescriptorType = LIBUSB_DT_CONFIG;
3220 cd->wTotalLength = (uint16_t) config_total_len;
3221 cd->bNumInterfaces = 1;
3222 cd->bConfigurationValue = 1;
3223 cd->iConfiguration = 0;
3224 cd->bmAttributes = 1 << 7; /* bus powered */
3225 cd->MaxPower = 50;
3226
3227 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3228 id->bDescriptorType = LIBUSB_DT_INTERFACE;
3229 id->bInterfaceNumber = 0;
3230 id->bAlternateSetting = 0;
3231 id->bNumEndpoints = num_endpoints;
3232 id->bInterfaceClass = 3;
3233 id->bInterfaceSubClass = 0;
3234 id->bInterfaceProtocol = 0;
3235 id->iInterface = 0;
3236
3237 tmp_size = LIBUSB_DT_HID_SIZE;
3238 _hid_get_hid_descriptor(dev, hd, &tmp_size);
3239
3240 if (dev->input_report_size) {
3241 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3242 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3243 ed->bEndpointAddress = HID_IN_EP;
3244 ed->bmAttributes = 3;
3245 ed->wMaxPacketSize = dev->input_report_size - 1;
3246 ed->bInterval = 10;
3247 ed = (struct libusb_endpoint_descriptor *)((char*)ed + LIBUSB_DT_ENDPOINT_SIZE);
3248 }
3249
3250 if (dev->output_report_size) {
3251 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3252 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3253 ed->bEndpointAddress = HID_OUT_EP;
3254 ed->bmAttributes = 3;
3255 ed->wMaxPacketSize = dev->output_report_size - 1;
3256 ed->bInterval = 10;
3257 }
3258
3259 if (*size > config_total_len)
3260 *size = config_total_len;
3261 memcpy(data, tmp, *size);
3262 return LIBUSB_COMPLETED;
3263 }
3264
_hid_get_string_descriptor(struct hid_device_priv * dev,int _index,void * data,size_t * size)3265 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3266 void *data, size_t *size)
3267 {
3268 void *tmp = NULL;
3269 size_t tmp_size = 0;
3270 int i;
3271
3272 /* language ID, EN-US */
3273 char string_langid[] = {
3274 0x09,
3275 0x04
3276 };
3277
3278 if ((*size < 2) || (*size > 255)) {
3279 return LIBUSB_ERROR_OVERFLOW;
3280 }
3281
3282 if (_index == 0) {
3283 tmp = string_langid;
3284 tmp_size = sizeof(string_langid)+2;
3285 } else {
3286 for (i=0; i<3; i++) {
3287 if (_index == (dev->string_index[i])) {
3288 tmp = dev->string[i];
3289 tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3290 break;
3291 }
3292 }
3293 if (i == 3) { // not found
3294 return LIBUSB_ERROR_INVALID_PARAM;
3295 }
3296 }
3297
3298 if(!tmp_size) {
3299 return LIBUSB_ERROR_INVALID_PARAM;
3300 }
3301
3302 if (tmp_size < *size) {
3303 *size = tmp_size;
3304 }
3305 // 2 byte header
3306 ((uint8_t*)data)[0] = (uint8_t)*size;
3307 ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3308 memcpy((uint8_t*)data+2, tmp, *size-2);
3309 return LIBUSB_COMPLETED;
3310 }
3311
_hid_get_hid_descriptor(struct hid_device_priv * dev,void * data,size_t * size)3312 static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3313 {
3314 struct libusb_hid_descriptor d;
3315 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3316 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3317
3318 _hid_get_report_descriptor(dev, tmp, &report_len);
3319
3320 d.bLength = LIBUSB_DT_HID_SIZE;
3321 d.bDescriptorType = LIBUSB_DT_HID;
3322 d.bcdHID = 0x0110; /* 1.10 */
3323 d.bCountryCode = 0;
3324 d.bNumDescriptors = 1;
3325 d.bClassDescriptorType = LIBUSB_DT_REPORT;
3326 d.wClassDescriptorLength = (uint16_t)report_len;
3327
3328 if (*size > LIBUSB_DT_HID_SIZE)
3329 *size = LIBUSB_DT_HID_SIZE;
3330 memcpy(data, &d, *size);
3331 return LIBUSB_COMPLETED;
3332 }
3333
_hid_get_report_descriptor(struct hid_device_priv * dev,void * data,size_t * size)3334 static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3335 {
3336 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3337 size_t i = 0;
3338
3339 /* usage page (0xFFA0 == vendor defined) */
3340 d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3341 /* usage (vendor defined) */
3342 d[i++] = 0x09; d[i++] = 0x01;
3343 /* start collection (application) */
3344 d[i++] = 0xA1; d[i++] = 0x01;
3345 /* input report */
3346 if (dev->input_report_size) {
3347 /* usage (vendor defined) */
3348 d[i++] = 0x09; d[i++] = 0x01;
3349 /* logical minimum (0) */
3350 d[i++] = 0x15; d[i++] = 0x00;
3351 /* logical maximum (255) */
3352 d[i++] = 0x25; d[i++] = 0xFF;
3353 /* report size (8 bits) */
3354 d[i++] = 0x75; d[i++] = 0x08;
3355 /* report count */
3356 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3357 /* input (data, variable, absolute) */
3358 d[i++] = 0x81; d[i++] = 0x00;
3359 }
3360 /* output report */
3361 if (dev->output_report_size) {
3362 /* usage (vendor defined) */
3363 d[i++] = 0x09; d[i++] = 0x02;
3364 /* logical minimum (0) */
3365 d[i++] = 0x15; d[i++] = 0x00;
3366 /* logical maximum (255) */
3367 d[i++] = 0x25; d[i++] = 0xFF;
3368 /* report size (8 bits) */
3369 d[i++] = 0x75; d[i++] = 0x08;
3370 /* report count */
3371 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3372 /* output (data, variable, absolute) */
3373 d[i++] = 0x91; d[i++] = 0x00;
3374 }
3375 /* feature report */
3376 if (dev->feature_report_size) {
3377 /* usage (vendor defined) */
3378 d[i++] = 0x09; d[i++] = 0x03;
3379 /* logical minimum (0) */
3380 d[i++] = 0x15; d[i++] = 0x00;
3381 /* logical maximum (255) */
3382 d[i++] = 0x25; d[i++] = 0xFF;
3383 /* report size (8 bits) */
3384 d[i++] = 0x75; d[i++] = 0x08;
3385 /* report count */
3386 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3387 /* feature (data, variable, absolute) */
3388 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3389 }
3390
3391 /* end collection */
3392 d[i++] = 0xC0;
3393
3394 if (*size > i)
3395 *size = i;
3396 memcpy(data, d, *size);
3397 return LIBUSB_COMPLETED;
3398 }
3399
_hid_get_descriptor(struct hid_device_priv * dev,HANDLE hid_handle,int recipient,int type,int _index,void * data,size_t * size)3400 static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3401 int type, int _index, void *data, size_t *size)
3402 {
3403 switch(type) {
3404 case LIBUSB_DT_DEVICE:
3405 usbi_dbg("LIBUSB_DT_DEVICE");
3406 return _hid_get_device_descriptor(dev, data, size);
3407 case LIBUSB_DT_CONFIG:
3408 usbi_dbg("LIBUSB_DT_CONFIG");
3409 if (!_index)
3410 return _hid_get_config_descriptor(dev, data, size);
3411 return LIBUSB_ERROR_INVALID_PARAM;
3412 case LIBUSB_DT_STRING:
3413 usbi_dbg("LIBUSB_DT_STRING");
3414 return _hid_get_string_descriptor(dev, _index, data, size);
3415 case LIBUSB_DT_HID:
3416 usbi_dbg("LIBUSB_DT_HID");
3417 if (!_index)
3418 return _hid_get_hid_descriptor(dev, data, size);
3419 return LIBUSB_ERROR_INVALID_PARAM;
3420 case LIBUSB_DT_REPORT:
3421 usbi_dbg("LIBUSB_DT_REPORT");
3422 if (!_index)
3423 return _hid_get_report_descriptor(dev, data, size);
3424 return LIBUSB_ERROR_INVALID_PARAM;
3425 case LIBUSB_DT_PHYSICAL:
3426 usbi_dbg("LIBUSB_DT_PHYSICAL");
3427 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3428 return LIBUSB_COMPLETED;
3429 return LIBUSB_ERROR_OTHER;
3430 }
3431 usbi_dbg("unsupported");
3432 return LIBUSB_ERROR_INVALID_PARAM;
3433 }
3434
_hid_get_report(struct hid_device_priv * dev,HANDLE hid_handle,int id,void * data,struct windows_transfer_priv * tp,size_t * size,OVERLAPPED * overlapped,int report_type)3435 static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3436 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3437 int report_type)
3438 {
3439 uint8_t *buf;
3440 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3441 int r = LIBUSB_SUCCESS;
3442
3443 if (tp->hid_buffer != NULL) {
3444 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3445 }
3446
3447 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3448 usbi_dbg("invalid size (%d)", *size);
3449 return LIBUSB_ERROR_INVALID_PARAM;
3450 }
3451
3452 switch (report_type) {
3453 case HID_REPORT_TYPE_INPUT:
3454 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3455 break;
3456 case HID_REPORT_TYPE_FEATURE:
3457 ioctl_code = IOCTL_HID_GET_FEATURE;
3458 break;
3459 default:
3460 usbi_dbg("unknown HID report type %d", report_type);
3461 return LIBUSB_ERROR_INVALID_PARAM;
3462 }
3463
3464 // Add a trailing byte to detect overflows
3465 buf = (uint8_t*)calloc(expected_size+1, 1);
3466 if (buf == NULL) {
3467 return LIBUSB_ERROR_NO_MEM;
3468 }
3469 buf[0] = (uint8_t)id; // Must be set always
3470 usbi_dbg("report ID: 0x%02X", buf[0]);
3471
3472 tp->hid_expected_size = expected_size;
3473 read_size = expected_size;
3474
3475 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3476 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3477 buf, expected_size+1, &read_size, overlapped)) {
3478 if (GetLastError() != ERROR_IO_PENDING) {
3479 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3480 safe_free(buf);
3481 return LIBUSB_ERROR_IO;
3482 }
3483 // Asynchronous wait
3484 tp->hid_buffer = buf;
3485 tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3486 return LIBUSB_SUCCESS;
3487 }
3488
3489 // Transfer completed synchronously => copy and discard extra buffer
3490 if (read_size == 0) {
3491 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3492 *size = 0;
3493 } else {
3494 if (buf[0] != id) {
3495 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3496 }
3497 if ((size_t)read_size > expected_size) {
3498 r = LIBUSB_ERROR_OVERFLOW;
3499 usbi_dbg("OVERFLOW!");
3500 } else {
3501 r = LIBUSB_COMPLETED;
3502 }
3503
3504 *size = MIN((size_t)read_size, *size);
3505 if (id == 0) {
3506 // Discard report ID
3507 memcpy(data, buf+1, *size);
3508 } else {
3509 memcpy(data, buf, *size);
3510 }
3511 }
3512 safe_free(buf);
3513 return r;
3514 }
3515
_hid_set_report(struct hid_device_priv * dev,HANDLE hid_handle,int id,void * data,struct windows_transfer_priv * tp,size_t * size,OVERLAPPED * overlapped,int report_type)3516 static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3517 struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3518 int report_type)
3519 {
3520 uint8_t *buf = NULL;
3521 DWORD ioctl_code, write_size= (DWORD)*size;
3522
3523 if (tp->hid_buffer != NULL) {
3524 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3525 }
3526
3527 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3528 usbi_dbg("invalid size (%d)", *size);
3529 return LIBUSB_ERROR_INVALID_PARAM;
3530 }
3531
3532 switch (report_type) {
3533 case HID_REPORT_TYPE_OUTPUT:
3534 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3535 break;
3536 case HID_REPORT_TYPE_FEATURE:
3537 ioctl_code = IOCTL_HID_SET_FEATURE;
3538 break;
3539 default:
3540 usbi_dbg("unknown HID report type %d", report_type);
3541 return LIBUSB_ERROR_INVALID_PARAM;
3542 }
3543
3544 usbi_dbg("report ID: 0x%02X", id);
3545 // When report IDs are not used (i.e. when id == 0), we must add
3546 // a null report ID. Otherwise, we just use original data buffer
3547 if (id == 0) {
3548 write_size++;
3549 }
3550 buf = (uint8_t*) malloc(write_size);
3551 if (buf == NULL) {
3552 return LIBUSB_ERROR_NO_MEM;
3553 }
3554 if (id == 0) {
3555 buf[0] = 0;
3556 memcpy(buf + 1, data, *size);
3557 } else {
3558 // This seems like a waste, but if we don't duplicate the
3559 // data, we'll get issues when freeing hid_buffer
3560 memcpy(buf, data, *size);
3561 if (buf[0] != id) {
3562 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3563 }
3564 }
3565
3566 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3567 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3568 buf, write_size, &write_size, overlapped)) {
3569 if (GetLastError() != ERROR_IO_PENDING) {
3570 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3571 safe_free(buf);
3572 return LIBUSB_ERROR_IO;
3573 }
3574 tp->hid_buffer = buf;
3575 tp->hid_dest = NULL;
3576 return LIBUSB_SUCCESS;
3577 }
3578
3579 // Transfer completed synchronously
3580 *size = write_size;
3581 if (write_size == 0) {
3582 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3583 }
3584 safe_free(buf);
3585 return LIBUSB_COMPLETED;
3586 }
3587
_hid_class_request(struct hid_device_priv * dev,HANDLE hid_handle,int request_type,int request,int value,int _index,void * data,struct windows_transfer_priv * tp,size_t * size,OVERLAPPED * overlapped)3588 static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3589 int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3590 size_t *size, OVERLAPPED* overlapped)
3591 {
3592 int report_type = (value >> 8) & 0xFF;
3593 int report_id = value & 0xFF;
3594
3595 if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3596 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3597 return LIBUSB_ERROR_INVALID_PARAM;
3598
3599 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3600 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3601
3602 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3603 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3604
3605 return LIBUSB_ERROR_INVALID_PARAM;
3606 }
3607
3608
3609 /*
3610 * HID API functions
3611 */
hid_init(int sub_api,struct libusb_context * ctx)3612 static int hid_init(int sub_api, struct libusb_context *ctx)
3613 {
3614 DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3615 DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3616 DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3617 DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3618 DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3619 DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3620 DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3621 DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3622 DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3623 DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3624 DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3625 DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3626 DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3627 DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3628 DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3629 DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3630
3631 api_hid_available = true;
3632 return LIBUSB_SUCCESS;
3633 }
3634
hid_exit(int sub_api)3635 static int hid_exit(int sub_api)
3636 {
3637 return LIBUSB_SUCCESS;
3638 }
3639
3640 // NB: open and close must ensure that they only handle interface of
3641 // the right API type, as these functions can be called wholesale from
3642 // composite_open(), with interfaces belonging to different APIs
hid_open(int sub_api,struct libusb_device_handle * dev_handle)3643 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3644 {
3645 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3646 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3647 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3648
3649 HIDD_ATTRIBUTES hid_attributes;
3650 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3651 HIDP_CAPS capabilities;
3652 HIDP_VALUE_CAPS *value_caps;
3653
3654 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3655 int i, j;
3656 // report IDs handling
3657 ULONG size[3];
3658 const char* type[3] = {"input", "output", "feature"};
3659 int nb_ids[2]; // zero and nonzero report IDs
3660
3661 CHECK_HID_AVAILABLE;
3662 if (priv->hid == NULL) {
3663 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3664 return LIBUSB_ERROR_NOT_FOUND;
3665 }
3666
3667 for (i = 0; i < USB_MAXINTERFACES; i++) {
3668 if ( (priv->usb_interface[i].path != NULL)
3669 && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3670 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3671 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3672 /*
3673 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3674 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3675 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3676 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3677 * HidD_GetFeature (if the device supports Feature reports)."
3678 */
3679 if (hid_handle == INVALID_HANDLE_VALUE) {
3680 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3681 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3682 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3683 if (hid_handle == INVALID_HANDLE_VALUE) {
3684 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3685 switch(GetLastError()) {
3686 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3687 return LIBUSB_ERROR_NO_DEVICE;
3688 case ERROR_ACCESS_DENIED:
3689 return LIBUSB_ERROR_ACCESS;
3690 default:
3691 return LIBUSB_ERROR_IO;
3692 }
3693 }
3694 priv->usb_interface[i].restricted_functionality = true;
3695 }
3696 handle_priv->interface_handle[i].api_handle = hid_handle;
3697 }
3698 }
3699
3700 hid_attributes.Size = sizeof(hid_attributes);
3701 do {
3702 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3703 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3704 break;
3705 }
3706
3707 priv->hid->vid = hid_attributes.VendorID;
3708 priv->hid->pid = hid_attributes.ProductID;
3709
3710 // Set the maximum available input buffer size
3711 for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3712 usbi_dbg("set maximum input buffer size to %d", i/2);
3713
3714 // Get the maximum input and output report size
3715 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3716 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3717 break;
3718 }
3719 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3720 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3721 break;
3722 }
3723
3724 // Find out if interrupt will need report IDs
3725 size[0] = capabilities.NumberInputValueCaps;
3726 size[1] = capabilities.NumberOutputValueCaps;
3727 size[2] = capabilities.NumberFeatureValueCaps;
3728 for (j=HidP_Input; j<=HidP_Feature; j++) {
3729 usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3730 priv->hid->uses_report_ids[j] = false;
3731 if (size[j] > 0) {
3732 value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3733 if ( (value_caps != NULL)
3734 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3735 && (size[j] >= 1) ) {
3736 nb_ids[0] = 0;
3737 nb_ids[1] = 0;
3738 for (i=0; i<(int)size[j]; i++) {
3739 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3740 if (value_caps[i].ReportID != 0) {
3741 nb_ids[1]++;
3742 } else {
3743 nb_ids[0]++;
3744 }
3745 }
3746 if (nb_ids[1] != 0) {
3747 if (nb_ids[0] != 0) {
3748 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3749 type[j]);
3750 }
3751 priv->hid->uses_report_ids[j] = true;
3752 }
3753 } else {
3754 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3755 }
3756 safe_free(value_caps);
3757 }
3758 }
3759
3760 // Set the report sizes
3761 priv->hid->input_report_size = capabilities.InputReportByteLength;
3762 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3763 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3764
3765 // Fetch string descriptors
3766 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3767 if (priv->hid->string_index[0] != 0) {
3768 HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3769 sizeof(priv->hid->string[0]));
3770 } else {
3771 priv->hid->string[0][0] = 0;
3772 }
3773 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3774 if (priv->hid->string_index[1] != 0) {
3775 HidD_GetProductString(hid_handle, priv->hid->string[1],
3776 sizeof(priv->hid->string[1]));
3777 } else {
3778 priv->hid->string[1][0] = 0;
3779 }
3780 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3781 if (priv->hid->string_index[2] != 0) {
3782 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3783 sizeof(priv->hid->string[2]));
3784 } else {
3785 priv->hid->string[2][0] = 0;
3786 }
3787 } while(0);
3788
3789 if (preparsed_data) {
3790 HidD_FreePreparsedData(preparsed_data);
3791 }
3792
3793 return LIBUSB_SUCCESS;
3794 }
3795
hid_close(int sub_api,struct libusb_device_handle * dev_handle)3796 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3797 {
3798 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3799 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3800 HANDLE file_handle;
3801 int i;
3802
3803 if (!api_hid_available)
3804 return;
3805
3806 for (i = 0; i < USB_MAXINTERFACES; i++) {
3807 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3808 file_handle = handle_priv->interface_handle[i].api_handle;
3809 if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
3810 CloseHandle(file_handle);
3811 }
3812 }
3813 }
3814 }
3815
hid_claim_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)3816 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3817 {
3818 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3819 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3820
3821 CHECK_HID_AVAILABLE;
3822
3823 // NB: Disconnection detection is not possible in this function
3824 if (priv->usb_interface[iface].path == NULL) {
3825 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3826 }
3827
3828 // We use dev_handle as a flag for interface claimed
3829 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
3830 return LIBUSB_ERROR_BUSY; // already claimed
3831 }
3832
3833 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3834
3835 usbi_dbg("claimed interface %d", iface);
3836 handle_priv->active_interface = iface;
3837
3838 return LIBUSB_SUCCESS;
3839 }
3840
hid_release_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)3841 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3842 {
3843 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3844 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3845
3846 CHECK_HID_AVAILABLE;
3847
3848 if (priv->usb_interface[iface].path == NULL) {
3849 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3850 }
3851
3852 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
3853 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3854 }
3855
3856 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3857
3858 return LIBUSB_SUCCESS;
3859 }
3860
hid_set_interface_altsetting(int sub_api,struct libusb_device_handle * dev_handle,int iface,int altsetting)3861 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3862 {
3863 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3864
3865 CHECK_HID_AVAILABLE;
3866
3867 if (altsetting > 255) {
3868 return LIBUSB_ERROR_INVALID_PARAM;
3869 }
3870
3871 if (altsetting != 0) {
3872 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3873 return LIBUSB_ERROR_NOT_SUPPORTED;
3874 }
3875
3876 return LIBUSB_SUCCESS;
3877 }
3878
hid_submit_control_transfer(int sub_api,struct usbi_transfer * itransfer)3879 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3880 {
3881 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3882 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3883 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3884 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3885 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3886 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3887 HANDLE hid_handle;
3888 struct winfd wfd;
3889 int current_interface, config;
3890 size_t size;
3891 int r = LIBUSB_ERROR_INVALID_PARAM;
3892
3893 CHECK_HID_AVAILABLE;
3894
3895 transfer_priv->pollable_fd = INVALID_WINFD;
3896 safe_free(transfer_priv->hid_buffer);
3897 transfer_priv->hid_dest = NULL;
3898 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3899
3900 if (size > MAX_CTRL_BUFFER_LENGTH) {
3901 return LIBUSB_ERROR_INVALID_PARAM;
3902 }
3903
3904 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3905 if (current_interface < 0) {
3906 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) {
3907 return LIBUSB_ERROR_NOT_FOUND;
3908 }
3909 }
3910
3911 usbi_dbg("will use interface %d", current_interface);
3912 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3913 // Always use the handle returned from usbi_create_fd (wfd.handle)
3914 wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
3915 if (wfd.fd < 0) {
3916 return LIBUSB_ERROR_NOT_FOUND;
3917 }
3918
3919 switch(LIBUSB_REQ_TYPE(setup->request_type)) {
3920 case LIBUSB_REQUEST_TYPE_STANDARD:
3921 switch(setup->request) {
3922 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3923 r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
3924 (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3925 break;
3926 case LIBUSB_REQUEST_GET_CONFIGURATION:
3927 r = windows_get_configuration(transfer->dev_handle, &config);
3928 if (r == LIBUSB_SUCCESS) {
3929 size = 1;
3930 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3931 r = LIBUSB_COMPLETED;
3932 }
3933 break;
3934 case LIBUSB_REQUEST_SET_CONFIGURATION:
3935 if (setup->value == priv->active_config) {
3936 r = LIBUSB_COMPLETED;
3937 } else {
3938 usbi_warn(ctx, "cannot set configuration other than the default one");
3939 r = LIBUSB_ERROR_INVALID_PARAM;
3940 }
3941 break;
3942 case LIBUSB_REQUEST_GET_INTERFACE:
3943 size = 1;
3944 ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3945 r = LIBUSB_COMPLETED;
3946 break;
3947 case LIBUSB_REQUEST_SET_INTERFACE:
3948 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
3949 if (r == LIBUSB_SUCCESS) {
3950 r = LIBUSB_COMPLETED;
3951 }
3952 break;
3953 default:
3954 usbi_warn(ctx, "unsupported HID control request");
3955 r = LIBUSB_ERROR_INVALID_PARAM;
3956 break;
3957 }
3958 break;
3959 case LIBUSB_REQUEST_TYPE_CLASS:
3960 r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
3961 setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3962 &size, wfd.overlapped);
3963 break;
3964 default:
3965 usbi_warn(ctx, "unsupported HID control request");
3966 r = LIBUSB_ERROR_INVALID_PARAM;
3967 break;
3968 }
3969
3970 if (r == LIBUSB_COMPLETED) {
3971 // Force request to be completed synchronously. Transferred size has been set by previous call
3972 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3973 // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
3974 // set InternalHigh to the number of bytes transferred
3975 wfd.overlapped->InternalHigh = (DWORD)size;
3976 r = LIBUSB_SUCCESS;
3977 }
3978
3979 if (r == LIBUSB_SUCCESS) {
3980 // Use priv_transfer to store data needed for async polling
3981 transfer_priv->pollable_fd = wfd;
3982 transfer_priv->interface_number = (uint8_t)current_interface;
3983 } else {
3984 usbi_free_fd(&wfd);
3985 }
3986
3987 return r;
3988 }
3989
hid_submit_bulk_transfer(int sub_api,struct usbi_transfer * itransfer)3990 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3991 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3992 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3993 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3994 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3995 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3996 struct winfd wfd;
3997 HANDLE hid_handle;
3998 bool direction_in, ret;
3999 int current_interface, length;
4000 DWORD size;
4001 int r = LIBUSB_SUCCESS;
4002
4003 CHECK_HID_AVAILABLE;
4004
4005 transfer_priv->pollable_fd = INVALID_WINFD;
4006 transfer_priv->hid_dest = NULL;
4007 safe_free(transfer_priv->hid_buffer);
4008
4009 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4010 if (current_interface < 0) {
4011 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4012 return LIBUSB_ERROR_NOT_FOUND;
4013 }
4014
4015 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
4016
4017 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4018 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
4019
4020 wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
4021 // Always use the handle returned from usbi_create_fd (wfd.handle)
4022 if (wfd.fd < 0) {
4023 return LIBUSB_ERROR_NO_MEM;
4024 }
4025
4026 // If report IDs are not in use, an extra prefix byte must be added
4027 if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4028 || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4029 length = transfer->length+1;
4030 } else {
4031 length = transfer->length;
4032 }
4033 // Add a trailing byte to detect overflows on input
4034 transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4035 if (transfer_priv->hid_buffer == NULL) {
4036 return LIBUSB_ERROR_NO_MEM;
4037 }
4038 transfer_priv->hid_expected_size = length;
4039
4040 if (direction_in) {
4041 transfer_priv->hid_dest = transfer->buffer;
4042 usbi_dbg("reading %d bytes (report ID: 0x00)", length);
4043 ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4044 } else {
4045 if (!priv->hid->uses_report_ids[1]) {
4046 memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4047 } else {
4048 // We could actually do without the calloc and memcpy in this case
4049 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4050 }
4051 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4052 ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4053 }
4054 if (!ret) {
4055 if (GetLastError() != ERROR_IO_PENDING) {
4056 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4057 usbi_free_fd(&wfd);
4058 safe_free(transfer_priv->hid_buffer);
4059 return LIBUSB_ERROR_IO;
4060 }
4061 } else {
4062 // Only write operations that completed synchronously need to free up
4063 // hid_buffer. For reads, copy_transfer_data() handles that process.
4064 if (!direction_in) {
4065 safe_free(transfer_priv->hid_buffer);
4066 }
4067 if (size == 0) {
4068 usbi_err(ctx, "program assertion failed - no data was transferred");
4069 size = 1;
4070 }
4071 if (size > (size_t)length) {
4072 usbi_err(ctx, "OVERFLOW!");
4073 r = LIBUSB_ERROR_OVERFLOW;
4074 }
4075 wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4076 wfd.overlapped->InternalHigh = size;
4077 }
4078
4079 transfer_priv->pollable_fd = wfd;
4080 transfer_priv->interface_number = (uint8_t)current_interface;
4081
4082 return r;
4083 }
4084
hid_abort_transfers(int sub_api,struct usbi_transfer * itransfer)4085 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4086 {
4087 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4088 struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4089 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4090 HANDLE hid_handle;
4091 int current_interface;
4092
4093 CHECK_HID_AVAILABLE;
4094
4095 current_interface = transfer_priv->interface_number;
4096 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4097 CancelIo(hid_handle);
4098
4099 return LIBUSB_SUCCESS;
4100 }
4101
hid_reset_device(int sub_api,struct libusb_device_handle * dev_handle)4102 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4103 {
4104 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4105 HANDLE hid_handle;
4106 int current_interface;
4107
4108 CHECK_HID_AVAILABLE;
4109
4110 // Flushing the queues on all interfaces is the best we can achieve
4111 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4112 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4113 if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4114 HidD_FlushQueue(hid_handle);
4115 }
4116 }
4117 return LIBUSB_SUCCESS;
4118 }
4119
hid_clear_halt(int sub_api,struct libusb_device_handle * dev_handle,unsigned char endpoint)4120 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4121 {
4122 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4123 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4124 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4125 HANDLE hid_handle;
4126 int current_interface;
4127
4128 CHECK_HID_AVAILABLE;
4129
4130 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4131 if (current_interface < 0) {
4132 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4133 return LIBUSB_ERROR_NOT_FOUND;
4134 }
4135
4136 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4137 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4138
4139 // No endpoint selection with Microsoft's implementation, so we try to flush the
4140 // whole interface. Should be OK for most case scenarios
4141 if (!HidD_FlushQueue(hid_handle)) {
4142 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4143 // Device was probably disconnected
4144 return LIBUSB_ERROR_NO_DEVICE;
4145 }
4146
4147 return LIBUSB_SUCCESS;
4148 }
4149
4150 // This extra function is only needed for HID
hid_copy_transfer_data(int sub_api,struct usbi_transfer * itransfer,uint32_t io_size)4151 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4152 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4153 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4154 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4155 int r = LIBUSB_TRANSFER_COMPLETED;
4156 uint32_t corrected_size = io_size;
4157
4158 if (transfer_priv->hid_buffer != NULL) {
4159 // If we have a valid hid_buffer, it means the transfer was async
4160 if (transfer_priv->hid_dest != NULL) { // Data readout
4161 // First, check for overflow
4162 if (corrected_size > transfer_priv->hid_expected_size) {
4163 usbi_err(ctx, "OVERFLOW!");
4164 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4165 r = LIBUSB_TRANSFER_OVERFLOW;
4166 }
4167
4168 if (transfer_priv->hid_buffer[0] == 0) {
4169 // Discard the 1 byte report ID prefix
4170 corrected_size--;
4171 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4172 } else {
4173 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4174 }
4175 transfer_priv->hid_dest = NULL;
4176 }
4177 // For write, we just need to free the hid buffer
4178 safe_free(transfer_priv->hid_buffer);
4179 }
4180 itransfer->transferred += corrected_size;
4181 return r;
4182 }
4183
4184
4185 /*
4186 * Composite API functions
4187 */
composite_init(int sub_api,struct libusb_context * ctx)4188 static int composite_init(int sub_api, struct libusb_context *ctx)
4189 {
4190 return LIBUSB_SUCCESS;
4191 }
4192
composite_exit(int sub_api)4193 static int composite_exit(int sub_api)
4194 {
4195 return LIBUSB_SUCCESS;
4196 }
4197
composite_open(int sub_api,struct libusb_device_handle * dev_handle)4198 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4199 {
4200 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4201 int r = LIBUSB_ERROR_NOT_FOUND;
4202 uint8_t i;
4203 // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4204 bool available[SUB_API_MAX+1] = {0};
4205
4206 for (i=0; i<USB_MAXINTERFACES; i++) {
4207 switch (priv->usb_interface[i].apib->id) {
4208 case USB_API_WINUSBX:
4209 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4210 available[priv->usb_interface[i].sub_api] = true;
4211 break;
4212 case USB_API_HID:
4213 available[SUB_API_MAX] = true;
4214 break;
4215 default:
4216 break;
4217 }
4218 }
4219
4220 for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4221 if (available[i]) {
4222 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4223 if (r != LIBUSB_SUCCESS) {
4224 return r;
4225 }
4226 }
4227 }
4228 if (available[SUB_API_MAX]) { // HID driver
4229 r = hid_open(SUB_API_NOTSET, dev_handle);
4230 }
4231 return r;
4232 }
4233
composite_close(int sub_api,struct libusb_device_handle * dev_handle)4234 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4235 {
4236 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4237 uint8_t i;
4238 bool available[SUB_API_MAX];
4239
4240 for (i = 0; i<SUB_API_MAX; i++) {
4241 available[i] = false;
4242 }
4243
4244 for (i=0; i<USB_MAXINTERFACES; i++) {
4245 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4246 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4247 available[priv->usb_interface[i].sub_api] = true;
4248 }
4249 }
4250
4251 for (i=0; i<SUB_API_MAX; i++) {
4252 if (available[i]) {
4253 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4254 }
4255 }
4256 }
4257
composite_claim_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)4258 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4259 {
4260 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4261 return priv->usb_interface[iface].apib->
4262 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4263 }
4264
composite_set_interface_altsetting(int sub_api,struct libusb_device_handle * dev_handle,int iface,int altsetting)4265 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4266 {
4267 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4268 return priv->usb_interface[iface].apib->
4269 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4270 }
4271
composite_release_interface(int sub_api,struct libusb_device_handle * dev_handle,int iface)4272 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4273 {
4274 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4275 return priv->usb_interface[iface].apib->
4276 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4277 }
4278
composite_submit_control_transfer(int sub_api,struct usbi_transfer * itransfer)4279 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4280 {
4281 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4282 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4283 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4284 int i, pass;
4285
4286 // Interface shouldn't matter for control, but it does in practice, with Windows'
4287 // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
4288 for (pass = 0; pass < 2; pass++) {
4289 for (i=0; i<USB_MAXINTERFACES; i++) {
4290 if (priv->usb_interface[i].path != NULL) {
4291 if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
4292 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
4293 continue;
4294 }
4295 usbi_dbg("using interface %d", i);
4296 return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
4297 }
4298 }
4299 }
4300
4301 usbi_err(ctx, "no libusbx supported interfaces to complete request");
4302 return LIBUSB_ERROR_NOT_FOUND;
4303 }
4304
composite_submit_bulk_transfer(int sub_api,struct usbi_transfer * itransfer)4305 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4306 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4307 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4308 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4309 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4310 int current_interface;
4311
4312 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4313 if (current_interface < 0) {
4314 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4315 return LIBUSB_ERROR_NOT_FOUND;
4316 }
4317
4318 return priv->usb_interface[current_interface].apib->
4319 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4320
composite_submit_iso_transfer(int sub_api,struct usbi_transfer * itransfer)4321 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4322 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4323 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4324 struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4325 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4326 int current_interface;
4327
4328 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4329 if (current_interface < 0) {
4330 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4331 return LIBUSB_ERROR_NOT_FOUND;
4332 }
4333
4334 return priv->usb_interface[current_interface].apib->
4335 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4336
composite_clear_halt(int sub_api,struct libusb_device_handle * dev_handle,unsigned char endpoint)4337 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4338 {
4339 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4340 struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4341 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4342 int current_interface;
4343
4344 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4345 if (current_interface < 0) {
4346 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4347 return LIBUSB_ERROR_NOT_FOUND;
4348 }
4349
4350 return priv->usb_interface[current_interface].apib->
4351 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4352
composite_abort_control(int sub_api,struct usbi_transfer * itransfer)4353 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4354 {
4355 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4356 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4357 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4358
4359 return priv->usb_interface[transfer_priv->interface_number].apib->
4360 abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4361
composite_abort_transfers(int sub_api,struct usbi_transfer * itransfer)4362 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4363 {
4364 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4365 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4366 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4367
4368 return priv->usb_interface[transfer_priv->interface_number].apib->
4369 abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4370
composite_reset_device(int sub_api,struct libusb_device_handle * dev_handle)4371 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4372 {
4373 struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4374 int r;
4375 uint8_t i;
4376 bool available[SUB_API_MAX];
4377 for (i = 0; i<SUB_API_MAX; i++) {
4378 available[i] = false;
4379 }
4380 for (i=0; i<USB_MAXINTERFACES; i++) {
4381 if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4382 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4383 available[priv->usb_interface[i].sub_api] = true;
4384 }
4385 }
4386 for (i=0; i<SUB_API_MAX; i++) {
4387 if (available[i]) {
4388 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4389 if (r != LIBUSB_SUCCESS) {
4390 return r;
4391 }
4392 }
4393 }
4394 return LIBUSB_SUCCESS;
4395 }
4396
composite_copy_transfer_data(int sub_api,struct usbi_transfer * itransfer,uint32_t io_size)4397 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4398 {
4399 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4400 struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4401 struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4402
4403 return priv->usb_interface[transfer_priv->interface_number].apib->
4404 copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);
4405 }
4406