2 * windows backend for libusb 1.0
3 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4 * Copyright © 2016-2018 Chris Dickens <christopher.a.dickens@gmail.com>
5 * With contributions from Michael Plante, Orin Eman et al.
6 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
7 * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
8 * Hash table functions adapted from glibc, by Ulrich Drepper et al.
9 * Major code testing contribution by Xiaofan Chen
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
40 #include "windows_common.h"
41 #include "windows_nt_common.h"
42 #include "windows_winusb.h"
44 #define HANDLE_VALID(h) (((h) != NULL) && ((h) != INVALID_HANDLE_VALUE))
46 // The 2 macros below are used in conjunction with safe loops.
47 #define LOOP_CHECK(fcall) \
50 if (r != LIBUSB_SUCCESS) \
53 #define LOOP_BREAK(err) \
59 // WinUSB-like API prototypes
60 static int winusbx_init(struct libusb_context *ctx);
61 static void winusbx_exit(void);
62 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle);
63 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle);
64 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
65 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
66 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
67 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
68 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
69 static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
70 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
71 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
72 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
73 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer);
74 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
75 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
77 static int hid_init(struct libusb_context *ctx);
78 static void hid_exit(void);
79 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle);
80 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle);
81 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
82 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
83 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
84 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
85 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
86 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
87 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
88 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
89 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
90 // Composite API prototypes
91 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle);
92 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle);
93 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
94 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
95 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
96 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
97 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
98 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
99 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
100 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
101 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer);
102 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
103 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
105 static usbi_mutex_t autoclaim_lock;
108 static HMODULE WinUSBX_handle = NULL;
109 static struct winusb_interface WinUSBX[SUB_API_MAX];
110 #define CHECK_WINUSBX_AVAILABLE(sub_api) \
112 if (sub_api == SUB_API_NOTSET) \
113 sub_api = priv->sub_api; \
114 if (!WinUSBX[sub_api].initialized) \
115 return LIBUSB_ERROR_ACCESS; \
118 static bool api_hid_available = false;
119 #define CHECK_HID_AVAILABLE \
121 if (!api_hid_available) \
122 return LIBUSB_ERROR_ACCESS; \
125 #if defined(ENABLE_LOGGING)
126 static const char *guid_to_string(const GUID *guid)
128 static char guid_string[MAX_GUID_STRING_LENGTH];
133 sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
134 (unsigned int)guid->Data1, guid->Data2, guid->Data3,
135 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
136 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
143 * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
144 * Return an allocated sanitized string or NULL on error.
146 static char *sanitize_path(const char *path)
148 const char root_prefix[] = {'\\', '\\', '.', '\\'};
156 size = strlen(path) + 1;
158 // Microsoft indiscriminately uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
159 if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\'))
160 || ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
161 add_root = sizeof(root_prefix);
165 ret_path = malloc(size);
166 if (ret_path == NULL)
169 strcpy(&ret_path[add_root], path);
171 // Ensure consistency with root prefix
172 memcpy(ret_path, root_prefix, sizeof(root_prefix));
174 // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
175 for (j = sizeof(root_prefix); j < size; j++) {
176 ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
177 if (ret_path[j] == '\\')
185 * Cfgmgr32, AdvAPI32, OLE32 and SetupAPI DLL functions
187 static BOOL init_dlls(void)
189 DLL_GET_HANDLE(Cfgmgr32);
190 DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Parent, TRUE);
191 DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Child, TRUE);
193 // Prefixed to avoid conflict with header files
194 DLL_GET_HANDLE(AdvAPI32);
195 DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegQueryValueExW, TRUE);
196 DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegCloseKey, TRUE);
198 DLL_GET_HANDLE(OLE32);
199 DLL_LOAD_FUNC_PREFIXED(OLE32, p, IIDFromString, TRUE);
201 DLL_GET_HANDLE(SetupAPI);
202 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetClassDevsA, TRUE);
203 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInfo, TRUE);
204 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInterfaces, TRUE);
205 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInstanceIdA, TRUE);
206 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
207 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
208 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiDestroyDeviceInfoList, TRUE);
209 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDevRegKey, TRUE);
210 DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
215 static void exit_dlls(void)
217 DLL_FREE_HANDLE(Cfgmgr32);
218 DLL_FREE_HANDLE(AdvAPI32);
219 DLL_FREE_HANDLE(OLE32);
220 DLL_FREE_HANDLE(SetupAPI);
224 * enumerate interfaces for the whole USB class
227 * dev_info: a pointer to a dev_info list
228 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
229 * enumerator: the generic USB class for which to retrieve interface details
230 * index: zero based index of the interface in the device info list
232 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
233 * structure returned and call this function repeatedly using the same guid (with an
234 * incremented index starting at zero) until all interfaces have been returned.
236 static bool get_devinfo_data(struct libusb_context *ctx,
237 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char *enumerator, unsigned _index)
240 *dev_info = pSetupDiGetClassDevsA(NULL, enumerator, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
241 if (*dev_info == INVALID_HANDLE_VALUE) {
242 usbi_err(ctx, "could not obtain device info set for PnP enumerator '%s': %s",
243 enumerator, windows_error_str(0));
248 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
249 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
250 if (GetLastError() != ERROR_NO_MORE_ITEMS)
251 usbi_err(ctx, "could not obtain device info data for PnP enumerator '%s' index %u: %s",
252 enumerator, _index, windows_error_str(0));
254 pSetupDiDestroyDeviceInfoList(*dev_info);
255 *dev_info = INVALID_HANDLE_VALUE;
262 * enumerate interfaces for a specific GUID
265 * dev_info: a pointer to a dev_info list
266 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
267 * guid: the GUID for which to retrieve interface details
268 * index: zero based index of the interface in the device info list
270 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
271 * structure returned and call this function repeatedly using the same guid (with an
272 * incremented index starting at zero) until all interfaces have been returned.
274 static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
275 PSP_DEVINFO_DATA dev_info_data, LPCGUID guid, DWORD *_index, char **dev_interface_path)
277 SP_DEVICE_INTERFACE_DATA dev_interface_data;
278 PSP_DEVICE_INTERFACE_DETAIL_DATA_A dev_interface_details;
281 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
282 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
284 if (!pSetupDiEnumDeviceInfo(dev_info, *_index, dev_info_data)) {
285 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
286 usbi_err(ctx, "Could not obtain device info data for %s index %u: %s",
287 guid_to_string(guid), *_index, windows_error_str(0));
288 return LIBUSB_ERROR_OTHER;
292 return LIBUSB_SUCCESS;
295 // Always advance the index for the next iteration
298 if (pSetupDiEnumDeviceInterfaces(dev_info, dev_info_data, guid, 0, &dev_interface_data))
301 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
302 usbi_err(ctx, "Could not obtain interface data for %s devInst %X: %s",
303 guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0));
304 return LIBUSB_ERROR_OTHER;
307 // Device does not have an interface matching this GUID, skip
310 // Read interface data (dummy + actual) to access the device path
311 if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
312 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
313 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
314 usbi_err(ctx, "could not access interface data (dummy) for %s devInst %X: %s",
315 guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0));
316 return LIBUSB_ERROR_OTHER;
319 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong");
320 return LIBUSB_ERROR_OTHER;
323 dev_interface_details = malloc(size);
324 if (dev_interface_details == NULL) {
325 usbi_err(ctx, "could not allocate interface data for %s devInst %X",
326 guid_to_string(guid), dev_info_data->DevInst);
327 return LIBUSB_ERROR_NO_MEM;
330 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
331 if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data,
332 dev_interface_details, size, NULL, NULL)) {
333 usbi_err(ctx, "could not access interface data (actual) for %s devInst %X: %s",
334 guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0));
335 free(dev_interface_details);
336 return LIBUSB_ERROR_OTHER;
339 *dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
340 free(dev_interface_details);
342 if (*dev_interface_path == NULL) {
343 usbi_err(ctx, "could not allocate interface path for %s devInst %X",
344 guid_to_string(guid), dev_info_data->DevInst);
345 return LIBUSB_ERROR_NO_MEM;
348 return LIBUSB_SUCCESS;
351 /* For libusb0 filter */
352 static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
353 HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID *guid, unsigned _index, char *filter_path)
355 SP_DEVICE_INTERFACE_DATA dev_interface_data;
356 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details;
360 *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
362 if (dev_info_data != NULL) {
363 dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
364 if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
365 if (GetLastError() != ERROR_NO_MORE_ITEMS)
366 usbi_err(ctx, "Could not obtain device info data for index %u: %s",
367 _index, windows_error_str(0));
369 pSetupDiDestroyDeviceInfoList(*dev_info);
370 *dev_info = INVALID_HANDLE_VALUE;
375 dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
376 if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
377 if (GetLastError() != ERROR_NO_MORE_ITEMS)
378 usbi_err(ctx, "Could not obtain interface data for index %u: %s",
379 _index, windows_error_str(0));
381 pSetupDiDestroyDeviceInfoList(*dev_info);
382 *dev_info = INVALID_HANDLE_VALUE;
386 // Read interface data (dummy + actual) to access the device path
387 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
388 // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
389 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
390 usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
391 _index, windows_error_str(0));
395 usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
399 dev_interface_details = calloc(1, size);
400 if (dev_interface_details == NULL) {
401 usbi_err(ctx, "could not allocate interface data for index %u.", _index);
405 dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
406 if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, dev_interface_details, size, &size, NULL))
407 usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
408 _index, windows_error_str(0));
410 // [trobinso] lookup the libusb0 symbolic index.
411 if (dev_interface_details) {
412 HKEY hkey_device_interface = pSetupDiOpenDeviceInterfaceRegKey(*dev_info, &dev_interface_data, 0, KEY_READ);
413 if (hkey_device_interface != INVALID_HANDLE_VALUE) {
414 DWORD libusb0_symboliclink_index = 0;
415 DWORD value_length = sizeof(DWORD);
416 DWORD value_type = 0;
419 status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type,
420 (LPBYTE)&libusb0_symboliclink_index, &value_length);
421 if (status == ERROR_SUCCESS) {
422 if (libusb0_symboliclink_index < 256) {
423 // libusb0.sys is connected to this device instance.
424 // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
425 sprintf(filter_path, "\\\\.\\libusb0-%04u", (unsigned int)libusb0_symboliclink_index);
426 usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
428 // libusb0.sys was connected to this device instance at one time; but not anymore.
431 pRegCloseKey(hkey_device_interface);
435 return dev_interface_details;
438 pSetupDiDestroyDeviceInfoList(*dev_info);
439 *dev_info = INVALID_HANDLE_VALUE;
444 * Returns the first known ancestor of a device
446 static struct libusb_device *get_ancestor(struct libusb_context *ctx,
447 DEVINST devinst, PDEVINST _parent_devinst)
449 struct libusb_device *dev = NULL;
450 DEVINST parent_devinst;
452 while (dev == NULL) {
453 if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS)
455 devinst = parent_devinst;
456 dev = usbi_get_device_by_session_id(ctx, (unsigned long)devinst);
459 if ((dev != NULL) && (_parent_devinst != NULL))
460 *_parent_devinst = devinst;
466 * Determine which interface the given endpoint address belongs to
468 static int get_interface_by_endpoint(struct libusb_config_descriptor *conf_desc, uint8_t ep)
470 const struct libusb_interface *intf;
471 const struct libusb_interface_descriptor *intf_desc;
474 for (i = 0; i < conf_desc->bNumInterfaces; i++) {
475 intf = &conf_desc->interface[i];
476 for (j = 0; j < intf->num_altsetting; j++) {
477 intf_desc = &intf->altsetting[j];
478 for (k = 0; k < intf_desc->bNumEndpoints; k++) {
479 if (intf_desc->endpoint[k].bEndpointAddress == ep) {
480 usbi_dbg("found endpoint %02X on interface %d", intf_desc->bInterfaceNumber, i);
481 return intf_desc->bInterfaceNumber;
487 usbi_dbg("endpoint %02X not found on any interface", ep);
488 return LIBUSB_ERROR_NOT_FOUND;
492 * Populate the endpoints addresses of the device_priv interface helper structs
494 static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
497 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
498 struct libusb_config_descriptor *conf_desc;
499 const struct libusb_interface_descriptor *if_desc;
500 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
502 r = libusb_get_active_config_descriptor(dev_handle->dev, &conf_desc);
503 if (r != LIBUSB_SUCCESS) {
504 usbi_warn(ctx, "could not read config descriptor: error %d", r);
508 if_desc = &conf_desc->interface[iface].altsetting[altsetting];
509 safe_free(priv->usb_interface[iface].endpoint);
511 if (if_desc->bNumEndpoints == 0) {
512 usbi_dbg("no endpoints found for interface %d", iface);
513 libusb_free_config_descriptor(conf_desc);
514 return LIBUSB_SUCCESS;
517 priv->usb_interface[iface].endpoint = malloc(if_desc->bNumEndpoints);
518 if (priv->usb_interface[iface].endpoint == NULL) {
519 libusb_free_config_descriptor(conf_desc);
520 return LIBUSB_ERROR_NO_MEM;
523 priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
524 for (i = 0; i < if_desc->bNumEndpoints; i++) {
525 priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
526 usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface);
528 libusb_free_config_descriptor(conf_desc);
530 // Extra init may be required to configure endpoints
531 if (priv->apib->configure_endpoints)
532 r = priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
537 // Lookup for a match in the list of API driver names
538 // return -1 if not found, driver match number otherwise
539 static int get_sub_api(char *driver, int api)
542 const char sep_str[2] = {LIST_SEPARATOR, 0};
544 size_t len = strlen(driver);
547 return SUB_API_NOTSET;
549 tmp_str = _strdup(driver);
551 return SUB_API_NOTSET;
553 tok = strtok(tmp_str, sep_str);
554 while (tok != NULL) {
555 for (i = 0; i < usb_api_backend[api].nb_driver_names; i++) {
556 if (_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
561 tok = strtok(NULL, sep_str);
565 return SUB_API_NOTSET;
569 * auto-claiming and auto-release helper functions
571 static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
573 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
574 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(
575 transfer->dev_handle);
576 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
577 int current_interface = *interface_number;
578 int r = LIBUSB_SUCCESS;
581 case USB_API_WINUSBX:
585 return LIBUSB_ERROR_INVALID_PARAM;
588 usbi_mutex_lock(&autoclaim_lock);
589 if (current_interface < 0) { // No serviceable interface was found
590 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
591 // Must claim an interface of the same API type
592 if ((priv->usb_interface[current_interface].apib->id == api_type)
593 && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS)) {
594 usbi_dbg("auto-claimed interface %d for control request", current_interface);
595 if (handle_priv->autoclaim_count[current_interface] != 0)
596 usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero");
597 handle_priv->autoclaim_count[current_interface]++;
601 if (current_interface == USB_MAXINTERFACES) {
602 usbi_err(ctx, "could not auto-claim any interface");
603 r = LIBUSB_ERROR_NOT_FOUND;
606 // If we have a valid interface that was autoclaimed, we must increment
607 // its autoclaim count so that we can prevent an early release.
608 if (handle_priv->autoclaim_count[current_interface] != 0)
609 handle_priv->autoclaim_count[current_interface]++;
611 usbi_mutex_unlock(&autoclaim_lock);
613 *interface_number = current_interface;
617 static void auto_release(struct usbi_transfer *itransfer)
619 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
620 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
621 libusb_device_handle *dev_handle = transfer->dev_handle;
622 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
625 usbi_mutex_lock(&autoclaim_lock);
626 if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
627 handle_priv->autoclaim_count[transfer_priv->interface_number]--;
628 if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
629 r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
630 if (r == LIBUSB_SUCCESS)
631 usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
633 usbi_dbg("failed to auto-release interface %d (%s)",
634 transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
637 usbi_mutex_unlock(&autoclaim_lock);
641 * init: libusb backend init function
643 static int winusb_init(struct libusb_context *ctx)
647 // We need a lock for proper auto-release
648 usbi_mutex_init(&autoclaim_lock);
652 usbi_err(ctx, "could not resolve DLL functions");
653 return LIBUSB_ERROR_OTHER;
656 // Initialize the low level APIs (we don't care about errors at this stage)
657 for (i = 0; i < USB_API_MAX; i++) {
658 if (usb_api_backend[i].init && usb_api_backend[i].init(ctx))
659 usbi_warn(ctx, "error initializing %s backend",
660 usb_api_backend[i].designation);
663 return LIBUSB_SUCCESS;
667 * exit: libusb backend deinitialization function
669 static void winusb_exit(struct libusb_context *ctx)
673 for (i = 0; i < USB_API_MAX; i++) {
674 if (usb_api_backend[i].exit)
675 usb_api_backend[i].exit();
679 usbi_mutex_destroy(&autoclaim_lock);
683 * fetch and cache all the config descriptors through I/O
685 static void cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle)
687 struct libusb_context *ctx = DEVICE_CTX(dev);
688 struct winusb_device_priv *priv = _device_priv(dev);
689 DWORD size, ret_size;
692 USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
693 PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
694 PUSB_CONFIGURATION_DESCRIPTOR cd_data;
696 if (dev->num_configurations == 0)
699 priv->config_descriptor = calloc(dev->num_configurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR));
700 if (priv->config_descriptor == NULL) {
701 usbi_err(ctx, "could not allocate configuration descriptor array for '%s'", priv->dev_id);
705 for (i = 0; i <= dev->num_configurations; i++) {
706 safe_free(cd_buf_actual);
708 if (i == dev->num_configurations)
711 size = sizeof(cd_buf_short);
712 memset(&cd_buf_short, 0, size);
714 cd_buf_short.req.ConnectionIndex = (ULONG)dev->port_number;
715 cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
716 cd_buf_short.req.SetupPacket.bRequest = LIBUSB_REQUEST_GET_DESCRIPTOR;
717 cd_buf_short.req.SetupPacket.wValue = (LIBUSB_DT_CONFIG << 8) | i;
718 cd_buf_short.req.SetupPacket.wIndex = 0;
719 cd_buf_short.req.SetupPacket.wLength = (USHORT)sizeof(USB_CONFIGURATION_DESCRIPTOR);
721 // Dummy call to get the required data size. Initial failures are reported as info rather
722 // than error as they can occur for non-penalizing situations, such as with some hubs.
723 // coverity[tainted_data_argument]
724 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
725 &cd_buf_short, size, &ret_size, NULL)) {
726 usbi_info(ctx, "could not access configuration descriptor %u (dummy) for '%s': %s", i, priv->dev_id, windows_error_str(0));
730 if ((ret_size != size) || (cd_buf_short.desc.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
731 usbi_info(ctx, "unexpected configuration descriptor %u size (dummy) for '%s'", i, priv->dev_id);
735 size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.desc.wTotalLength;
736 cd_buf_actual = malloc(size);
737 if (cd_buf_actual == NULL) {
738 usbi_err(ctx, "could not allocate configuration descriptor %u buffer for '%s'", i, priv->dev_id);
743 cd_buf_actual->ConnectionIndex = (ULONG)dev->port_number;
744 cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
745 cd_buf_actual->SetupPacket.bRequest = LIBUSB_REQUEST_GET_DESCRIPTOR;
746 cd_buf_actual->SetupPacket.wValue = (LIBUSB_DT_CONFIG << 8) | i;
747 cd_buf_actual->SetupPacket.wIndex = 0;
748 cd_buf_actual->SetupPacket.wLength = cd_buf_short.desc.wTotalLength;
750 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
751 cd_buf_actual, size, &ret_size, NULL)) {
752 usbi_err(ctx, "could not access configuration descriptor %u (actual) for '%s': %s", i, priv->dev_id, windows_error_str(0));
756 cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR *)cd_buf_actual + sizeof(USB_DESCRIPTOR_REQUEST));
758 if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.desc.wTotalLength)) {
759 usbi_err(ctx, "unexpected configuration descriptor %u size (actual) for '%s'", i, priv->dev_id);
763 if (cd_data->bDescriptorType != LIBUSB_DT_CONFIG) {
764 usbi_err(ctx, "descriptor %u not a configuration descriptor for '%s'", i, priv->dev_id);
768 usbi_dbg("cached config descriptor %u (bConfigurationValue=%u, %u bytes)",
769 i, cd_data->bConfigurationValue, cd_data->wTotalLength);
771 // Cache the descriptor
772 priv->config_descriptor[i] = malloc(cd_data->wTotalLength);
773 if (priv->config_descriptor[i] != NULL) {
774 memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
776 usbi_err(ctx, "could not allocate configuration descriptor %u buffer for '%s'", i, priv->dev_id);
782 * Populate a libusb device structure
784 static int init_device(struct libusb_device *dev, struct libusb_device *parent_dev,
785 uint8_t port_number, DEVINST devinst)
787 struct libusb_context *ctx;
788 struct libusb_device *tmp_dev;
789 struct winusb_device_priv *priv, *parent_priv;
790 USB_NODE_CONNECTION_INFORMATION_EX conn_info;
791 USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2;
794 uint8_t bus_number, depth;
797 priv = _device_priv(dev);
799 // If the device is already initialized, we can stop here
800 if (priv->initialized)
801 return LIBUSB_SUCCESS;
803 if (parent_dev != NULL) { // Not a HCD root hub
804 ctx = DEVICE_CTX(dev);
805 parent_priv = _device_priv(parent_dev);
806 if (parent_priv->apib->id != USB_API_HUB) {
807 usbi_warn(ctx, "parent for device '%s' is not a hub", priv->dev_id);
808 return LIBUSB_ERROR_NOT_FOUND;
811 // Calculate depth and fetch bus number
812 bus_number = parent_dev->bus_number;
813 if (bus_number == 0) {
814 tmp_dev = get_ancestor(ctx, devinst, &devinst);
815 if (tmp_dev != parent_dev) {
816 usbi_err(ctx, "program assertion failed - first ancestor is not parent");
817 return LIBUSB_ERROR_NOT_FOUND;
819 libusb_unref_device(tmp_dev);
821 for (depth = 1; bus_number == 0; depth++) {
822 tmp_dev = get_ancestor(ctx, devinst, &devinst);
823 if (tmp_dev->bus_number != 0) {
824 bus_number = tmp_dev->bus_number;
825 depth += _device_priv(tmp_dev)->depth;
827 libusb_unref_device(tmp_dev);
830 depth = parent_priv->depth + 1;
833 if (bus_number == 0) {
834 usbi_err(ctx, "program assertion failed - bus number not found for '%s'", priv->dev_id);
835 return LIBUSB_ERROR_NOT_FOUND;
838 dev->bus_number = bus_number;
839 dev->port_number = port_number;
840 dev->parent_dev = parent_dev;
843 hub_handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
845 if (hub_handle == INVALID_HANDLE_VALUE) {
846 usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
847 return LIBUSB_ERROR_ACCESS;
850 memset(&conn_info, 0, sizeof(conn_info));
851 conn_info.ConnectionIndex = (ULONG)port_number;
852 // coverity[tainted_data_argument]
853 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, sizeof(conn_info),
854 &conn_info, sizeof(conn_info), &size, NULL)) {
855 usbi_warn(ctx, "could not get node connection information for device '%s': %s",
856 priv->dev_id, windows_error_str(0));
857 CloseHandle(hub_handle);
858 return LIBUSB_ERROR_NO_DEVICE;
861 if (conn_info.ConnectionStatus == NoDeviceConnected) {
862 usbi_err(ctx, "device '%s' is no longer connected!", priv->dev_id);
863 CloseHandle(hub_handle);
864 return LIBUSB_ERROR_NO_DEVICE;
867 memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
868 dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
869 priv->active_config = conn_info.CurrentConfigurationValue;
870 usbi_dbg("found %u configurations (active conf: %u)", dev->num_configurations, priv->active_config);
872 // Cache as many config descriptors as we can
873 cache_config_descriptors(dev, hub_handle);
875 // In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8
876 if (windows_version >= WINDOWS_8) {
877 conn_info_v2.ConnectionIndex = (ULONG)port_number;
878 conn_info_v2.Length = sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2);
879 conn_info_v2.SupportedUsbProtocols.Usb300 = 1;
880 if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2,
881 &conn_info_v2, sizeof(conn_info_v2), &conn_info_v2, sizeof(conn_info_v2), &size, NULL)) {
882 usbi_warn(ctx, "could not get node connection information (V2) for device '%s': %s",
883 priv->dev_id, windows_error_str(0));
884 } else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) {
889 CloseHandle(hub_handle);
891 if (conn_info.DeviceAddress > UINT8_MAX)
892 usbi_err(ctx, "program assertion failed - device address overflow");
894 dev->device_address = (uint8_t)conn_info.DeviceAddress;
896 switch (conn_info.Speed) {
897 case 0: dev->speed = LIBUSB_SPEED_LOW; break;
898 case 1: dev->speed = LIBUSB_SPEED_FULL; break;
899 case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
900 case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
902 usbi_warn(ctx, "unknown device speed %u", conn_info.Speed);
907 r = usbi_sanitize_device(dev);
911 priv->initialized = true;
913 usbi_dbg("(bus: %u, addr: %u, depth: %u, port: %u): '%s'",
914 dev->bus_number, dev->device_address, priv->depth, dev->port_number, priv->dev_id);
916 return LIBUSB_SUCCESS;
919 static int enumerate_hcd_root_hub(struct libusb_context *ctx, const char *dev_id,
920 uint8_t bus_number, DEVINST devinst)
922 struct libusb_device *dev;
923 struct winusb_device_priv *priv;
924 unsigned long session_id;
925 DEVINST child_devinst;
927 if (CM_Get_Child(&child_devinst, devinst, 0) != CR_SUCCESS) {
928 usbi_err(ctx, "could not get child devinst for '%s'", dev_id);
929 return LIBUSB_ERROR_OTHER;
932 session_id = (unsigned long)child_devinst;
933 dev = usbi_get_device_by_session_id(ctx, session_id);
935 usbi_err(ctx, "program assertion failed - HCD '%s' child not found", dev_id);
936 return LIBUSB_ERROR_NO_DEVICE;
939 if (dev->bus_number == 0) {
941 usbi_dbg("assigning HCD '%s' bus number %u", dev_id, bus_number);
942 priv = _device_priv(dev);
943 dev->bus_number = bus_number;
944 dev->num_configurations = 1;
945 priv->dev_descriptor.bLength = LIBUSB_DT_DEVICE_SIZE;
946 priv->dev_descriptor.bDescriptorType = LIBUSB_DT_DEVICE;
947 priv->dev_descriptor.bDeviceClass = LIBUSB_CLASS_HUB;
948 priv->dev_descriptor.bNumConfigurations = 1;
949 priv->active_config = 1;
950 priv->root_hub = true;
951 if (sscanf(dev_id, "PCI\\VEN_%04hx&DEV_%04hx%*s", &priv->dev_descriptor.idVendor, &priv->dev_descriptor.idProduct) != 2) {
952 usbi_warn(ctx, "could not infer VID/PID of HCD root hub from '%s'", dev_id);
953 priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub
954 priv->dev_descriptor.idProduct = 1;
958 libusb_unref_device(dev);
959 return LIBUSB_SUCCESS;
962 // Returns the api type, or 0 if not found/unsupported
963 static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
964 SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
966 // Precedence for filter drivers vs driver is in the order of this array
967 struct driver_lookup lookup[3] = {
968 {"\0\0", SPDRP_SERVICE, "driver"},
969 {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
970 {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
972 DWORD size, reg_type;
976 // Check the service & filter names to know the API we should use
977 for (k = 0; k < 3; k++) {
978 if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
979 ®_type, (PBYTE)lookup[k].list, MAX_KEY_LENGTH, &size)) {
980 // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
981 if (lookup[k].reg_prop == SPDRP_SERVICE)
982 // our buffers are MAX_KEY_LENGTH + 1 so we can overflow if needed
983 lookup[k].list[strlen(lookup[k].list) + 1] = 0;
985 // MULTI_SZ is a pain to work with. Turn it into something much more manageable
986 // NB: none of the driver names we check against contain LIST_SEPARATOR,
987 // (currently ';'), so even if an unsuported one does, it's not an issue
988 for (l = 0; (lookup[k].list[l] != 0) || (lookup[k].list[l + 1] != 0); l++) {
989 if (lookup[k].list[l] == 0)
990 lookup[k].list[l] = LIST_SEPARATOR;
992 usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
994 if (GetLastError() != ERROR_INVALID_DATA)
995 usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
996 lookup[k].list[0] = 0;
1000 for (i = 2; i < USB_API_MAX; i++) {
1001 for (k = 0; k < 3; k++) {
1002 j = get_sub_api(lookup[k].list, i);
1004 usbi_dbg("matched %s name against %s", lookup[k].designation,
1005 (i != USB_API_WINUSBX) ? usb_api_backend[i].designation : usb_api_backend[i].driver_name_list[j]);
1014 static int set_composite_interface(struct libusb_context *ctx, struct libusb_device *dev,
1015 char *dev_interface_path, char *device_id, int api, int sub_api)
1017 struct winusb_device_priv *priv = _device_priv(dev);
1018 int interface_number;
1021 // Because MI_## are not necessarily in sequential order (some composite
1022 // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1023 // interface number from the path's MI value
1024 mi_str = strstr(device_id, "MI_");
1025 if ((mi_str != NULL) && isdigit(mi_str[3]) && isdigit(mi_str[4])) {
1026 interface_number = ((mi_str[3] - '0') * 10) + (mi_str[4] - '0');
1028 usbi_warn(ctx, "failure to read interface number for %s, using default value", device_id);
1029 interface_number = 0;
1032 if (interface_number >= USB_MAXINTERFACES) {
1033 usbi_warn(ctx, "interface %d too large - ignoring interface path %s", interface_number, dev_interface_path);
1034 return LIBUSB_ERROR_ACCESS;
1037 if (priv->usb_interface[interface_number].path != NULL) {
1038 if (api == USB_API_HID) {
1039 // HID devices can have multiple collections (COL##) for each MI_## interface
1040 usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1041 interface_number, device_id);
1042 return LIBUSB_ERROR_ACCESS;
1044 // In other cases, just use the latest data
1045 safe_free(priv->usb_interface[interface_number].path);
1048 usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1049 priv->usb_interface[interface_number].path = dev_interface_path;
1050 priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1051 priv->usb_interface[interface_number].sub_api = sub_api;
1052 if ((api == USB_API_HID) && (priv->hid == NULL)) {
1053 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1054 if (priv->hid == NULL)
1055 return LIBUSB_ERROR_NO_MEM;
1058 return LIBUSB_SUCCESS;
1061 static int set_hid_interface(struct libusb_context *ctx, struct libusb_device *dev,
1062 char *dev_interface_path)
1065 struct winusb_device_priv *priv = _device_priv(dev);
1067 if (priv->hid == NULL) {
1068 usbi_err(ctx, "program assertion failed: parent is not HID");
1069 return LIBUSB_ERROR_NO_DEVICE;
1070 } else if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1071 usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1072 return LIBUSB_ERROR_NO_DEVICE;
1075 for (i = 0; i < priv->hid->nb_interfaces; i++) {
1076 if ((priv->usb_interface[i].path != NULL) && strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
1077 usbi_dbg("interface[%d] already set to %s", i, dev_interface_path);
1078 return LIBUSB_ERROR_ACCESS;
1082 priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1083 priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1084 usbi_dbg("interface[%u] = %s", priv->hid->nb_interfaces, dev_interface_path);
1085 priv->hid->nb_interfaces++;
1086 return LIBUSB_SUCCESS;
1090 * get_device_list: libusb backend device enumeration function
1092 static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1094 struct discovered_devs *discdevs;
1095 HDEVINFO *dev_info, dev_info_intf, dev_info_enum;
1096 SP_DEVINFO_DATA dev_info_data;
1099 int r = LIBUSB_SUCCESS;
1101 unsigned int pass, i, j;
1102 char enumerator[16];
1103 char dev_id[MAX_PATH_LENGTH];
1104 struct libusb_device *dev, *parent_dev;
1105 struct winusb_device_priv *priv, *parent_priv;
1106 char *dev_interface_path = NULL;
1107 unsigned long session_id;
1108 DWORD size, port_nr, reg_type, install_state;
1110 WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1119 // Keep a list of guids that will be enumerated
1120 #define GUID_SIZE_STEP 8
1121 const GUID **guid_list, **new_guid_list;
1122 unsigned int guid_size = GUID_SIZE_STEP;
1123 unsigned int nb_guids;
1124 // Keep a list of PnP enumerator strings that are found
1125 char *usb_enumerator[8] = { "USB" };
1126 unsigned int nb_usb_enumerators = 1;
1127 unsigned int usb_enum_index = 0;
1128 // Keep a list of newly allocated devs to unref
1129 #define UNREF_SIZE_STEP 16
1130 libusb_device **unref_list, **new_unref_list;
1131 unsigned int unref_size = UNREF_SIZE_STEP;
1132 unsigned int unref_cur = 0;
1134 // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1135 // PASS 2 : (re)enumerate HUBS
1136 // PASS 3 : (re)enumerate generic USB devices (including driverless)
1137 // and list additional USB device interface GUIDs to explore
1138 // PASS 4 : (re)enumerate master USB devices that have a device interface
1139 // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1140 // set the device interfaces.
1142 // Init the GUID table
1143 guid_list = malloc(guid_size * sizeof(void *));
1144 if (guid_list == NULL) {
1145 usbi_err(ctx, "failed to alloc guid list");
1146 return LIBUSB_ERROR_NO_MEM;
1149 guid_list[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1150 guid_list[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1151 guid_list[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1152 guid_list[GEN_PASS] = NULL;
1153 if (api_hid_available) {
1154 HidD_GetHidGuid(&hid_guid);
1155 guid_list[HID_PASS] = &hid_guid;
1157 guid_list[HID_PASS] = NULL;
1159 nb_guids = EXT_PASS;
1161 unref_list = malloc(unref_size * sizeof(void *));
1162 if (unref_list == NULL) {
1163 usbi_err(ctx, "failed to alloc unref list");
1164 free((void *)guid_list);
1165 return LIBUSB_ERROR_NO_MEM;
1168 dev_info_intf = pSetupDiGetClassDevsA(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
1169 if (dev_info_intf == INVALID_HANDLE_VALUE) {
1170 usbi_err(ctx, "failed to obtain device info list: %s", windows_error_str(0));
1172 free((void *)guid_list);
1173 return LIBUSB_ERROR_OTHER;
1176 for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1177 //#define ENUM_DEBUG
1178 #if defined(ENABLE_LOGGING) && defined(ENUM_DEBUG)
1179 const char * const passname[] = {"HUB", "DEV", "HCD", "GEN", "HID", "EXT"};
1180 usbi_dbg("#### PROCESSING %ss %s", passname[MIN(pass, EXT_PASS)], guid_to_string(guid_list[pass]));
1182 if ((pass == HID_PASS) && (guid_list[HID_PASS] == NULL))
1185 dev_info = (pass != GEN_PASS) ? &dev_info_intf : &dev_info_enum;
1187 for (i = 0; ; i++) {
1188 // safe loop: free up any (unprotected) dynamic resource
1189 // NB: this is always executed before breaking the loop
1190 safe_free(dev_interface_path);
1191 priv = parent_priv = NULL;
1192 dev = parent_dev = NULL;
1194 // Safe loop: end of loop conditions
1195 if (r != LIBUSB_SUCCESS)
1198 if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1199 usbi_warn(ctx, "program assertion failed - found more than %u buses, skipping the rest.", UINT8_MAX);
1203 if (pass != GEN_PASS) {
1204 // Except for GEN, all passes deal with device interfaces
1205 r = get_interface_details(ctx, *dev_info, &dev_info_data, guid_list[pass], &_index, &dev_interface_path);
1206 if ((r != LIBUSB_SUCCESS) || (dev_interface_path == NULL)) {
1211 // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1212 // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1213 // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1214 // The Intel Alpine Ridge USB 3.1 driver uses "IARUSB3"
1215 for (; usb_enum_index < nb_usb_enumerators; usb_enum_index++) {
1216 if (get_devinfo_data(ctx, dev_info, &dev_info_data, usb_enumerator[usb_enum_index], i))
1220 if (usb_enum_index == nb_usb_enumerators)
1224 // Read the Device ID path
1225 if (!pSetupDiGetDeviceInstanceIdA(*dev_info, &dev_info_data, dev_id, sizeof(dev_id), NULL)) {
1226 usbi_warn(ctx, "could not read the device instance ID for devInst %X, skipping",
1227 dev_info_data.DevInst);
1232 usbi_dbg("PRO: %s", dev_id);
1235 // Set API to use or get additional data from generic pass
1236 api = USB_API_UNSUPPORTED;
1237 sub_api = SUB_API_NOTSET;
1243 // Fetch the PnP enumerator class for this hub
1244 // This will allow us to enumerate all classes during the GEN pass
1245 if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME,
1246 NULL, (PBYTE)enumerator, sizeof(enumerator), NULL)) {
1247 usbi_err(ctx, "could not read enumerator string for device '%s': %s", dev_id, windows_error_str(0));
1248 LOOP_BREAK(LIBUSB_ERROR_OTHER);
1250 for (j = 0; j < nb_usb_enumerators; j++) {
1251 if (strcmp(usb_enumerator[j], enumerator) == 0)
1254 if (j == nb_usb_enumerators) {
1255 usbi_dbg("found new PnP enumerator string '%s'", enumerator);
1256 if (nb_usb_enumerators < ARRAYSIZE(usb_enumerator)) {
1257 usb_enumerator[nb_usb_enumerators] = _strdup(enumerator);
1258 if (usb_enumerator[nb_usb_enumerators] != NULL) {
1259 nb_usb_enumerators++;
1261 usbi_err(ctx, "could not allocate enumerator string '%s'", enumerator);
1262 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1265 usbi_warn(ctx, "too many enumerator strings, some devices may not be accessible");
1270 // We use the GEN pass to detect driverless devices...
1271 if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_DRIVER,
1272 NULL, NULL, 0, NULL) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
1273 usbi_info(ctx, "The following device has no driver: '%s'", dev_id);
1274 usbi_info(ctx, "libusb will not be able to access it");
1276 // ...and to add the additional device interface GUIDs
1277 key = pSetupDiOpenDevRegKey(*dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1278 if (key == INVALID_HANDLE_VALUE)
1280 // Look for both DeviceInterfaceGUIDs *and* DeviceInterfaceGUID, in that order
1281 size = sizeof(guid_string_w);
1282 s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type,
1283 (LPBYTE)guid_string_w, &size);
1284 if (s == ERROR_FILE_NOT_FOUND)
1285 s = pRegQueryValueExW(key, L"DeviceInterfaceGUID", NULL, ®_type,
1286 (LPBYTE)guid_string_w, &size);
1288 if ((s == ERROR_SUCCESS) &&
1289 (((reg_type == REG_SZ) && (size == (sizeof(guid_string_w) - sizeof(WCHAR)))) ||
1290 ((reg_type == REG_MULTI_SZ) && (size == sizeof(guid_string_w))))) {
1291 if (nb_guids == guid_size) {
1292 new_guid_list = realloc((void *)guid_list, (guid_size + GUID_SIZE_STEP) * sizeof(void *));
1293 if (new_guid_list == NULL) {
1294 usbi_err(ctx, "failed to realloc guid list");
1295 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1297 guid_list = new_guid_list;
1298 guid_size += GUID_SIZE_STEP;
1300 if_guid = malloc(sizeof(*if_guid));
1301 if (if_guid == NULL) {
1302 usbi_err(ctx, "failed to alloc if_guid");
1303 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1305 if (pIIDFromString(guid_string_w, if_guid) != 0) {
1306 usbi_warn(ctx, "device '%s' has malformed DeviceInterfaceGUID string, skipping", dev_id);
1309 // Check if we've already seen this GUID
1310 for (j = EXT_PASS; j < nb_guids; j++) {
1311 if (memcmp(guid_list[j], if_guid, sizeof(*if_guid)) == 0)
1314 if (j == nb_guids) {
1315 usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1316 guid_list[nb_guids++] = if_guid;
1318 // Duplicate, ignore
1322 } else if (s == ERROR_SUCCESS) {
1323 usbi_warn(ctx, "unexpected type/size of DeviceInterfaceGUID for '%s'", dev_id);
1330 // Get the API type (after checking that the driver installation is OK)
1331 if ((!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1332 NULL, (PBYTE)&install_state, sizeof(install_state), &size)) || (size != sizeof(install_state))) {
1333 usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1334 dev_id, windows_error_str(0));
1335 } else if (install_state != 0) {
1336 usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %u) - skipping",
1337 dev_id, (unsigned int)install_state);
1340 get_api_type(ctx, dev_info, &dev_info_data, &api, &sub_api);
1344 // Find parent device (for the passes that need it)
1345 if (pass >= GEN_PASS) {
1346 parent_dev = get_ancestor(ctx, dev_info_data.DevInst, NULL);
1347 if (parent_dev == NULL) {
1348 // Root hubs will not have a parent
1349 dev = usbi_get_device_by_session_id(ctx, (unsigned long)dev_info_data.DevInst);
1351 priv = _device_priv(dev);
1354 libusb_unref_device(dev);
1357 usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id);
1361 parent_priv = _device_priv(parent_dev);
1362 // virtual USB devices are also listed during GEN - don't process these yet
1363 if ((pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB)) {
1364 libusb_unref_device(parent_dev);
1369 // Create new or match existing device, using the devInst as session id
1370 if ((pass <= GEN_PASS) && (pass != HCD_PASS)) { // For subsequent passes, we'll lookup the parent
1371 // These are the passes that create "new" devices
1372 session_id = (unsigned long)dev_info_data.DevInst;
1373 dev = usbi_get_device_by_session_id(ctx, session_id);
1376 usbi_dbg("allocating new device for session [%lX]", session_id);
1377 dev = usbi_alloc_device(ctx, session_id);
1379 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1381 priv = winusb_device_priv_init(dev);
1382 priv->dev_id = _strdup(dev_id);
1383 if (priv->dev_id == NULL) {
1384 libusb_unref_device(dev);
1385 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1388 usbi_dbg("found existing device for session [%lX]", session_id);
1390 priv = _device_priv(dev);
1391 if (strcmp(priv->dev_id, dev_id) != 0) {
1392 usbi_dbg("device instance ID for session [%lX] changed", session_id);
1393 usbi_disconnect_device(dev);
1394 libusb_unref_device(dev);
1400 // Keep track of devices that need unref
1401 if (unref_cur == unref_size) {
1402 new_unref_list = realloc(unref_list, (unref_size + UNREF_SIZE_STEP) * sizeof(void *));
1403 if (new_unref_list == NULL) {
1404 usbi_err(ctx, "could not realloc list for unref - aborting");
1405 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1407 unref_list = new_unref_list;
1408 unref_size += UNREF_SIZE_STEP;
1410 unref_list[unref_cur++] = dev;
1417 // If the device has already been setup, don't do it again
1418 if (priv->path != NULL)
1420 // Take care of API initialization
1421 priv->path = dev_interface_path;
1422 dev_interface_path = NULL;
1423 priv->apib = &usb_api_backend[api];
1424 priv->sub_api = sub_api;
1426 case USB_API_COMPOSITE:
1430 priv->hid = calloc(1, sizeof(struct hid_device_priv));
1431 if (priv->hid == NULL)
1432 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1435 // For other devices, the first interface is the same as the device
1436 priv->usb_interface[0].path = _strdup(priv->path);
1437 if (priv->usb_interface[0].path == NULL)
1438 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1439 // The following is needed if we want API calls to work for both simple
1440 // and composite devices.
1441 for (j = 0; j < USB_MAXINTERFACES; j++)
1442 priv->usb_interface[j].apib = &usb_api_backend[api];
1447 r = enumerate_hcd_root_hub(ctx, dev_id, (uint8_t)(i + 1), dev_info_data.DevInst);
1450 // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1452 if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_ADDRESS,
1453 NULL, (PBYTE)&port_nr, sizeof(port_nr), &size) || (size != sizeof(port_nr)))
1454 usbi_warn(ctx, "could not retrieve port number for device '%s': %s", dev_id, windows_error_str(0));
1455 r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_info_data.DevInst);
1456 if (r == LIBUSB_SUCCESS) {
1457 // Append device to the list of discovered devices
1458 discdevs = discovered_devs_append(*_discdevs, dev);
1460 LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1462 *_discdevs = discdevs;
1463 } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1464 // This can occur if the device was disconnected but Windows hasn't
1465 // refreshed its enumeration yet - in that case, we ignore the device
1469 default: // HID_PASS and later
1470 if (parent_priv->apib->id == USB_API_HID || parent_priv->apib->id == USB_API_COMPOSITE) {
1471 if (parent_priv->apib->id == USB_API_HID) {
1472 usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1473 r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1475 usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1476 r = set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id, api, sub_api);
1479 case LIBUSB_SUCCESS:
1480 dev_interface_path = NULL;
1482 case LIBUSB_ERROR_ACCESS:
1483 // interface has already been set => make sure dev_interface_path is freed then
1491 libusb_unref_device(parent_dev);
1497 pSetupDiDestroyDeviceInfoList(dev_info_intf);
1499 // Free any additional GUIDs
1500 for (pass = EXT_PASS; pass < nb_guids; pass++)
1501 free((void *)guid_list[pass]);
1502 free((void *)guid_list);
1504 // Free any PnP enumerator strings
1505 for (i = 1; i < nb_usb_enumerators; i++)
1506 free(usb_enumerator[i]);
1508 // Unref newly allocated devs
1509 for (i = 0; i < unref_cur; i++)
1510 libusb_unref_device(unref_list[i]);
1516 static int winusb_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer)
1518 struct winusb_device_priv *priv = _device_priv(dev);
1520 memcpy(buffer, &priv->dev_descriptor, DEVICE_DESC_LENGTH);
1521 return LIBUSB_SUCCESS;
1524 static int winusb_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len)
1526 struct winusb_device_priv *priv = _device_priv(dev);
1527 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1530 // config index is zero based
1531 if (config_index >= dev->num_configurations)
1532 return LIBUSB_ERROR_INVALID_PARAM;
1534 if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1535 return LIBUSB_ERROR_NOT_FOUND;
1537 config_header = priv->config_descriptor[config_index];
1539 size = MIN(config_header->wTotalLength, len);
1540 memcpy(buffer, priv->config_descriptor[config_index], size);
1544 static int winusb_get_config_descriptor_by_value(struct libusb_device *dev, uint8_t bConfigurationValue,
1545 unsigned char **buffer)
1547 struct winusb_device_priv *priv = _device_priv(dev);
1548 PUSB_CONFIGURATION_DESCRIPTOR config_header;
1551 if (priv->config_descriptor == NULL)
1552 return LIBUSB_ERROR_NOT_FOUND;
1554 for (index = 0; index < dev->num_configurations; index++) {
1555 config_header = priv->config_descriptor[index];
1556 if (config_header == NULL)
1558 if (config_header->bConfigurationValue == bConfigurationValue) {
1559 *buffer = (unsigned char *)priv->config_descriptor[index];
1560 return (int)config_header->wTotalLength;
1564 return LIBUSB_ERROR_NOT_FOUND;
1568 * return the cached copy of the active config descriptor
1570 static int winusb_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len)
1572 struct winusb_device_priv *priv = _device_priv(dev);
1573 unsigned char *config_desc;
1576 if (priv->active_config == 0)
1577 return LIBUSB_ERROR_NOT_FOUND;
1579 r = winusb_get_config_descriptor_by_value(dev, priv->active_config, &config_desc);
1583 len = MIN((size_t)r, len);
1584 memcpy(buffer, config_desc, len);
1588 static int winusb_open(struct libusb_device_handle *dev_handle)
1590 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1592 CHECK_SUPPORTED_API(priv->apib, open);
1594 return priv->apib->open(SUB_API_NOTSET, dev_handle);
1597 static void winusb_close(struct libusb_device_handle *dev_handle)
1599 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1601 if (priv->apib->close)
1602 priv->apib->close(SUB_API_NOTSET, dev_handle);
1605 static int winusb_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1607 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1609 if (priv->active_config == 0) {
1611 return LIBUSB_ERROR_NOT_FOUND;
1614 *config = priv->active_config;
1615 return LIBUSB_SUCCESS;
1619 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1620 * does not currently expose a service that allows higher-level drivers to set
1621 * the configuration."
1623 static int winusb_set_configuration(struct libusb_device_handle *dev_handle, int config)
1625 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1626 int r = LIBUSB_SUCCESS;
1628 if (config >= USB_MAXCONFIG)
1629 return LIBUSB_ERROR_INVALID_PARAM;
1631 r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
1632 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
1633 LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
1636 if (r == LIBUSB_SUCCESS)
1637 priv->active_config = (uint8_t)config;
1642 static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int iface)
1644 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1647 CHECK_SUPPORTED_API(priv->apib, claim_interface);
1649 safe_free(priv->usb_interface[iface].endpoint);
1650 priv->usb_interface[iface].nb_endpoints = 0;
1652 r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
1654 if (r == LIBUSB_SUCCESS)
1655 r = windows_assign_endpoints(dev_handle, iface, 0);
1660 static int winusb_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
1662 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1665 CHECK_SUPPORTED_API(priv->apib, set_interface_altsetting);
1667 safe_free(priv->usb_interface[iface].endpoint);
1668 priv->usb_interface[iface].nb_endpoints = 0;
1670 r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
1672 if (r == LIBUSB_SUCCESS)
1673 r = windows_assign_endpoints(dev_handle, iface, altsetting);
1678 static int winusb_release_interface(struct libusb_device_handle *dev_handle, int iface)
1680 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1682 CHECK_SUPPORTED_API(priv->apib, release_interface);
1684 return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
1687 static int winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
1689 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1691 CHECK_SUPPORTED_API(priv->apib, clear_halt);
1693 return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
1696 static int winusb_reset_device(struct libusb_device_handle *dev_handle)
1698 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
1700 CHECK_SUPPORTED_API(priv->apib, reset_device);
1702 return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
1705 static void winusb_destroy_device(struct libusb_device *dev)
1707 winusb_device_priv_release(dev);
1710 static void winusb_clear_transfer_priv(struct usbi_transfer *itransfer)
1712 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
1714 usbi_close(transfer_priv->pollable_fd.fd);
1715 transfer_priv->pollable_fd = INVALID_WINFD;
1716 transfer_priv->handle = NULL;
1717 safe_free(transfer_priv->hid_buffer);
1718 safe_free(transfer_priv->iso_context);
1720 // When auto claim is in use, attempt to release the auto-claimed interface
1721 auto_release(itransfer);
1724 static int do_submit_transfer(struct usbi_transfer *itransfer, short events,
1725 int (*transfer_fn)(int, struct usbi_transfer *))
1727 struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
1728 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
1732 wfd = usbi_create_fd();
1734 return LIBUSB_ERROR_NO_MEM;
1736 r = usbi_add_pollfd(ctx, wfd.fd, events);
1742 // Use transfer_priv to store data needed for async polling
1743 transfer_priv->pollable_fd = wfd;
1745 r = transfer_fn(SUB_API_NOTSET, itransfer);
1747 if ((r != LIBUSB_SUCCESS) && (r != LIBUSB_ERROR_OVERFLOW)) {
1748 usbi_remove_pollfd(ctx, wfd.fd);
1750 transfer_priv->pollable_fd = INVALID_WINFD;
1756 static int winusb_submit_transfer(struct usbi_transfer *itransfer)
1758 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1759 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1760 int (*transfer_fn)(int, struct usbi_transfer *);
1763 switch (transfer->type) {
1764 case LIBUSB_TRANSFER_TYPE_CONTROL:
1765 events = (transfer->buffer[0] & LIBUSB_ENDPOINT_IN) ? POLLIN : POLLOUT;
1766 transfer_fn = priv->apib->submit_control_transfer;
1768 case LIBUSB_TRANSFER_TYPE_BULK:
1769 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1770 if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET))
1771 return LIBUSB_ERROR_NOT_SUPPORTED;
1772 events = IS_XFERIN(transfer) ? POLLIN : POLLOUT;
1773 transfer_fn = priv->apib->submit_bulk_transfer;
1775 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1776 events = IS_XFERIN(transfer) ? POLLIN : POLLOUT;
1777 transfer_fn = priv->apib->submit_iso_transfer;
1779 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
1780 return LIBUSB_ERROR_NOT_SUPPORTED;
1782 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1783 return LIBUSB_ERROR_INVALID_PARAM;
1786 if (transfer_fn == NULL) {
1787 usbi_warn(TRANSFER_CTX(transfer),
1788 "unsupported transfer type %d (unrecognized device driver)",
1790 return LIBUSB_ERROR_NOT_SUPPORTED;
1793 return do_submit_transfer(itransfer, events, transfer_fn);
1796 static int windows_abort_control(struct usbi_transfer *itransfer)
1798 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1799 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1801 CHECK_SUPPORTED_API(priv->apib, abort_control);
1803 return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
1806 static int windows_abort_transfers(struct usbi_transfer *itransfer)
1808 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1809 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1811 CHECK_SUPPORTED_API(priv->apib, abort_transfers);
1813 return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
1816 static int winusb_cancel_transfer(struct usbi_transfer *itransfer)
1818 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1820 switch (transfer->type) {
1821 case LIBUSB_TRANSFER_TYPE_CONTROL:
1822 return windows_abort_control(itransfer);
1823 case LIBUSB_TRANSFER_TYPE_BULK:
1824 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1825 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1826 return windows_abort_transfers(itransfer);
1827 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
1828 return LIBUSB_ERROR_NOT_SUPPORTED;
1830 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
1831 return LIBUSB_ERROR_INVALID_PARAM;
1835 static int winusb_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size)
1837 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1838 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
1839 return priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
1842 static int winusb_get_transfer_fd(struct usbi_transfer *itransfer)
1844 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
1845 return transfer_priv->pollable_fd.fd;
1848 static void winusb_get_overlapped_result(struct usbi_transfer *itransfer,
1849 DWORD *io_result, DWORD *io_size)
1851 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
1852 struct winfd *pollable_fd = &transfer_priv->pollable_fd;
1854 if (HasOverlappedIoCompletedSync(pollable_fd->overlapped)) {
1855 *io_result = NO_ERROR;
1856 *io_size = (DWORD)pollable_fd->overlapped->InternalHigh;
1857 } else if (GetOverlappedResult(transfer_priv->handle, pollable_fd->overlapped, io_size, FALSE)) {
1858 // Regular async overlapped
1859 *io_result = NO_ERROR;
1861 *io_result = GetLastError();
1865 // NB: MSVC6 does not support named initializers.
1866 const struct windows_backend winusb_backend = {
1869 winusb_get_device_list,
1872 winusb_get_device_descriptor,
1873 winusb_get_active_config_descriptor,
1874 winusb_get_config_descriptor,
1875 winusb_get_config_descriptor_by_value,
1876 winusb_get_configuration,
1877 winusb_set_configuration,
1878 winusb_claim_interface,
1879 winusb_release_interface,
1880 winusb_set_interface_altsetting,
1882 winusb_reset_device,
1883 winusb_destroy_device,
1884 winusb_submit_transfer,
1885 winusb_cancel_transfer,
1886 winusb_clear_transfer_priv,
1887 winusb_copy_transfer_data,
1888 winusb_get_transfer_fd,
1889 winusb_get_overlapped_result,
1896 static const char * const composite_driver_names[] = {"USBCCGP"};
1897 static const char * const winusbx_driver_names[] = {"libusbK", "libusb0", "WinUSB"};
1898 static const char * const hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
1899 const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
1901 USB_API_UNSUPPORTED,
1903 // No supported operations
1908 // No supported operations
1913 composite_driver_names,
1914 ARRAYSIZE(composite_driver_names),
1919 NULL, /* configure_endpoints */
1920 composite_claim_interface,
1921 composite_set_interface_altsetting,
1922 composite_release_interface,
1923 composite_clear_halt,
1924 composite_reset_device,
1925 composite_submit_bulk_transfer,
1926 composite_submit_iso_transfer,
1927 composite_submit_control_transfer,
1928 composite_abort_control,
1929 composite_abort_transfers,
1930 composite_copy_transfer_data,
1935 winusbx_driver_names,
1936 ARRAYSIZE(winusbx_driver_names),
1941 winusbx_configure_endpoints,
1942 winusbx_claim_interface,
1943 winusbx_set_interface_altsetting,
1944 winusbx_release_interface,
1946 winusbx_reset_device,
1947 winusbx_submit_bulk_transfer,
1948 winusbx_submit_iso_transfer,
1949 winusbx_submit_control_transfer,
1950 winusbx_abort_control,
1951 winusbx_abort_transfers,
1952 winusbx_copy_transfer_data,
1958 ARRAYSIZE(hid_driver_names),
1963 NULL, /* configure_endpoints */
1964 hid_claim_interface,
1965 hid_set_interface_altsetting,
1966 hid_release_interface,
1969 hid_submit_bulk_transfer,
1970 NULL, /* submit_iso_transfer */
1971 hid_submit_control_transfer,
1972 hid_abort_transfers,
1973 hid_abort_transfers,
1974 hid_copy_transfer_data,
1980 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
1982 #define WinUSBX_Set(fn) \
1984 if (native_winusb) \
1985 WinUSBX[i].fn = (WinUsb_##fn##_t)GetProcAddress(h, "WinUsb_" #fn); \
1987 pLibK_GetProcAddress((PVOID *)&WinUSBX[i].fn, i, KUSB_FNID_##fn); \
1990 static int winusbx_init(struct libusb_context *ctx)
1995 KLIB_VERSION LibK_Version;
1996 LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
1997 LibK_GetVersion_t pLibK_GetVersion;
1999 h = LoadLibraryA("libusbK");
2002 usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2003 h = LoadLibraryA("WinUSB");
2006 usbi_warn(ctx, "WinUSB DLL is not available either, "
2007 "you will not be able to access devices outside of enumeration");
2008 return LIBUSB_ERROR_NOT_FOUND;
2011 usbi_dbg("using libusbK DLL for universal access");
2012 pLibK_GetVersion = (LibK_GetVersion_t)GetProcAddress(h, "LibK_GetVersion");
2013 if (pLibK_GetVersion != NULL) {
2014 pLibK_GetVersion(&LibK_Version);
2015 usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2016 LibK_Version.Micro, LibK_Version.Nano);
2018 pLibK_GetProcAddress = (LibK_GetProcAddress_t)GetProcAddress(h, "LibK_GetProcAddress");
2019 if (pLibK_GetProcAddress == NULL) {
2020 usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2022 return LIBUSB_ERROR_NOT_FOUND;
2026 native_winusb = (pLibK_GetProcAddress == NULL);
2027 for (i = 0; i < SUB_API_MAX; i++) {
2028 WinUSBX_Set(AbortPipe);
2029 WinUSBX_Set(ControlTransfer);
2030 WinUSBX_Set(FlushPipe);
2032 WinUSBX_Set(GetAssociatedInterface);
2033 WinUSBX_Set(Initialize);
2034 WinUSBX_Set(ReadPipe);
2036 WinUSBX_Set(ResetDevice);
2037 WinUSBX_Set(ResetPipe);
2038 WinUSBX_Set(SetCurrentAlternateSetting);
2039 WinUSBX_Set(SetPipePolicy);
2040 WinUSBX_Set(WritePipe);
2041 WinUSBX_Set(IsoReadPipe);
2042 WinUSBX_Set(IsoWritePipe);
2044 if (WinUSBX[i].Initialize != NULL) {
2045 WinUSBX[i].initialized = true;
2046 // Assume driver supports CancelIoEx() if it is available
2047 WinUSBX[i].CancelIoEx_supported = (pCancelIoEx != NULL);
2048 usbi_dbg("initalized sub API %s", winusbx_driver_names[i]);
2050 usbi_warn(ctx, "Failed to initalize sub API %s", winusbx_driver_names[i]);
2051 WinUSBX[i].initialized = false;
2056 return LIBUSB_SUCCESS;
2059 static void winusbx_exit(void)
2061 if (WinUSBX_handle != NULL) {
2062 FreeLibrary(WinUSBX_handle);
2063 WinUSBX_handle = NULL;
2065 /* Reset the WinUSBX API structures */
2066 memset(&WinUSBX, 0, sizeof(WinUSBX));
2070 // NB: open and close must ensure that they only handle interface of
2071 // the right API type, as these functions can be called wholesale from
2072 // composite_open(), with interfaces belonging to different APIs
2073 static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2075 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2076 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2077 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2081 CHECK_WINUSBX_AVAILABLE(sub_api);
2083 // WinUSB requires a separate handle for each interface
2084 for (i = 0; i < USB_MAXINTERFACES; i++) {
2085 if ((priv->usb_interface[i].path != NULL)
2086 && (priv->usb_interface[i].apib->id == USB_API_WINUSBX)) {
2087 file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2088 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2089 if (file_handle == INVALID_HANDLE_VALUE) {
2090 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2091 switch (GetLastError()) {
2092 case ERROR_FILE_NOT_FOUND: // The device was disconnected
2093 return LIBUSB_ERROR_NO_DEVICE;
2094 case ERROR_ACCESS_DENIED:
2095 return LIBUSB_ERROR_ACCESS;
2097 return LIBUSB_ERROR_IO;
2100 handle_priv->interface_handle[i].dev_handle = file_handle;
2104 return LIBUSB_SUCCESS;
2107 static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2109 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2110 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2114 if (sub_api == SUB_API_NOTSET)
2115 sub_api = priv->sub_api;
2117 if (!WinUSBX[sub_api].initialized)
2120 if (priv->apib->id == USB_API_COMPOSITE) {
2121 // If this is a composite device, just free and close all WinUSB-like
2122 // interfaces directly (each is independent and not associated with another)
2123 for (i = 0; i < USB_MAXINTERFACES; i++) {
2124 if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2125 handle = handle_priv->interface_handle[i].api_handle;
2126 if (HANDLE_VALID(handle))
2127 WinUSBX[sub_api].Free(handle);
2129 handle = handle_priv->interface_handle[i].dev_handle;
2130 if (HANDLE_VALID(handle))
2131 CloseHandle(handle);
2135 // If this is a WinUSB device, free all interfaces above interface 0,
2136 // then free and close interface 0 last
2137 for (i = 1; i < USB_MAXINTERFACES; i++) {
2138 handle = handle_priv->interface_handle[i].api_handle;
2139 if (HANDLE_VALID(handle))
2140 WinUSBX[sub_api].Free(handle);
2142 handle = handle_priv->interface_handle[0].api_handle;
2143 if (HANDLE_VALID(handle))
2144 WinUSBX[sub_api].Free(handle);
2146 handle = handle_priv->interface_handle[0].dev_handle;
2147 if (HANDLE_VALID(handle))
2148 CloseHandle(handle);
2152 static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2154 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2155 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2156 HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2159 uint8_t endpoint_address;
2162 CHECK_WINUSBX_AVAILABLE(sub_api);
2164 // With handle and enpoints set (in parent), we can setup the default pipe properties
2165 // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2166 for (i = -1; i < priv->usb_interface[iface].nb_endpoints; i++) {
2167 endpoint_address = (i == -1) ? 0 : priv->usb_interface[iface].endpoint[i];
2168 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2169 PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout))
2170 usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2172 if ((i == -1) || (sub_api == SUB_API_LIBUSB0))
2173 continue; // Other policies don't apply to control endpoint or libusb0
2176 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2177 SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy))
2178 usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2180 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2181 IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy))
2182 usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2185 /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2186 https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2187 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2188 ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy))
2189 usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2191 if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2192 AUTO_CLEAR_STALL, sizeof(UCHAR), &policy))
2193 usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2196 return LIBUSB_SUCCESS;
2199 static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2201 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2202 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2203 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2204 bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2205 SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2206 HDEVINFO dev_info = INVALID_HANDLE_VALUE;
2207 SP_DEVINFO_DATA dev_info_data;
2208 char *dev_path_no_guid = NULL;
2209 char filter_path[] = "\\\\.\\libusb0-0000";
2210 bool found_filter = false;
2211 HANDLE file_handle, winusb_handle;
2215 CHECK_WINUSBX_AVAILABLE(sub_api);
2217 // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2218 // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2219 if ((is_using_usbccgp) || (iface == 0)) {
2220 // composite device (independent interfaces) or interface 0
2221 file_handle = handle_priv->interface_handle[iface].dev_handle;
2222 if (!HANDLE_VALID(file_handle))
2223 return LIBUSB_ERROR_NOT_FOUND;
2225 if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2226 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2227 err = GetLastError();
2229 case ERROR_BAD_COMMAND:
2230 // The device was disconnected
2231 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2232 return LIBUSB_ERROR_NO_DEVICE;
2234 // it may be that we're using the libusb0 filter driver.
2235 // TODO: can we move this whole business into the K/0 DLL?
2236 for (i = 0; ; i++) {
2237 safe_free(dev_interface_details);
2238 safe_free(dev_path_no_guid);
2240 dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2241 if ((found_filter) || (dev_interface_details == NULL))
2245 dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2246 if (dev_path_no_guid == NULL)
2249 if (strncmp(dev_path_no_guid, priv->usb_interface[iface].path, strlen(dev_path_no_guid)) == 0) {
2250 file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2251 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2252 if (file_handle != INVALID_HANDLE_VALUE) {
2253 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2254 // Replace the existing file handle with the working one
2255 CloseHandle(handle_priv->interface_handle[iface].dev_handle);
2256 handle_priv->interface_handle[iface].dev_handle = file_handle;
2257 found_filter = true;
2259 usbi_err(ctx, "could not initialize filter driver for %s", filter_path);
2260 CloseHandle(file_handle);
2263 usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2267 free(dev_interface_details);
2268 if (!found_filter) {
2269 usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2270 return LIBUSB_ERROR_ACCESS;
2274 handle_priv->interface_handle[iface].api_handle = winusb_handle;
2276 // For all other interfaces, use GetAssociatedInterface()
2277 winusb_handle = handle_priv->interface_handle[0].api_handle;
2278 // It is a requirement for multiple interface devices on Windows that, to you
2279 // must first claim the first interface before you claim the others
2280 if (!HANDLE_VALID(winusb_handle)) {
2281 file_handle = handle_priv->interface_handle[0].dev_handle;
2282 if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2283 handle_priv->interface_handle[0].api_handle = winusb_handle;
2284 usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2286 usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2287 return LIBUSB_ERROR_ACCESS;
2290 if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface - 1),
2291 &handle_priv->interface_handle[iface].api_handle)) {
2292 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2293 switch (GetLastError()) {
2294 case ERROR_NO_MORE_ITEMS: // invalid iface
2295 return LIBUSB_ERROR_NOT_FOUND;
2296 case ERROR_BAD_COMMAND: // The device was disconnected
2297 return LIBUSB_ERROR_NO_DEVICE;
2298 case ERROR_ALREADY_EXISTS: // already claimed
2299 return LIBUSB_ERROR_BUSY;
2301 usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2302 return LIBUSB_ERROR_ACCESS;
2306 usbi_dbg("claimed interface %d", iface);
2307 handle_priv->active_interface = iface;
2309 return LIBUSB_SUCCESS;
2312 static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2314 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2315 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2316 HANDLE winusb_handle;
2318 CHECK_WINUSBX_AVAILABLE(sub_api);
2320 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2321 if (!HANDLE_VALID(winusb_handle))
2322 return LIBUSB_ERROR_NOT_FOUND;
2324 WinUSBX[sub_api].Free(winusb_handle);
2325 handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2327 return LIBUSB_SUCCESS;
2331 * Return the first valid interface (of the same API type), for control transfers
2333 static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2335 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2336 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2339 if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2340 usbi_dbg("unsupported API ID");
2344 for (i = 0; i < USB_MAXINTERFACES; i++) {
2345 if (HANDLE_VALID(handle_priv->interface_handle[i].dev_handle)
2346 && HANDLE_VALID(handle_priv->interface_handle[i].api_handle)
2347 && (priv->usb_interface[i].apib->id == api_id))
2355 * Lookup interface by endpoint address. -1 if not found
2357 static int interface_by_endpoint(struct winusb_device_priv *priv,
2358 struct winusb_device_handle_priv *handle_priv, uint8_t endpoint_address)
2362 for (i = 0; i < USB_MAXINTERFACES; i++) {
2363 if (!HANDLE_VALID(handle_priv->interface_handle[i].api_handle))
2365 if (priv->usb_interface[i].endpoint == NULL)
2367 for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) {
2368 if (priv->usb_interface[i].endpoint[j] == endpoint_address)
2376 static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2378 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2379 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2380 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2381 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
2382 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2383 PWINUSB_SETUP_PACKET setup = (PWINUSB_SETUP_PACKET)transfer->buffer;
2385 HANDLE winusb_handle;
2386 OVERLAPPED *overlapped;
2387 int current_interface;
2389 CHECK_WINUSBX_AVAILABLE(sub_api);
2391 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2393 // Windows places upper limits on the control transfer size
2394 // See: https://msdn.microsoft.com/en-us/library/windows/hardware/ff538112.aspx
2395 if (size > MAX_CTRL_BUFFER_LENGTH)
2396 return LIBUSB_ERROR_INVALID_PARAM;
2398 current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
2399 if (current_interface < 0) {
2400 if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS)
2401 return LIBUSB_ERROR_NOT_FOUND;
2404 usbi_dbg("will use interface %d", current_interface);
2406 transfer_priv->handle = winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2407 overlapped = transfer_priv->pollable_fd.overlapped;
2409 // Sending of set configuration control requests from WinUSB creates issues
2410 if ((LIBUSB_REQ_TYPE(setup->RequestType) == LIBUSB_REQUEST_TYPE_STANDARD)
2411 && (setup->Request == LIBUSB_REQUEST_SET_CONFIGURATION)) {
2412 if (setup->Value != priv->active_config) {
2413 usbi_warn(ctx, "cannot set configuration other than the default one");
2414 return LIBUSB_ERROR_INVALID_PARAM;
2416 windows_force_sync_completion(overlapped, 0);
2418 if (!WinUSBX[sub_api].ControlTransfer(winusb_handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, overlapped)) {
2419 if (GetLastError() != ERROR_IO_PENDING) {
2420 usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
2421 return LIBUSB_ERROR_IO;
2424 windows_force_sync_completion(overlapped, size);
2428 transfer_priv->interface_number = (uint8_t)current_interface;
2430 return LIBUSB_SUCCESS;
2433 static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
2435 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2436 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2437 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2438 HANDLE winusb_handle;
2440 CHECK_WINUSBX_AVAILABLE(sub_api);
2442 if (altsetting > 255)
2443 return LIBUSB_ERROR_INVALID_PARAM;
2445 winusb_handle = handle_priv->interface_handle[iface].api_handle;
2446 if (!HANDLE_VALID(winusb_handle)) {
2447 usbi_err(ctx, "interface must be claimed first");
2448 return LIBUSB_ERROR_NOT_FOUND;
2451 if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
2452 usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
2453 return LIBUSB_ERROR_IO;
2456 return LIBUSB_SUCCESS;
2459 static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer)
2461 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2462 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2463 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
2464 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2465 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2466 HANDLE winusb_handle;
2467 OVERLAPPED *overlapped;
2469 int current_interface;
2472 PKISO_CONTEXT iso_context;
2473 size_t iso_ctx_size;
2475 CHECK_WINUSBX_AVAILABLE(sub_api);
2477 if ((sub_api != SUB_API_LIBUSBK) && (sub_api != SUB_API_LIBUSB0)) {
2478 // iso only supported on libusbk-based backends
2479 PRINT_UNSUPPORTED_API(submit_iso_transfer);
2480 return LIBUSB_ERROR_NOT_SUPPORTED;
2483 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2484 if (current_interface < 0) {
2485 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2486 return LIBUSB_ERROR_NOT_FOUND;
2489 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2491 transfer_priv->handle = winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2492 overlapped = transfer_priv->pollable_fd.overlapped;
2494 iso_ctx_size = sizeof(KISO_CONTEXT) + (transfer->num_iso_packets * sizeof(KISO_PACKET));
2495 transfer_priv->iso_context = iso_context = calloc(1, iso_ctx_size);
2496 if (transfer_priv->iso_context == NULL)
2497 return LIBUSB_ERROR_NO_MEM;
2500 iso_context->StartFrame = 0;
2501 iso_context->NumberOfPackets = (SHORT)transfer->num_iso_packets;
2503 // convert the transfer packet lengths to iso_packet offsets
2505 for (i = 0; i < transfer->num_iso_packets; i++) {
2506 iso_context->IsoPackets[i].offset = offset;
2507 offset += transfer->iso_packet_desc[i].length;
2510 if (IS_XFERIN(transfer)) {
2511 usbi_dbg("reading %d iso packets", transfer->num_iso_packets);
2512 ret = WinUSBX[sub_api].IsoReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context);
2514 usbi_dbg("writing %d iso packets", transfer->num_iso_packets);
2515 ret = WinUSBX[sub_api].IsoWritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context);
2519 if (GetLastError() != ERROR_IO_PENDING) {
2520 usbi_err(ctx, "IsoReadPipe/IsoWritePipe failed: %s", windows_error_str(0));
2521 return LIBUSB_ERROR_IO;
2524 windows_force_sync_completion(overlapped, (ULONG)transfer->length);
2527 transfer_priv->interface_number = (uint8_t)current_interface;
2529 return LIBUSB_SUCCESS;
2532 static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
2534 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2535 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2536 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
2537 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2538 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2539 HANDLE winusb_handle;
2540 OVERLAPPED *overlapped;
2542 int current_interface;
2544 CHECK_WINUSBX_AVAILABLE(sub_api);
2546 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
2547 if (current_interface < 0) {
2548 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
2549 return LIBUSB_ERROR_NOT_FOUND;
2552 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
2554 transfer_priv->handle = winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2555 overlapped = transfer_priv->pollable_fd.overlapped;
2557 if (IS_XFERIN(transfer)) {
2558 usbi_dbg("reading %d bytes", transfer->length);
2559 ret = WinUSBX[sub_api].ReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped);
2561 usbi_dbg("writing %d bytes", transfer->length);
2562 ret = WinUSBX[sub_api].WritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped);
2566 if (GetLastError() != ERROR_IO_PENDING) {
2567 usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
2568 return LIBUSB_ERROR_IO;
2571 windows_force_sync_completion(overlapped, (ULONG)transfer->length);
2574 transfer_priv->interface_number = (uint8_t)current_interface;
2576 return LIBUSB_SUCCESS;
2579 static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
2581 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2582 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2583 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2584 HANDLE winusb_handle;
2585 int current_interface;
2587 CHECK_WINUSBX_AVAILABLE(sub_api);
2589 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
2590 if (current_interface < 0) {
2591 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
2592 return LIBUSB_ERROR_NOT_FOUND;
2595 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
2596 winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
2598 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
2599 usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
2600 return LIBUSB_ERROR_NO_DEVICE;
2603 return LIBUSB_SUCCESS;
2607 * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
2608 * through testing as well):
2609 * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
2610 * the control transfer using CancelIo"
2612 static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
2614 // Cancelling of the I/O is done in the parent
2615 return LIBUSB_SUCCESS;
2618 static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
2620 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2621 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2622 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
2623 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
2624 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2626 int current_interface;
2628 CHECK_WINUSBX_AVAILABLE(sub_api);
2630 current_interface = transfer_priv->interface_number;
2631 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
2632 usbi_err(ctx, "program assertion failed: invalid interface_number");
2633 return LIBUSB_ERROR_NOT_FOUND;
2635 usbi_dbg("will use interface %d", current_interface);
2637 if (WinUSBX[sub_api].CancelIoEx_supported) {
2638 // Try to use CancelIoEx if available to cancel just a single transfer
2639 handle = handle_priv->interface_handle[current_interface].dev_handle;
2640 if (pCancelIoEx(handle, transfer_priv->pollable_fd.overlapped))
2641 return LIBUSB_SUCCESS;
2642 else if (GetLastError() == ERROR_NOT_FOUND)
2643 return LIBUSB_ERROR_NOT_FOUND;
2645 // Not every driver implements the necessary functionality for CancelIoEx
2646 usbi_warn(ctx, "CancelIoEx not supported for sub API %s", winusbx_driver_names[sub_api]);
2647 WinUSBX[sub_api].CancelIoEx_supported = false;
2650 handle = handle_priv->interface_handle[current_interface].api_handle;
2651 if (!WinUSBX[sub_api].AbortPipe(handle, transfer->endpoint)) {
2652 usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
2653 return LIBUSB_ERROR_NO_DEVICE;
2656 return LIBUSB_SUCCESS;
2660 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
2661 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
2662 * "WinUSB does not support host-initiated reset port and cycle port operations" and
2663 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
2664 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
2665 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
2667 // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
2668 static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
2670 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2671 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2672 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
2673 HANDLE winusb_handle;
2676 CHECK_WINUSBX_AVAILABLE(sub_api);
2678 // Reset any available pipe (except control)
2679 for (i = 0; i < USB_MAXINTERFACES; i++) {
2680 winusb_handle = handle_priv->interface_handle[i].api_handle;
2681 if (HANDLE_VALID(winusb_handle)) {
2682 for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) {
2683 usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
2684 if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))
2685 usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
2686 priv->usb_interface[i].endpoint[j], windows_error_str(0));
2688 // FlushPipe seems to fail on OUT pipes
2689 if (IS_EPIN(priv->usb_interface[i].endpoint[j])
2690 && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])))
2691 usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
2692 priv->usb_interface[i].endpoint[j], windows_error_str(0));
2694 if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))
2695 usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
2696 priv->usb_interface[i].endpoint[j], windows_error_str(0));
2701 // libusbK & libusb0 have the ability to issue an actual device reset
2702 if (WinUSBX[sub_api].ResetDevice != NULL) {
2703 winusb_handle = handle_priv->interface_handle[0].api_handle;
2704 if (HANDLE_VALID(winusb_handle))
2705 WinUSBX[sub_api].ResetDevice(winusb_handle);
2708 return LIBUSB_SUCCESS;
2711 static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
2713 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2714 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
2715 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2716 PKISO_CONTEXT iso_context;
2719 if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
2720 CHECK_WINUSBX_AVAILABLE(sub_api);
2722 // for isochronous, need to copy the individual iso packet actual_lengths and statuses
2723 if ((sub_api == SUB_API_LIBUSBK) || (sub_api == SUB_API_LIBUSB0)) {
2724 // iso only supported on libusbk-based backends for now
2725 iso_context = transfer_priv->iso_context;
2726 for (i = 0; i < transfer->num_iso_packets; i++) {
2727 transfer->iso_packet_desc[i].actual_length = iso_context->IsoPackets[i].actual_length;
2728 // TODO translate USDB_STATUS codes http://msdn.microsoft.com/en-us/library/ff539136(VS.85).aspx to libusb_transfer_status
2729 //transfer->iso_packet_desc[i].status = transfer_priv->iso_context->IsoPackets[i].status;
2732 // This should only occur if backend is not set correctly or other backend isoc is partially implemented
2733 PRINT_UNSUPPORTED_API(copy_transfer_data);
2734 return LIBUSB_ERROR_NOT_SUPPORTED;
2738 itransfer->transferred += io_size;
2739 return LIBUSB_TRANSFER_COMPLETED;
2743 * Internal HID Support functions (from libusb-win32)
2744 * Note that functions that complete data transfer synchronously must return
2745 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
2747 static int _hid_get_hid_descriptor(struct hid_device_priv *dev, void *data, size_t *size);
2748 static int _hid_get_report_descriptor(struct hid_device_priv *dev, void *data, size_t *size);
2750 static int _hid_wcslen(WCHAR *str)
2754 while (str[i] && (str[i] != 0x409))
2760 static int _hid_get_device_descriptor(struct hid_device_priv *dev, void *data, size_t *size)
2762 struct libusb_device_descriptor d;
2764 d.bLength = LIBUSB_DT_DEVICE_SIZE;
2765 d.bDescriptorType = LIBUSB_DT_DEVICE;
2766 d.bcdUSB = 0x0200; /* 2.00 */
2768 d.bDeviceSubClass = 0;
2769 d.bDeviceProtocol = 0;
2770 d.bMaxPacketSize0 = 64; /* fix this! */
2771 d.idVendor = (uint16_t)dev->vid;
2772 d.idProduct = (uint16_t)dev->pid;
2773 d.bcdDevice = 0x0100;
2774 d.iManufacturer = dev->string_index[0];
2775 d.iProduct = dev->string_index[1];
2776 d.iSerialNumber = dev->string_index[2];
2777 d.bNumConfigurations = 1;
2779 if (*size > LIBUSB_DT_DEVICE_SIZE)
2780 *size = LIBUSB_DT_DEVICE_SIZE;
2781 memcpy(data, &d, *size);
2783 return LIBUSB_COMPLETED;
2786 static int _hid_get_config_descriptor(struct hid_device_priv *dev, void *data, size_t *size)
2788 char num_endpoints = 0;
2789 size_t config_total_len = 0;
2790 char tmp[HID_MAX_CONFIG_DESC_SIZE];
2791 struct libusb_config_descriptor *cd;
2792 struct libusb_interface_descriptor *id;
2793 struct libusb_hid_descriptor *hd;
2794 struct libusb_endpoint_descriptor *ed;
2797 if (dev->input_report_size)
2799 if (dev->output_report_size)
2802 config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
2803 + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
2805 cd = (struct libusb_config_descriptor *)tmp;
2806 id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
2807 hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
2808 + LIBUSB_DT_INTERFACE_SIZE);
2809 ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
2810 + LIBUSB_DT_INTERFACE_SIZE
2811 + LIBUSB_DT_HID_SIZE);
2813 cd->bLength = LIBUSB_DT_CONFIG_SIZE;
2814 cd->bDescriptorType = LIBUSB_DT_CONFIG;
2815 cd->wTotalLength = (uint16_t)config_total_len;
2816 cd->bNumInterfaces = 1;
2817 cd->bConfigurationValue = 1;
2818 cd->iConfiguration = 0;
2819 cd->bmAttributes = 1 << 7; /* bus powered */
2822 id->bLength = LIBUSB_DT_INTERFACE_SIZE;
2823 id->bDescriptorType = LIBUSB_DT_INTERFACE;
2824 id->bInterfaceNumber = 0;
2825 id->bAlternateSetting = 0;
2826 id->bNumEndpoints = num_endpoints;
2827 id->bInterfaceClass = 3;
2828 id->bInterfaceSubClass = 0;
2829 id->bInterfaceProtocol = 0;
2832 tmp_size = LIBUSB_DT_HID_SIZE;
2833 _hid_get_hid_descriptor(dev, hd, &tmp_size);
2835 if (dev->input_report_size) {
2836 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
2837 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
2838 ed->bEndpointAddress = HID_IN_EP;
2839 ed->bmAttributes = 3;
2840 ed->wMaxPacketSize = dev->input_report_size - 1;
2842 ed = (struct libusb_endpoint_descriptor *)((char *)ed + LIBUSB_DT_ENDPOINT_SIZE);
2845 if (dev->output_report_size) {
2846 ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
2847 ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
2848 ed->bEndpointAddress = HID_OUT_EP;
2849 ed->bmAttributes = 3;
2850 ed->wMaxPacketSize = dev->output_report_size - 1;
2854 if (*size > config_total_len)
2855 *size = config_total_len;
2856 memcpy(data, tmp, *size);
2858 return LIBUSB_COMPLETED;
2861 static int _hid_get_string_descriptor(struct hid_device_priv *dev, int _index,
2862 void *data, size_t *size, HANDLE hid_handle)
2865 WCHAR string[MAX_USB_STRING_LENGTH];
2866 size_t tmp_size = 0;
2869 /* language ID, EN-US */
2870 char string_langid[] = {0x09, 0x04};
2872 if ((*size < 2) || (*size > 255))
2873 return LIBUSB_ERROR_OVERFLOW;
2876 tmp = string_langid;
2877 tmp_size = sizeof(string_langid) + 2;
2879 for (i = 0; i < 3; i++) {
2880 if (_index == (dev->string_index[i])) {
2881 tmp = dev->string[i];
2882 tmp_size = (_hid_wcslen(dev->string[i]) + 1) * sizeof(WCHAR);
2888 if (!HidD_GetIndexedString(hid_handle, _index, string, sizeof(string)))
2889 return LIBUSB_ERROR_INVALID_PARAM;
2891 tmp_size = (_hid_wcslen(string) + 1) * sizeof(WCHAR);
2896 return LIBUSB_ERROR_INVALID_PARAM;
2898 if (tmp_size < *size)
2902 ((uint8_t *)data)[0] = (uint8_t)*size;
2903 ((uint8_t *)data)[1] = LIBUSB_DT_STRING;
2904 memcpy((uint8_t *)data + 2, tmp, *size - 2);
2906 return LIBUSB_COMPLETED;
2909 static int _hid_get_hid_descriptor(struct hid_device_priv *dev, void *data, size_t *size)
2911 struct libusb_hid_descriptor d;
2912 uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
2913 size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
2915 _hid_get_report_descriptor(dev, tmp, &report_len);
2917 d.bLength = LIBUSB_DT_HID_SIZE;
2918 d.bDescriptorType = LIBUSB_DT_HID;
2919 d.bcdHID = 0x0110; /* 1.10 */
2921 d.bNumDescriptors = 1;
2922 d.bClassDescriptorType = LIBUSB_DT_REPORT;
2923 d.wClassDescriptorLength = (uint16_t)report_len;
2925 if (*size > LIBUSB_DT_HID_SIZE)
2926 *size = LIBUSB_DT_HID_SIZE;
2927 memcpy(data, &d, *size);
2929 return LIBUSB_COMPLETED;
2932 static int _hid_get_report_descriptor(struct hid_device_priv *dev, void *data, size_t *size)
2934 uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
2938 d[i++] = 0x06; d[i++] = dev->usagePage & 0xFF; d[i++] = dev->usagePage >> 8;
2940 d[i++] = 0x09; d[i++] = (uint8_t)dev->usage;
2941 /* start collection (application) */
2942 d[i++] = 0xA1; d[i++] = 0x01;
2944 if (dev->input_report_size) {
2945 /* usage (vendor defined) */
2946 d[i++] = 0x09; d[i++] = 0x01;
2947 /* logical minimum (0) */
2948 d[i++] = 0x15; d[i++] = 0x00;
2949 /* logical maximum (255) */
2950 d[i++] = 0x25; d[i++] = 0xFF;
2951 /* report size (8 bits) */
2952 d[i++] = 0x75; d[i++] = 0x08;
2954 d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
2955 /* input (data, variable, absolute) */
2956 d[i++] = 0x81; d[i++] = 0x00;
2959 if (dev->output_report_size) {
2960 /* usage (vendor defined) */
2961 d[i++] = 0x09; d[i++] = 0x02;
2962 /* logical minimum (0) */
2963 d[i++] = 0x15; d[i++] = 0x00;
2964 /* logical maximum (255) */
2965 d[i++] = 0x25; d[i++] = 0xFF;
2966 /* report size (8 bits) */
2967 d[i++] = 0x75; d[i++] = 0x08;
2969 d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
2970 /* output (data, variable, absolute) */
2971 d[i++] = 0x91; d[i++] = 0x00;
2973 /* feature report */
2974 if (dev->feature_report_size) {
2975 /* usage (vendor defined) */
2976 d[i++] = 0x09; d[i++] = 0x03;
2977 /* logical minimum (0) */
2978 d[i++] = 0x15; d[i++] = 0x00;
2979 /* logical maximum (255) */
2980 d[i++] = 0x25; d[i++] = 0xFF;
2981 /* report size (8 bits) */
2982 d[i++] = 0x75; d[i++] = 0x08;
2984 d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
2985 /* feature (data, variable, absolute) */
2986 d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
2989 /* end collection */
2994 memcpy(data, d, *size);
2996 return LIBUSB_COMPLETED;
2999 static int _hid_get_descriptor(struct hid_device_priv *dev, HANDLE hid_handle, int recipient,
3000 int type, int _index, void *data, size_t *size)
3003 case LIBUSB_DT_DEVICE:
3004 usbi_dbg("LIBUSB_DT_DEVICE");
3005 return _hid_get_device_descriptor(dev, data, size);
3006 case LIBUSB_DT_CONFIG:
3007 usbi_dbg("LIBUSB_DT_CONFIG");
3009 return _hid_get_config_descriptor(dev, data, size);
3010 return LIBUSB_ERROR_INVALID_PARAM;
3011 case LIBUSB_DT_STRING:
3012 usbi_dbg("LIBUSB_DT_STRING");
3013 return _hid_get_string_descriptor(dev, _index, data, size, hid_handle);
3015 usbi_dbg("LIBUSB_DT_HID");
3017 return _hid_get_hid_descriptor(dev, data, size);
3018 return LIBUSB_ERROR_INVALID_PARAM;
3019 case LIBUSB_DT_REPORT:
3020 usbi_dbg("LIBUSB_DT_REPORT");
3022 return _hid_get_report_descriptor(dev, data, size);
3023 return LIBUSB_ERROR_INVALID_PARAM;
3024 case LIBUSB_DT_PHYSICAL:
3025 usbi_dbg("LIBUSB_DT_PHYSICAL");
3026 if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3027 return LIBUSB_COMPLETED;
3028 return LIBUSB_ERROR_OTHER;
3031 usbi_dbg("unsupported");
3032 return LIBUSB_ERROR_NOT_SUPPORTED;
3035 static int _hid_get_report(struct hid_device_priv *dev, HANDLE hid_handle, int id, void *data,
3036 struct winusb_transfer_priv *tp, size_t *size, OVERLAPPED *overlapped, int report_type)
3039 DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3040 int r = LIBUSB_SUCCESS;
3042 if (tp->hid_buffer != NULL)
3043 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3045 if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3046 usbi_dbg("invalid size (%u)", *size);
3047 return LIBUSB_ERROR_INVALID_PARAM;
3050 switch (report_type) {
3051 case HID_REPORT_TYPE_INPUT:
3052 ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3054 case HID_REPORT_TYPE_FEATURE:
3055 ioctl_code = IOCTL_HID_GET_FEATURE;
3058 usbi_dbg("unknown HID report type %d", report_type);
3059 return LIBUSB_ERROR_INVALID_PARAM;
3062 // Add a trailing byte to detect overflows
3063 buf = calloc(1, expected_size + 1);
3065 return LIBUSB_ERROR_NO_MEM;
3067 buf[0] = (uint8_t)id; // Must be set always
3068 usbi_dbg("report ID: 0x%02X", buf[0]);
3070 tp->hid_expected_size = expected_size;
3071 read_size = expected_size;
3073 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3074 if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size + 1,
3075 buf, expected_size + 1, &read_size, overlapped)) {
3076 if (GetLastError() != ERROR_IO_PENDING) {
3077 usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3079 return LIBUSB_ERROR_IO;
3081 // Asynchronous wait
3082 tp->hid_buffer = buf;
3083 tp->hid_dest = data; // copy dest, as not necessarily the start of the transfer buffer
3084 return LIBUSB_SUCCESS;
3087 // Transfer completed synchronously => copy and discard extra buffer
3088 if (read_size == 0) {
3089 usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3093 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3095 if ((size_t)read_size > expected_size) {
3096 r = LIBUSB_ERROR_OVERFLOW;
3097 usbi_dbg("OVERFLOW!");
3099 r = LIBUSB_COMPLETED;
3102 *size = MIN((size_t)read_size, *size);
3104 memcpy(data, buf + 1, *size); // Discard report ID
3106 memcpy(data, buf, *size);
3113 static int _hid_set_report(struct hid_device_priv *dev, HANDLE hid_handle, int id, void *data,
3114 struct winusb_transfer_priv *tp, size_t *size, OVERLAPPED *overlapped, int report_type)
3116 uint8_t *buf = NULL;
3117 DWORD ioctl_code, write_size = (DWORD)*size;
3118 // If an id is reported, we must allow MAX_HID_REPORT_SIZE + 1
3119 size_t max_report_size = MAX_HID_REPORT_SIZE + (id ? 1 : 0);
3121 if (tp->hid_buffer != NULL)
3122 usbi_dbg("program assertion failed: hid_buffer is not NULL");
3124 if ((*size == 0) || (*size > max_report_size)) {
3125 usbi_dbg("invalid size (%u)", *size);
3126 return LIBUSB_ERROR_INVALID_PARAM;
3129 switch (report_type) {
3130 case HID_REPORT_TYPE_OUTPUT:
3131 ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3133 case HID_REPORT_TYPE_FEATURE:
3134 ioctl_code = IOCTL_HID_SET_FEATURE;
3137 usbi_dbg("unknown HID report type %d", report_type);
3138 return LIBUSB_ERROR_INVALID_PARAM;
3141 usbi_dbg("report ID: 0x%02X", id);
3142 // When report IDs are not used (i.e. when id == 0), we must add
3143 // a null report ID. Otherwise, we just use original data buffer
3147 buf = malloc(write_size);
3149 return LIBUSB_ERROR_NO_MEM;
3153 memcpy(buf + 1, data, *size);
3155 // This seems like a waste, but if we don't duplicate the
3156 // data, we'll get issues when freeing hid_buffer
3157 memcpy(buf, data, *size);
3159 usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3162 // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3163 if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3164 buf, write_size, &write_size, overlapped)) {
3165 if (GetLastError() != ERROR_IO_PENDING) {
3166 usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3168 return LIBUSB_ERROR_IO;
3170 tp->hid_buffer = buf;
3171 tp->hid_dest = NULL;
3172 return LIBUSB_SUCCESS;
3175 // Transfer completed synchronously
3177 if (write_size == 0)
3178 usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3181 return LIBUSB_COMPLETED;
3184 static int _hid_class_request(struct hid_device_priv *dev, HANDLE hid_handle, int request_type,
3185 int request, int value, int _index, void *data, struct winusb_transfer_priv *tp,
3186 size_t *size, OVERLAPPED *overlapped)
3188 int report_type = (value >> 8) & 0xFF;
3189 int report_id = value & 0xFF;
3191 if ((LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3192 && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE))
3193 return LIBUSB_ERROR_INVALID_PARAM;
3195 if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3196 return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3198 if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3199 return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3201 return LIBUSB_ERROR_INVALID_PARAM;
3208 static int hid_init(struct libusb_context *ctx)
3210 DLL_GET_HANDLE(hid);
3212 DLL_LOAD_FUNC(hid, HidD_GetAttributes, TRUE);
3213 DLL_LOAD_FUNC(hid, HidD_GetHidGuid, TRUE);
3214 DLL_LOAD_FUNC(hid, HidD_GetPreparsedData, TRUE);
3215 DLL_LOAD_FUNC(hid, HidD_FreePreparsedData, TRUE);
3216 DLL_LOAD_FUNC(hid, HidD_GetManufacturerString, TRUE);
3217 DLL_LOAD_FUNC(hid, HidD_GetProductString, TRUE);
3218 DLL_LOAD_FUNC(hid, HidD_GetSerialNumberString, TRUE);
3219 DLL_LOAD_FUNC(hid, HidD_GetIndexedString, TRUE);
3220 DLL_LOAD_FUNC(hid, HidP_GetCaps, TRUE);
3221 DLL_LOAD_FUNC(hid, HidD_SetNumInputBuffers, TRUE);
3222 DLL_LOAD_FUNC(hid, HidD_GetPhysicalDescriptor, TRUE);
3223 DLL_LOAD_FUNC(hid, HidD_FlushQueue, TRUE);
3224 DLL_LOAD_FUNC(hid, HidP_GetValueCaps, TRUE);
3226 api_hid_available = true;
3227 return LIBUSB_SUCCESS;
3230 static void hid_exit(void)
3232 DLL_FREE_HANDLE(hid);
3235 // NB: open and close must ensure that they only handle interface of
3236 // the right API type, as these functions can be called wholesale from
3237 // composite_open(), with interfaces belonging to different APIs
3238 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3240 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3241 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3242 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3243 HIDD_ATTRIBUTES hid_attributes;
3244 PHIDP_PREPARSED_DATA preparsed_data = NULL;
3245 HIDP_CAPS capabilities;
3246 HIDP_VALUE_CAPS *value_caps;
3247 HANDLE hid_handle = INVALID_HANDLE_VALUE;
3249 // report IDs handling
3251 int nb_ids[2]; // zero and nonzero report IDs
3252 #if defined(ENABLE_LOGGING)
3253 const char * const type[3] = {"input", "output", "feature"};
3256 CHECK_HID_AVAILABLE;
3258 if (priv->hid == NULL) {
3259 usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3260 return LIBUSB_ERROR_NOT_FOUND;
3263 for (i = 0; i < USB_MAXINTERFACES; i++) {
3264 if ((priv->usb_interface[i].path != NULL)
3265 && (priv->usb_interface[i].apib->id == USB_API_HID)) {
3266 hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3267 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3269 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3270 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3271 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3272 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3273 * HidD_GetFeature (if the device supports Feature reports)."
3275 if (hid_handle == INVALID_HANDLE_VALUE) {
3276 usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3277 hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3278 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3279 if (hid_handle == INVALID_HANDLE_VALUE) {
3280 usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3281 switch (GetLastError()) {
3282 case ERROR_FILE_NOT_FOUND: // The device was disconnected
3283 return LIBUSB_ERROR_NO_DEVICE;
3284 case ERROR_ACCESS_DENIED:
3285 return LIBUSB_ERROR_ACCESS;
3287 return LIBUSB_ERROR_IO;
3290 priv->usb_interface[i].restricted_functionality = true;
3292 handle_priv->interface_handle[i].api_handle = hid_handle;
3296 hid_attributes.Size = sizeof(hid_attributes);
3298 if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3299 usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3303 priv->hid->vid = hid_attributes.VendorID;
3304 priv->hid->pid = hid_attributes.ProductID;
3306 // Set the maximum available input buffer size
3307 for (i = 32; HidD_SetNumInputBuffers(hid_handle, i); i *= 2);
3308 usbi_dbg("set maximum input buffer size to %d", i / 2);
3310 // Get the maximum input and output report size
3311 if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3312 usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3315 if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3316 usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3320 // Find out if interrupt will need report IDs
3321 size[0] = capabilities.NumberInputValueCaps;
3322 size[1] = capabilities.NumberOutputValueCaps;
3323 size[2] = capabilities.NumberFeatureValueCaps;
3324 for (j = HidP_Input; j <= HidP_Feature; j++) {
3325 usbi_dbg("%u HID %s report value(s) found", (unsigned int)size[j], type[j]);
3326 priv->hid->uses_report_ids[j] = false;
3328 value_caps = calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3329 if ((value_caps != NULL)
3330 && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3331 && (size[j] >= 1)) {
3334 for (i = 0; i < (int)size[j]; i++) {
3335 usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3336 if (value_caps[i].ReportID != 0)
3341 if (nb_ids[1] != 0) {
3343 usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3345 priv->hid->uses_report_ids[j] = true;
3348 usbi_warn(ctx, " could not process %s report IDs", type[j]);
3354 // Set the report sizes
3355 priv->hid->input_report_size = capabilities.InputReportByteLength;
3356 priv->hid->output_report_size = capabilities.OutputReportByteLength;
3357 priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3359 // Store usage and usagePage values
3360 priv->hid->usage = capabilities.Usage;
3361 priv->hid->usagePage = capabilities.UsagePage;
3363 // Fetch string descriptors
3364 priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3365 if (priv->hid->string_index[0] != 0)
3366 HidD_GetManufacturerString(hid_handle, priv->hid->string[0], sizeof(priv->hid->string[0]));
3368 priv->hid->string[0][0] = 0;
3370 priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3371 if (priv->hid->string_index[1] != 0)
3372 HidD_GetProductString(hid_handle, priv->hid->string[1], sizeof(priv->hid->string[1]));
3374 priv->hid->string[1][0] = 0;
3376 priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3377 if (priv->hid->string_index[2] != 0)
3378 HidD_GetSerialNumberString(hid_handle, priv->hid->string[2], sizeof(priv->hid->string[2]));
3380 priv->hid->string[2][0] = 0;
3384 HidD_FreePreparsedData(preparsed_data);
3386 return LIBUSB_SUCCESS;
3389 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3391 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3392 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3396 if (!api_hid_available)
3399 for (i = 0; i < USB_MAXINTERFACES; i++) {
3400 if (priv->usb_interface[i].apib->id == USB_API_HID) {
3401 file_handle = handle_priv->interface_handle[i].api_handle;
3402 if (HANDLE_VALID(file_handle))
3403 CloseHandle(file_handle);
3408 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3410 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3411 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3413 CHECK_HID_AVAILABLE;
3415 // NB: Disconnection detection is not possible in this function
3416 if (priv->usb_interface[iface].path == NULL)
3417 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3419 // We use dev_handle as a flag for interface claimed
3420 if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED)
3421 return LIBUSB_ERROR_BUSY; // already claimed
3423 handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
3425 usbi_dbg("claimed interface %d", iface);
3426 handle_priv->active_interface = iface;
3428 return LIBUSB_SUCCESS;
3431 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3433 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3434 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3436 CHECK_HID_AVAILABLE;
3438 if (priv->usb_interface[iface].path == NULL)
3439 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3441 if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED)
3442 return LIBUSB_ERROR_NOT_FOUND; // invalid iface
3444 handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
3446 return LIBUSB_SUCCESS;
3449 static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3451 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3453 CHECK_HID_AVAILABLE;
3455 if (altsetting > 255)
3456 return LIBUSB_ERROR_INVALID_PARAM;
3458 if (altsetting != 0) {
3459 usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
3460 return LIBUSB_ERROR_NOT_SUPPORTED;
3463 return LIBUSB_SUCCESS;
3466 static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3468 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3469 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
3470 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3471 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3472 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3473 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer;
3475 OVERLAPPED *overlapped;
3476 int current_interface, config;
3478 int r = LIBUSB_ERROR_INVALID_PARAM;
3480 CHECK_HID_AVAILABLE;
3482 safe_free(transfer_priv->hid_buffer);
3483 transfer_priv->hid_dest = NULL;
3484 size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3486 if (size > MAX_CTRL_BUFFER_LENGTH)
3487 return LIBUSB_ERROR_INVALID_PARAM;
3489 current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
3490 if (current_interface < 0) {
3491 if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS)
3492 return LIBUSB_ERROR_NOT_FOUND;
3495 usbi_dbg("will use interface %d", current_interface);
3497 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3498 overlapped = transfer_priv->pollable_fd.overlapped;
3500 switch (LIBUSB_REQ_TYPE(setup->RequestType)) {
3501 case LIBUSB_REQUEST_TYPE_STANDARD:
3502 switch (setup->Request) {
3503 case LIBUSB_REQUEST_GET_DESCRIPTOR:
3504 r = _hid_get_descriptor(priv->hid, hid_handle, LIBUSB_REQ_RECIPIENT(setup->RequestType),
3505 (setup->Value >> 8) & 0xFF, setup->Value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
3507 case LIBUSB_REQUEST_GET_CONFIGURATION:
3508 r = winusb_get_configuration(transfer->dev_handle, &config);
3509 if (r == LIBUSB_SUCCESS) {
3511 ((uint8_t *)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
3512 r = LIBUSB_COMPLETED;
3515 case LIBUSB_REQUEST_SET_CONFIGURATION:
3516 if (setup->Value == priv->active_config) {
3517 r = LIBUSB_COMPLETED;
3519 usbi_warn(ctx, "cannot set configuration other than the default one");
3520 r = LIBUSB_ERROR_NOT_SUPPORTED;
3523 case LIBUSB_REQUEST_GET_INTERFACE:
3525 ((uint8_t *)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
3526 r = LIBUSB_COMPLETED;
3528 case LIBUSB_REQUEST_SET_INTERFACE:
3529 r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->Index, setup->Value);
3530 if (r == LIBUSB_SUCCESS)
3531 r = LIBUSB_COMPLETED;
3534 usbi_warn(ctx, "unsupported HID control request");
3535 return LIBUSB_ERROR_NOT_SUPPORTED;
3538 case LIBUSB_REQUEST_TYPE_CLASS:
3539 r = _hid_class_request(priv->hid, hid_handle, setup->RequestType, setup->Request, setup->Value,
3540 setup->Index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
3544 usbi_warn(ctx, "unsupported HID control request");
3545 return LIBUSB_ERROR_NOT_SUPPORTED;
3551 if (r == LIBUSB_COMPLETED) {
3552 // Force request to be completed synchronously. Transferred size has been set by previous call
3553 windows_force_sync_completion(overlapped, (ULONG)size);
3557 transfer_priv->interface_number = (uint8_t)current_interface;
3559 return LIBUSB_SUCCESS;
3562 static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
3564 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3565 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
3566 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3567 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3568 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3570 OVERLAPPED *overlapped;
3571 bool direction_in, ret;
3572 int current_interface, length;
3574 int r = LIBUSB_SUCCESS;
3576 CHECK_HID_AVAILABLE;
3578 transfer_priv->hid_dest = NULL;
3579 safe_free(transfer_priv->hid_buffer);
3581 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3582 if (current_interface < 0) {
3583 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3584 return LIBUSB_ERROR_NOT_FOUND;
3587 usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3589 transfer_priv->handle = hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3590 overlapped = transfer_priv->pollable_fd.overlapped;
3591 direction_in = IS_XFERIN(transfer);
3593 // If report IDs are not in use, an extra prefix byte must be added
3594 if (((direction_in) && (!priv->hid->uses_report_ids[0]))
3595 || ((!direction_in) && (!priv->hid->uses_report_ids[1])))
3596 length = transfer->length + 1;
3598 length = transfer->length;
3600 // Add a trailing byte to detect overflows on input
3601 transfer_priv->hid_buffer = calloc(1, length + 1);
3602 if (transfer_priv->hid_buffer == NULL)
3603 return LIBUSB_ERROR_NO_MEM;
3605 transfer_priv->hid_expected_size = length;
3608 transfer_priv->hid_dest = transfer->buffer;
3609 usbi_dbg("reading %d bytes (report ID: 0x00)", length);
3610 ret = ReadFile(hid_handle, transfer_priv->hid_buffer, length + 1, &size, overlapped);
3612 if (!priv->hid->uses_report_ids[1])
3613 memcpy(transfer_priv->hid_buffer + 1, transfer->buffer, transfer->length);
3615 // We could actually do without the calloc and memcpy in this case
3616 memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
3618 usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
3619 ret = WriteFile(hid_handle, transfer_priv->hid_buffer, length, &size, overlapped);
3623 if (GetLastError() != ERROR_IO_PENDING) {
3624 usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
3625 safe_free(transfer_priv->hid_buffer);
3626 return LIBUSB_ERROR_IO;
3629 // Only write operations that completed synchronously need to free up
3630 // hid_buffer. For reads, copy_transfer_data() handles that process.
3632 safe_free(transfer_priv->hid_buffer);
3635 usbi_err(ctx, "program assertion failed - no data was transferred");
3638 if (size > (size_t)length) {
3639 usbi_err(ctx, "OVERFLOW!");
3640 r = LIBUSB_ERROR_OVERFLOW;
3642 windows_force_sync_completion(overlapped, (ULONG)size);
3645 transfer_priv->interface_number = (uint8_t)current_interface;
3650 static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3652 struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
3653 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3654 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
3655 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3657 int current_interface;
3659 CHECK_HID_AVAILABLE;
3661 current_interface = transfer_priv->interface_number;
3662 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3663 usbi_err(ctx, "program assertion failed: invalid interface_number");
3664 return LIBUSB_ERROR_NOT_FOUND;
3666 usbi_dbg("will use interface %d", current_interface);
3668 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3670 if (pCancelIoEx != NULL) {
3671 // Use CancelIoEx if available to cancel just a single transfer
3672 if (pCancelIoEx(hid_handle, transfer_priv->pollable_fd.overlapped))
3673 return LIBUSB_SUCCESS;
3675 if (CancelIo(hid_handle))
3676 return LIBUSB_SUCCESS;
3679 usbi_warn(ctx, "cancel failed: %s", windows_error_str(0));
3680 return LIBUSB_ERROR_NOT_FOUND;
3683 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3685 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3687 int current_interface;
3689 CHECK_HID_AVAILABLE;
3691 // Flushing the queues on all interfaces is the best we can achieve
3692 for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
3693 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3694 if (HANDLE_VALID(hid_handle))
3695 HidD_FlushQueue(hid_handle);
3698 return LIBUSB_SUCCESS;
3701 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3703 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3704 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3705 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3707 int current_interface;
3709 CHECK_HID_AVAILABLE;
3711 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3712 if (current_interface < 0) {
3713 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3714 return LIBUSB_ERROR_NOT_FOUND;
3717 usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3718 hid_handle = handle_priv->interface_handle[current_interface].api_handle;
3720 // No endpoint selection with Microsoft's implementation, so we try to flush the
3721 // whole interface. Should be OK for most case scenarios
3722 if (!HidD_FlushQueue(hid_handle)) {
3723 usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
3724 // Device was probably disconnected
3725 return LIBUSB_ERROR_NO_DEVICE;
3728 return LIBUSB_SUCCESS;
3731 // This extra function is only needed for HID
3732 static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3734 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3735 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3736 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
3737 int r = LIBUSB_TRANSFER_COMPLETED;
3738 uint32_t corrected_size = io_size;
3740 if (transfer_priv->hid_buffer != NULL) {
3741 // If we have a valid hid_buffer, it means the transfer was async
3742 if (transfer_priv->hid_dest != NULL) { // Data readout
3743 if (corrected_size > 0) {
3744 // First, check for overflow
3745 if (corrected_size > transfer_priv->hid_expected_size) {
3746 usbi_err(ctx, "OVERFLOW!");
3747 corrected_size = (uint32_t)transfer_priv->hid_expected_size;
3748 r = LIBUSB_TRANSFER_OVERFLOW;
3751 if (transfer_priv->hid_buffer[0] == 0) {
3752 // Discard the 1 byte report ID prefix
3754 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer + 1, corrected_size);
3756 memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
3759 transfer_priv->hid_dest = NULL;
3761 // For write, we just need to free the hid buffer
3762 safe_free(transfer_priv->hid_buffer);
3765 itransfer->transferred += corrected_size;
3771 * Composite API functions
3773 static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
3775 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3776 int r = LIBUSB_ERROR_NOT_FOUND;
3778 // SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID
3779 bool available[SUB_API_MAX + 1] = { 0 };
3781 for (i = 0; i < USB_MAXINTERFACES; i++) {
3782 switch (priv->usb_interface[i].apib->id) {
3783 case USB_API_WINUSBX:
3784 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
3785 available[priv->usb_interface[i].sub_api] = true;
3788 available[SUB_API_MAX] = true;
3795 for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers
3797 r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
3798 if (r != LIBUSB_SUCCESS)
3803 if (available[SUB_API_MAX]) // HID driver
3804 r = hid_open(SUB_API_NOTSET, dev_handle);
3809 static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
3811 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3813 // SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID
3814 bool available[SUB_API_MAX + 1] = { 0 };
3816 for (i = 0; i < USB_MAXINTERFACES; i++) {
3817 switch (priv->usb_interface[i].apib->id) {
3818 case USB_API_WINUSBX:
3819 if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
3820 available[priv->usb_interface[i].sub_api] = true;
3823 available[SUB_API_MAX] = true;
3830 for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers
3832 usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
3835 if (available[SUB_API_MAX]) // HID driver
3836 hid_close(SUB_API_NOTSET, dev_handle);
3839 static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3841 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3843 CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, claim_interface);
3845 return priv->usb_interface[iface].apib->
3846 claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
3849 static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3851 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3853 CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, set_interface_altsetting);
3855 return priv->usb_interface[iface].apib->
3856 set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
3859 static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
3861 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3863 CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, release_interface);
3865 return priv->usb_interface[iface].apib->
3866 release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
3869 static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3871 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3872 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3873 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3874 struct libusb_config_descriptor *conf_desc;
3875 WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer;
3878 // Interface shouldn't matter for control, but it does in practice, with Windows'
3879 // restrictions with regards to accessing HID keyboards and mice. Try to target
3880 // a specific interface first, if possible.
3881 switch (LIBUSB_REQ_RECIPIENT(setup->RequestType)) {
3882 case LIBUSB_RECIPIENT_INTERFACE:
3883 iface = setup->Index & 0xFF;
3885 case LIBUSB_RECIPIENT_ENDPOINT:
3886 r = libusb_get_active_config_descriptor(transfer->dev_handle->dev, &conf_desc);
3887 if (r == LIBUSB_SUCCESS) {
3888 iface = get_interface_by_endpoint(conf_desc, (setup->Index & 0xFF));
3889 libusb_free_config_descriptor(conf_desc);
3892 // Fall through if not able to determine interface
3898 // Try and target a specific interface if the control setup indicates such
3899 if ((iface >= 0) && (iface < USB_MAXINTERFACES)) {
3900 usbi_dbg("attempting control transfer targeted to interface %d", iface);
3901 if ((priv->usb_interface[iface].path != NULL)
3902 && (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) {
3903 r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
3904 if (r == LIBUSB_SUCCESS)
3909 // Either not targeted to a specific interface or no luck in doing so.
3910 // Try a 2 pass approach with all interfaces.
3911 for (pass = 0; pass < 2; pass++) {
3912 for (iface = 0; iface < USB_MAXINTERFACES; iface++) {
3913 if ((priv->usb_interface[iface].path != NULL)
3914 && (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) {
3915 if ((pass == 0) && (priv->usb_interface[iface].restricted_functionality)) {
3916 usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", iface);
3919 usbi_dbg("using interface %d", iface);
3920 r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
3921 // If not supported on this API, it may be supported on another, so don't give up yet!!
3922 if (r == LIBUSB_ERROR_NOT_SUPPORTED)
3929 usbi_err(ctx, "no libusb supported interfaces to complete request");
3930 return LIBUSB_ERROR_NOT_FOUND;
3933 static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
3934 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3935 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3936 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3937 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3938 int current_interface;
3940 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3941 if (current_interface < 0) {
3942 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3943 return LIBUSB_ERROR_NOT_FOUND;
3946 CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, submit_bulk_transfer);
3948 return priv->usb_interface[current_interface].apib->
3949 submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);
3952 static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
3953 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3954 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3955 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3956 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3957 int current_interface;
3959 current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3960 if (current_interface < 0) {
3961 usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3962 return LIBUSB_ERROR_NOT_FOUND;
3965 CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, submit_iso_transfer);
3967 return priv->usb_interface[current_interface].apib->
3968 submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);
3971 static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3973 struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3974 struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3975 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
3976 int current_interface;
3978 current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3979 if (current_interface < 0) {
3980 usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3981 return LIBUSB_ERROR_NOT_FOUND;
3984 CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, clear_halt);
3986 return priv->usb_interface[current_interface].apib->
3987 clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);
3990 static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
3992 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3993 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
3994 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3995 int current_interface = transfer_priv->interface_number;
3997 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3998 usbi_err(TRANSFER_CTX(transfer), "program assertion failed: invalid interface_number");
3999 return LIBUSB_ERROR_NOT_FOUND;
4002 CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, abort_control);
4004 return priv->usb_interface[current_interface].apib->
4005 abort_control(priv->usb_interface[current_interface].sub_api, itransfer);
4008 static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4010 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4011 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4012 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4013 int current_interface = transfer_priv->interface_number;
4015 if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
4016 usbi_err(TRANSFER_CTX(transfer), "program assertion failed: invalid interface_number");
4017 return LIBUSB_ERROR_NOT_FOUND;
4020 CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, abort_transfers);
4022 return priv->usb_interface[current_interface].apib->
4023 abort_transfers(priv->usb_interface[current_interface].sub_api, itransfer);
4026 static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4028 struct winusb_device_priv *priv = _device_priv(dev_handle->dev);
4031 bool available[SUB_API_MAX];
4033 for (i = 0; i < SUB_API_MAX; i++)
4034 available[i] = false;
4036 for (i = 0; i < USB_MAXINTERFACES; i++) {
4037 if ((priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4038 && (priv->usb_interface[i].sub_api != SUB_API_NOTSET))
4039 available[priv->usb_interface[i].sub_api] = true;
4042 for (i = 0; i < SUB_API_MAX; i++) {
4044 r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4045 if (r != LIBUSB_SUCCESS)
4050 return LIBUSB_SUCCESS;
4053 static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4055 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4056 struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4057 struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4058 int current_interface = transfer_priv->interface_number;
4060 CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, copy_transfer_data);
4062 return priv->usb_interface[current_interface].apib->
4063 copy_transfer_data(priv->usb_interface[current_interface].sub_api, itransfer, io_size);