/*
 * windows backend for libusb 1.0
 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
 * Copyright © 2016-2018 Chris Dickens <christopher.a.dickens@gmail.com>
 * With contributions from Michael Plante, Orin Eman et al.
 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
 * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
 * Hash table functions adapted from glibc, by Ulrich Drepper et al.
 * Major code testing contribution by Xiaofan Chen
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <config.h>

#include <windows.h>
#include <setupapi.h>
#include <ctype.h>
#include <stdio.h>

#include "libusbi.h"
#include "windows_winusb.h"

#define HANDLE_VALID(h) (((h) != NULL) && ((h) != INVALID_HANDLE_VALUE))

// The below macro is used in conjunction with safe loops.
#define LOOP_BREAK(err)				\
	{					\
		r = err;			\
		continue;			\
	}

// WinUSB-like API prototypes
static bool winusbx_init(struct libusb_context *ctx);
static void winusbx_exit(void);
static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle);
static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle);
static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting);
static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
static int winusbx_cancel_transfer(int sub_api, struct usbi_transfer *itransfer);
static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
static enum libusb_transfer_status winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length);
// HID API prototypes
static bool hid_init(struct libusb_context *ctx);
static void hid_exit(void);
static int hid_open(int sub_api, struct libusb_device_handle *dev_handle);
static void hid_close(int sub_api, struct libusb_device_handle *dev_handle);
static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting);
static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
static enum libusb_transfer_status hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length);
// Composite API prototypes
static int composite_open(int sub_api, struct libusb_device_handle *dev_handle);
static void composite_close(int sub_api, struct libusb_device_handle *dev_handle);
static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting);
static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
static int composite_cancel_transfer(int sub_api, struct usbi_transfer *itransfer);
static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
static enum libusb_transfer_status composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length);

static usbi_mutex_t autoclaim_lock;

// API globals
static struct winusb_interface WinUSBX[SUB_API_MAX];
#define CHECK_WINUSBX_AVAILABLE(sub_api)		\
	do {						\
		if (sub_api == SUB_API_NOTSET)		\
			sub_api = priv->sub_api;	\
		if (WinUSBX[sub_api].hDll == NULL)	\
			return LIBUSB_ERROR_ACCESS;	\
	} while (0)

#define CHECK_HID_AVAILABLE				\
	do {						\
		if (DLL_HANDLE_NAME(hid) == NULL)	\
			return LIBUSB_ERROR_ACCESS;	\
	} while (0)

#if defined(ENABLE_LOGGING)
static const char *guid_to_string(const GUID *guid, char guid_string[MAX_GUID_STRING_LENGTH])
{
	if (guid == NULL) {
		guid_string[0] = '\0';
		return guid_string;
	}

	sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
		(unsigned int)guid->Data1, guid->Data2, guid->Data3,
		guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
		guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);

	return guid_string;
}
#endif

static bool string_to_guid(const char guid_string[MAX_GUID_STRING_LENGTH], GUID *guid)
{
	unsigned short tmp[4];
	int num_chars = -1;
	char extra;
	int r;

	// Unfortunately MinGW complains that '%hhx' is not a valid format specifier,
	// even though Visual Studio 2013 and later support it. Rather than complicating
	// the logic in this function with '#ifdef's, use a temporary array on the stack
	// to store the conversions.
	r = sscanf(guid_string, "{%8x-%4hx-%4hx-%4hx-%4hx%4hx%4hx}%n%c",
		(unsigned int *)&guid->Data1, &guid->Data2, &guid->Data3,
		&tmp[0], &tmp[1], &tmp[2], &tmp[3], &num_chars, &extra);

	if ((r != 7) || (num_chars != 38))
		return false;

	// Extract the bytes from the 2-byte shorts
	guid->Data4[0] = (unsigned char)((tmp[0] >> 8) & 0xFF);
	guid->Data4[1] = (unsigned char)(tmp[0] & 0xFF);
	guid->Data4[2] = (unsigned char)((tmp[1] >> 8) & 0xFF);
	guid->Data4[3] = (unsigned char)(tmp[1] & 0xFF);
	guid->Data4[4] = (unsigned char)((tmp[2] >> 8) & 0xFF);
	guid->Data4[5] = (unsigned char)(tmp[2] & 0xFF);
	guid->Data4[6] = (unsigned char)((tmp[3] >> 8) & 0xFF);
	guid->Data4[7] = (unsigned char)(tmp[3] & 0xFF);

	return true;
}

/*
 * Normalize Microsoft's paths: return a duplicate of the given path
 * with all characters converted to uppercase
 */
static char *normalize_path(const char *path)
{
	char *ret_path = _strdup(path);
	char *p;

	if (ret_path == NULL)
		return NULL;

	for (p = ret_path; *p != '\0'; p++)
		*p = (char)toupper((unsigned char)*p);

	return ret_path;
}

/*
 * Cfgmgr32, AdvAPI32, OLE32 and SetupAPI DLL functions
 */
static bool init_dlls(struct libusb_context *ctx)
{
	DLL_GET_HANDLE(ctx, Cfgmgr32);
	DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Parent, true);
	DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Child, true);

	// Prefixed to avoid conflict with header files
	DLL_GET_HANDLE(ctx, AdvAPI32);
	DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegQueryValueExA, true);
	DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegCloseKey, true);

	DLL_GET_HANDLE(ctx, SetupAPI);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetClassDevsA, true);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInfo, true);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInterfaces, true);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInstanceIdA, true);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInterfaceDetailA, true);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceRegistryPropertyA, true);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiDestroyDeviceInfoList, true);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDevRegKey, true);
	DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDeviceInterfaceRegKey, true);

	return true;
}

static void exit_dlls(void)
{
	DLL_FREE_HANDLE(SetupAPI);
	DLL_FREE_HANDLE(AdvAPI32);
	DLL_FREE_HANDLE(Cfgmgr32);
}

/*
 * enumerate interfaces for the whole USB class
 *
 * Parameters:
 * dev_info: a pointer to a dev_info list
 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
 * enumerator: the generic USB class for which to retrieve interface details
 * index: zero based index of the interface in the device info list
 *
 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
 * structure returned and call this function repeatedly using the same guid (with an
 * incremented index starting at zero) until all interfaces have been returned.
 */
static bool get_devinfo_data(struct libusb_context *ctx,
	HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char *enumerator, unsigned _index)
{
	if (_index == 0) {
		*dev_info = pSetupDiGetClassDevsA(NULL, enumerator, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
		if (*dev_info == INVALID_HANDLE_VALUE) {
			usbi_err(ctx, "could not obtain device info set for PnP enumerator '%s': %s",
				enumerator, windows_error_str(0));
			return false;
		}
	}

	dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
	if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
		if (GetLastError() != ERROR_NO_MORE_ITEMS)
			usbi_err(ctx, "could not obtain device info data for PnP enumerator '%s' index %u: %s",
				enumerator, _index, windows_error_str(0));

		pSetupDiDestroyDeviceInfoList(*dev_info);
		*dev_info = INVALID_HANDLE_VALUE;
		return false;
	}
	return true;
}

/*
 * enumerate interfaces for a specific GUID
 *
 * Parameters:
 * dev_info: a pointer to a dev_info list
 * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
 * guid: the GUID for which to retrieve interface details
 * index: zero based index of the interface in the device info list
 *
 * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
 * structure returned and call this function repeatedly using the same guid (with an
 * incremented index starting at zero) until all interfaces have been returned.
 */
static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
	PSP_DEVINFO_DATA dev_info_data, LPCGUID guid, DWORD *_index, char **dev_interface_path)
{
	SP_DEVICE_INTERFACE_DATA dev_interface_data;
	PSP_DEVICE_INTERFACE_DETAIL_DATA_A dev_interface_details;
	char guid_string[MAX_GUID_STRING_LENGTH];
	DWORD size;

	dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
	dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	for (;;) {
		if (!pSetupDiEnumDeviceInfo(dev_info, *_index, dev_info_data)) {
			if (GetLastError() != ERROR_NO_MORE_ITEMS) {
				usbi_err(ctx, "Could not obtain device info data for %s index %lu: %s",
					guid_to_string(guid, guid_string), ULONG_CAST(*_index), windows_error_str(0));
				return LIBUSB_ERROR_OTHER;
			}

			// No more devices
			return LIBUSB_SUCCESS;
		}

		// Always advance the index for the next iteration
		(*_index)++;

		if (pSetupDiEnumDeviceInterfaces(dev_info, dev_info_data, guid, 0, &dev_interface_data))
			break;

		if (GetLastError() != ERROR_NO_MORE_ITEMS) {
			usbi_err(ctx, "Could not obtain interface data for %s devInst %lX: %s",
				guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
			return LIBUSB_ERROR_OTHER;
		}

		// Device does not have an interface matching this GUID, skip
	}

	// Read interface data (dummy + actual) to access the device path
	if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
		// The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
			usbi_err(ctx, "could not access interface data (dummy) for %s devInst %lX: %s",
				guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
			return LIBUSB_ERROR_OTHER;
		}
	} else {
		usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong");
		return LIBUSB_ERROR_OTHER;
	}

	dev_interface_details = malloc(size);
	if (dev_interface_details == NULL) {
		usbi_err(ctx, "could not allocate interface data for %s devInst %lX",
			guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst));
		return LIBUSB_ERROR_NO_MEM;
	}

	dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
	if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data,
		dev_interface_details, size, NULL, NULL)) {
		usbi_err(ctx, "could not access interface data (actual) for %s devInst %lX: %s",
			guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
		free(dev_interface_details);
		return LIBUSB_ERROR_OTHER;
	}

	*dev_interface_path = normalize_path(dev_interface_details->DevicePath);
	free(dev_interface_details);

	if (*dev_interface_path == NULL) {
		usbi_err(ctx, "could not allocate interface path for %s devInst %lX",
			guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst));
		return LIBUSB_ERROR_NO_MEM;
	}

	return LIBUSB_SUCCESS;
}

/* For libusb0 filter */
static int get_interface_details_filter(struct libusb_context *ctx, HDEVINFO *dev_info,
	DWORD _index, char *filter_path, char **dev_interface_path)
{
	const GUID *libusb0_guid = &GUID_DEVINTERFACE_LIBUSB0_FILTER;
	SP_DEVICE_INTERFACE_DATA dev_interface_data;
	PSP_DEVICE_INTERFACE_DETAIL_DATA_A dev_interface_details;
	HKEY hkey_dev_interface;
	DWORD size;
	int err = LIBUSB_ERROR_OTHER;

	if (_index == 0) {
		*dev_info = pSetupDiGetClassDevsA(libusb0_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
		if (*dev_info == INVALID_HANDLE_VALUE) {
			usbi_err(ctx, "could not obtain device info set: %s", windows_error_str(0));
			return LIBUSB_ERROR_OTHER;
		}
	}

	dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, libusb0_guid, _index, &dev_interface_data)) {
		if (GetLastError() != ERROR_NO_MORE_ITEMS) {
			usbi_err(ctx, "Could not obtain interface data for index %lu: %s",
				ULONG_CAST(_index), windows_error_str(0));
			goto err_exit;
		}

		pSetupDiDestroyDeviceInfoList(*dev_info);
		*dev_info = INVALID_HANDLE_VALUE;
		return LIBUSB_SUCCESS;
	}

	// Read interface data (dummy + actual) to access the device path
	if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
		// The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
			usbi_err(ctx, "could not access interface data (dummy) for index %lu: %s",
				ULONG_CAST(_index), windows_error_str(0));
			goto err_exit;
		}
	} else {
		usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong");
		goto err_exit;
	}

	dev_interface_details = malloc(size);
	if (dev_interface_details == NULL) {
		usbi_err(ctx, "could not allocate interface data for index %lu", ULONG_CAST(_index));
		err = LIBUSB_ERROR_NO_MEM;
		goto err_exit;
	}

	dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
	if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, dev_interface_details, size, NULL, NULL)) {
		usbi_err(ctx, "could not access interface data (actual) for index %lu: %s",
			ULONG_CAST(_index), windows_error_str(0));
		free(dev_interface_details);
		goto err_exit;
	}

	*dev_interface_path = normalize_path(dev_interface_details->DevicePath);
	free(dev_interface_details);

	if (*dev_interface_path == NULL) {
		usbi_err(ctx, "could not allocate interface path for index %lu", ULONG_CAST(_index));
		err = LIBUSB_ERROR_NO_MEM;
		goto err_exit;
	}

	// [trobinso] lookup the libusb0 symbolic index.
	hkey_dev_interface = pSetupDiOpenDeviceInterfaceRegKey(*dev_info, &dev_interface_data, 0, KEY_READ);
	if (hkey_dev_interface != INVALID_HANDLE_VALUE) {
		DWORD libusb0_symboliclink_index = 0;
		DWORD value_length = sizeof(DWORD);
		LONG status;

		status = pRegQueryValueExA(hkey_dev_interface, "LUsb0", NULL, NULL,
			(LPBYTE)&libusb0_symboliclink_index, &value_length);
		if (status == ERROR_SUCCESS) {
			if (libusb0_symboliclink_index < 256) {
				// libusb0.sys is connected to this device instance.
				// If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
				sprintf(filter_path, "\\\\.\\libusb0-%04u", (unsigned int)libusb0_symboliclink_index);
				usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
			} else {
				// libusb0.sys was connected to this device instance at one time; but not anymore.
			}
		}
		pRegCloseKey(hkey_dev_interface);
	} else {
		usbi_warn(ctx, "could not open device interface registry key for index %lu: %s",
			ULONG_CAST(_index), windows_error_str(0));
		// TODO: should this be an error?
	}

	return LIBUSB_SUCCESS;

err_exit:
	pSetupDiDestroyDeviceInfoList(*dev_info);
	*dev_info = INVALID_HANDLE_VALUE;
	return err;
}

/*
 * Returns the first known ancestor of a device
 */
static struct libusb_device *get_ancestor(struct libusb_context *ctx,
	DEVINST devinst, PDEVINST _parent_devinst)
{
	struct libusb_device *dev = NULL;
	DEVINST parent_devinst;

	while (dev == NULL) {
		if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS)
			break;
		devinst = parent_devinst;
		dev = usbi_get_device_by_session_id(ctx, (unsigned long)devinst);
	}

	if ((dev != NULL) && (_parent_devinst != NULL))
		*_parent_devinst = devinst;

	return dev;
}

/*
 * Determine which interface the given endpoint address belongs to
 */
static int get_interface_by_endpoint(struct libusb_config_descriptor *conf_desc, uint8_t ep)
{
	const struct libusb_interface *intf;
	const struct libusb_interface_descriptor *intf_desc;
	uint8_t i, k;
	int j;

	for (i = 0; i < conf_desc->bNumInterfaces; i++) {
		intf = &conf_desc->interface[i];
		for (j = 0; j < intf->num_altsetting; j++) {
			intf_desc = &intf->altsetting[j];
			for (k = 0; k < intf_desc->bNumEndpoints; k++) {
				if (intf_desc->endpoint[k].bEndpointAddress == ep) {
					usbi_dbg("found endpoint %02X on interface %d", intf_desc->bInterfaceNumber, i);
					return intf_desc->bInterfaceNumber;
				}
			}
		}
	}

	usbi_dbg("endpoint %02X not found on any interface", ep);
	return LIBUSB_ERROR_NOT_FOUND;
}

/*
 * Open a device and associate the HANDLE with the context's I/O completion port
 */
static HANDLE windows_open(struct libusb_device_handle *dev_handle, const char *path, DWORD access)
{
	struct libusb_context *ctx = HANDLE_CTX(dev_handle);
	struct windows_context_priv *priv = usbi_get_context_priv(ctx);
	HANDLE handle;

	handle = CreateFileA(path, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	if (handle == INVALID_HANDLE_VALUE)
		return handle;

	if (CreateIoCompletionPort(handle, priv->completion_port, (ULONG_PTR)dev_handle, 0) == NULL) {
		usbi_err(ctx, "failed to associate handle to I/O completion port: %s", windows_error_str(0));
		CloseHandle(handle);
		return INVALID_HANDLE_VALUE;
	}

	return handle;
}

/*
 * Populate the endpoints addresses of the device_priv interface helper structs
 */
static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	struct libusb_config_descriptor *conf_desc;
	const struct libusb_interface_descriptor *if_desc;
	int i, r;

	r = libusb_get_active_config_descriptor(dev_handle->dev, &conf_desc);
	if (r != LIBUSB_SUCCESS) {
		usbi_warn(HANDLE_CTX(dev_handle), "could not read config descriptor: error %d", r);
		return r;
	}

	if_desc = &conf_desc->interface[iface].altsetting[altsetting];
	safe_free(priv->usb_interface[iface].endpoint);

	if (if_desc->bNumEndpoints == 0) {
		usbi_dbg("no endpoints found for interface %u", iface);
		libusb_free_config_descriptor(conf_desc);
		priv->usb_interface[iface].current_altsetting = altsetting;
		return LIBUSB_SUCCESS;
	}

	priv->usb_interface[iface].endpoint = malloc(if_desc->bNumEndpoints);
	if (priv->usb_interface[iface].endpoint == NULL) {
		libusb_free_config_descriptor(conf_desc);
		return LIBUSB_ERROR_NO_MEM;
	}

	priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
	for (i = 0; i < if_desc->bNumEndpoints; i++) {
		priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
		usbi_dbg("(re)assigned endpoint %02X to interface %u", priv->usb_interface[iface].endpoint[i], iface);
	}
	libusb_free_config_descriptor(conf_desc);

	// Extra init may be required to configure endpoints
	if (priv->apib->configure_endpoints)
		r = priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);

	if (r == LIBUSB_SUCCESS)
		priv->usb_interface[iface].current_altsetting = altsetting;

	return r;
}

// Lookup for a match in the list of API driver names
// return -1 if not found, driver match number otherwise
static int get_sub_api(char *driver, int api)
{
	const char sep_str[2] = {LIST_SEPARATOR, 0};
	char *tok, *tmp_str;
	size_t len = strlen(driver);
	int i;

	if (len == 0)
		return SUB_API_NOTSET;

	tmp_str = _strdup(driver);
	if (tmp_str == NULL)
		return SUB_API_NOTSET;

	tok = strtok(tmp_str, sep_str);
	while (tok != NULL) {
		for (i = 0; i < usb_api_backend[api].nb_driver_names; i++) {
			if (_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
				free(tmp_str);
				return i;
			}
		}
		tok = strtok(NULL, sep_str);
	}

	free(tmp_str);
	return SUB_API_NOTSET;
}

/*
 * auto-claiming and auto-release helper functions
 */
static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
{
	struct winusb_device_handle_priv *handle_priv =
		get_winusb_device_handle_priv(transfer->dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	int current_interface = *interface_number;
	int r = LIBUSB_SUCCESS;

	switch (api_type) {
	case USB_API_WINUSBX:
	case USB_API_HID:
		break;
	default:
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	usbi_mutex_lock(&autoclaim_lock);
	if (current_interface < 0) { // No serviceable interface was found
		for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
			// Must claim an interface of the same API type
			if ((priv->usb_interface[current_interface].apib->id == api_type)
					&& (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS)) {
				usbi_dbg("auto-claimed interface %d for control request", current_interface);
				if (handle_priv->autoclaim_count[current_interface] != 0)
					usbi_err(TRANSFER_CTX(transfer), "program assertion failed - autoclaim_count was nonzero");
				handle_priv->autoclaim_count[current_interface]++;
				break;
			}
		}
		if (current_interface == USB_MAXINTERFACES) {
			usbi_err(TRANSFER_CTX(transfer), "could not auto-claim any interface");
			r = LIBUSB_ERROR_NOT_FOUND;
		}
	} else {
		// If we have a valid interface that was autoclaimed, we must increment
		// its autoclaim count so that we can prevent an early release.
		if (handle_priv->autoclaim_count[current_interface] != 0)
			handle_priv->autoclaim_count[current_interface]++;
	}
	usbi_mutex_unlock(&autoclaim_lock);

	*interface_number = current_interface;
	return r;
}

static void auto_release(struct usbi_transfer *itransfer)
{
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	libusb_device_handle *dev_handle = transfer->dev_handle;
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	int r;

	usbi_mutex_lock(&autoclaim_lock);
	if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
		handle_priv->autoclaim_count[transfer_priv->interface_number]--;
		if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
			r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
			if (r == LIBUSB_SUCCESS)
				usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
			else
				usbi_dbg("failed to auto-release interface %d (%s)",
					transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
		}
	}
	usbi_mutex_unlock(&autoclaim_lock);
}

/*
 * init: libusb backend init function
 */
static int winusb_init(struct libusb_context *ctx)
{
	int i;

	// Load DLL imports
	if (!init_dlls(ctx)) {
		usbi_err(ctx, "could not resolve DLL functions");
		return LIBUSB_ERROR_OTHER;
	}

	// Initialize the low level APIs (we don't care about errors at this stage)
	for (i = 0; i < USB_API_MAX; i++) {
		if (usb_api_backend[i].init && !usb_api_backend[i].init(ctx))
			usbi_warn(ctx, "error initializing %s backend",
				usb_api_backend[i].designation);
	}

	// We need a lock for proper auto-release
	usbi_mutex_init(&autoclaim_lock);

	return LIBUSB_SUCCESS;
}

/*
* exit: libusb backend deinitialization function
*/
static void winusb_exit(struct libusb_context *ctx)
{
	int i;

	UNUSED(ctx);

	usbi_mutex_destroy(&autoclaim_lock);

	for (i = 0; i < USB_API_MAX; i++) {
		if (usb_api_backend[i].exit)
			usb_api_backend[i].exit();
	}

	exit_dlls();
}

/*
 * fetch and cache all the config descriptors through I/O
 */
static void cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle)
{
	struct libusb_context *ctx = DEVICE_CTX(dev);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	DWORD size, ret_size;
	uint8_t i, num_configurations;

	USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
	PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL;    // actual request
	PUSB_CONFIGURATION_DESCRIPTOR cd_data;

	num_configurations = dev->device_descriptor.bNumConfigurations;
	if (num_configurations == 0)
		return;

	assert(sizeof(USB_DESCRIPTOR_REQUEST) == USB_DESCRIPTOR_REQUEST_SIZE);

	priv->config_descriptor = calloc(num_configurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR));
	if (priv->config_descriptor == NULL) {
		usbi_err(ctx, "could not allocate configuration descriptor array for '%s'", priv->dev_id);
		return;
	}

	for (i = 0; i <= num_configurations; i++) {
		safe_free(cd_buf_actual);

		if (i == num_configurations)
			break;

		size = sizeof(cd_buf_short);
		memset(&cd_buf_short.desc, 0, sizeof(cd_buf_short.desc));

		cd_buf_short.req.ConnectionIndex = (ULONG)dev->port_number;
		cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
		cd_buf_short.req.SetupPacket.bRequest = LIBUSB_REQUEST_GET_DESCRIPTOR;
		cd_buf_short.req.SetupPacket.wValue = (LIBUSB_DT_CONFIG << 8) | i;
		cd_buf_short.req.SetupPacket.wIndex = 0;
		cd_buf_short.req.SetupPacket.wLength = (USHORT)sizeof(USB_CONFIGURATION_DESCRIPTOR);

		// Dummy call to get the required data size. Initial failures are reported as info rather
		// than error as they can occur for non-penalizing situations, such as with some hubs.
		// coverity[tainted_data_argument]
		if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
			&cd_buf_short, size, &ret_size, NULL)) {
			usbi_info(ctx, "could not access configuration descriptor %u (dummy) for '%s': %s", i, priv->dev_id, windows_error_str(0));
			continue;
		}

		if ((ret_size != size) || (cd_buf_short.desc.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
			usbi_info(ctx, "unexpected configuration descriptor %u size (dummy) for '%s'", i, priv->dev_id);
			continue;
		}

		size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.desc.wTotalLength;
		cd_buf_actual = malloc(size);
		if (cd_buf_actual == NULL) {
			usbi_err(ctx, "could not allocate configuration descriptor %u buffer for '%s'", i, priv->dev_id);
			continue;
		}

		// Actual call
		cd_buf_actual->ConnectionIndex = (ULONG)dev->port_number;
		cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
		cd_buf_actual->SetupPacket.bRequest = LIBUSB_REQUEST_GET_DESCRIPTOR;
		cd_buf_actual->SetupPacket.wValue = (LIBUSB_DT_CONFIG << 8) | i;
		cd_buf_actual->SetupPacket.wIndex = 0;
		cd_buf_actual->SetupPacket.wLength = cd_buf_short.desc.wTotalLength;

		if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
			cd_buf_actual, size, &ret_size, NULL)) {
			usbi_err(ctx, "could not access configuration descriptor %u (actual) for '%s': %s", i, priv->dev_id, windows_error_str(0));
			continue;
		}

		cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR *)cd_buf_actual + USB_DESCRIPTOR_REQUEST_SIZE);

		if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.desc.wTotalLength)) {
			usbi_err(ctx, "unexpected configuration descriptor %u size (actual) for '%s'", i, priv->dev_id);
			continue;
		}

		if (cd_data->bDescriptorType != LIBUSB_DT_CONFIG) {
			usbi_err(ctx, "descriptor %u not a configuration descriptor for '%s'", i, priv->dev_id);
			continue;
		}

		usbi_dbg("cached config descriptor %u (bConfigurationValue=%u, %u bytes)",
			i, cd_data->bConfigurationValue, cd_data->wTotalLength);

		// Cache the descriptor
		priv->config_descriptor[i] = cd_data;
		cd_buf_actual = NULL;
	}
}

#define ROOT_HUB_FS_CONFIG_DESC_LENGTH		0x19
#define ROOT_HUB_HS_CONFIG_DESC_LENGTH		0x19
#define ROOT_HUB_SS_CONFIG_DESC_LENGTH		0x1f
#define CONFIG_DESC_WTOTAL_LENGTH_OFFSET	0x02
#define CONFIG_DESC_EP_MAX_PACKET_OFFSET	0x16
#define CONFIG_DESC_EP_BINTERVAL_OFFSET		0x18

static const uint8_t root_hub_config_descriptor_template[] = {
	// Configuration Descriptor
	LIBUSB_DT_CONFIG_SIZE,		// bLength
	LIBUSB_DT_CONFIG,		// bDescriptorType
	0x00, 0x00,			// wTotalLength (filled in)
	0x01,				// bNumInterfaces
	0x01,				// bConfigurationValue
	0x00,				// iConfiguration
	0xc0,				// bmAttributes (reserved + self-powered)
	0x00,				// bMaxPower
	// Interface Descriptor
	LIBUSB_DT_INTERFACE_SIZE,	// bLength
	LIBUSB_DT_INTERFACE,		// bDescriptorType
	0x00,				// bInterfaceNumber
	0x00,				// bAlternateSetting
	0x01,				// bNumEndpoints
	LIBUSB_CLASS_HUB,		// bInterfaceClass
	0x00,				// bInterfaceSubClass
	0x00,				// bInterfaceProtocol
	0x00,				// iInterface
	// Endpoint Descriptor
	LIBUSB_DT_ENDPOINT_SIZE,	// bLength
	LIBUSB_DT_ENDPOINT,		// bDescriptorType
	0x81,				// bEndpointAddress
	0x03,				// bmAttributes (Interrupt)
	0x00, 0x00,			// wMaxPacketSize (filled in)
	0x00,				// bInterval (filled in)
	// SuperSpeed Endpoint Companion Descriptor
	LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE,	// bLength
	LIBUSB_DT_SS_ENDPOINT_COMPANION,	// bDescriptorType
	0x00,					// bMaxBurst
	0x00,					// bmAttributes
	0x02, 0x00				// wBytesPerInterval
};

static int alloc_root_hub_config_desc(struct libusb_device *dev, ULONG num_ports,
	uint8_t config_desc_length, uint8_t ep_interval)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	uint8_t *ptr;

	priv->config_descriptor = malloc(sizeof(*priv->config_descriptor));
	if (priv->config_descriptor == NULL)
		return LIBUSB_ERROR_NO_MEM;

	// Most config descriptors come from cache_config_descriptors() which obtains the
	// descriptors from the hub using an allocated USB_DESCRIPTOR_REQUEST structure.
	// To avoid an extra malloc + memcpy we just hold on to the USB_DESCRIPTOR_REQUEST
	// structure we already have and back up the pointer in windows_device_priv_release()
	// when freeing the descriptors. To keep a single execution path, we need to offset
	// the pointer here by the same amount.
	ptr = malloc(USB_DESCRIPTOR_REQUEST_SIZE + config_desc_length);
	if (ptr == NULL)
		return LIBUSB_ERROR_NO_MEM;

	ptr += USB_DESCRIPTOR_REQUEST_SIZE;

	memcpy(ptr, root_hub_config_descriptor_template, config_desc_length);
	ptr[CONFIG_DESC_WTOTAL_LENGTH_OFFSET] = config_desc_length;
	ptr[CONFIG_DESC_EP_MAX_PACKET_OFFSET] = (uint8_t)((num_ports + 7) / 8);
	ptr[CONFIG_DESC_EP_BINTERVAL_OFFSET] = ep_interval;

	priv->config_descriptor[0] = (PUSB_CONFIGURATION_DESCRIPTOR)ptr;
	priv->active_config = 1;

	return 0;
}

static int init_root_hub(struct libusb_device *dev)
{
	struct libusb_context *ctx = DEVICE_CTX(dev);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	USB_NODE_CONNECTION_INFORMATION_EX conn_info;
	USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2;
	USB_NODE_INFORMATION hub_info;
	enum libusb_speed speed = LIBUSB_SPEED_UNKNOWN;
	uint8_t config_desc_length;
	uint8_t ep_interval;
	HANDLE handle;
	ULONG port_number, num_ports;
	DWORD size;
	int r;

	// Determining the speed of a root hub is painful. Microsoft does not directly report the speed
	// capabilities of the root hub itself, only its ports and/or connected devices. Therefore we
	// are forced to query each individual port of the root hub to try and infer the root hub's
	// speed. Note that we have to query all ports because the presence of a device on that port
	// changes if/how Windows returns any useful speed information.
	handle = CreateFileA(priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (handle == INVALID_HANDLE_VALUE) {
		usbi_err(ctx, "could not open root hub %s: %s", priv->path, windows_error_str(0));
		return LIBUSB_ERROR_ACCESS;
	}

	if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_INFORMATION, NULL, 0, &hub_info, sizeof(hub_info), &size, NULL)) {
		usbi_warn(ctx, "could not get root hub info for '%s': %s", priv->dev_id, windows_error_str(0));
		CloseHandle(handle);
		return LIBUSB_ERROR_ACCESS;
	}

	num_ports = hub_info.u.HubInformation.HubDescriptor.bNumberOfPorts;
	usbi_dbg("root hub '%s' reports %lu ports", priv->dev_id, ULONG_CAST(num_ports));

	if (windows_version >= WINDOWS_8) {
		// Windows 8 and later is better at reporting the speed capabilities of the root hub,
		// but it is not perfect. If no device is attached to the port being queried, the
		// returned information will only indicate whether that port supports USB 3.0 signalling.
		// That is not enough information to distinguish between SuperSpeed and SuperSpeed Plus.
		for (port_number = 1; port_number <= num_ports; port_number++) {
			conn_info_v2.ConnectionIndex = port_number;
			conn_info_v2.Length = sizeof(conn_info_v2);
			conn_info_v2.SupportedUsbProtocols.Usb300 = 1;
			if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2,
				&conn_info_v2, sizeof(conn_info_v2), &conn_info_v2, sizeof(conn_info_v2), &size, NULL)) {
				usbi_warn(ctx, "could not get node connection information (V2) for root hub '%s' port %lu: %s",
					priv->dev_id, ULONG_CAST(port_number), windows_error_str(0));
				break;
			}

			if (conn_info_v2.Flags.DeviceIsSuperSpeedPlusCapableOrHigher)
				speed = MAX(speed, LIBUSB_SPEED_SUPER_PLUS);
			else if (conn_info_v2.Flags.DeviceIsSuperSpeedCapableOrHigher || conn_info_v2.SupportedUsbProtocols.Usb300)
				speed = MAX(speed, LIBUSB_SPEED_SUPER);
			else if (conn_info_v2.SupportedUsbProtocols.Usb200)
				speed = MAX(speed, LIBUSB_SPEED_HIGH);
			else
				speed = MAX(speed, LIBUSB_SPEED_FULL);
		}

		if (speed != LIBUSB_SPEED_UNKNOWN)
			goto make_descriptors;
	}

	// At this point the speed is still not known, most likely because we are executing on
	// Windows 7 or earlier. The following hackery peeks into the root hub's Device ID and
	// tries to extract speed information from it, based on observed naming conventions.
	// If this does not work, we will query individual ports of the root hub.
	if (strstr(priv->dev_id, "ROOT_HUB31") != NULL)
		speed = LIBUSB_SPEED_SUPER_PLUS;
	else if (strstr(priv->dev_id, "ROOT_HUB30") != NULL)
		speed = LIBUSB_SPEED_SUPER;
	else if (strstr(priv->dev_id, "ROOT_HUB20") != NULL)
		speed = LIBUSB_SPEED_HIGH;

	if (speed != LIBUSB_SPEED_UNKNOWN)
		goto make_descriptors;

	// Windows only reports speed information about a connected device. This means that a root
	// hub with no connected devices or devices that are all operating at a speed less than the
	// highest speed that the root hub supports will not give us the correct speed.
	for (port_number = 1; port_number <= num_ports; port_number++) {
		conn_info.ConnectionIndex = port_number;
		if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, sizeof(conn_info),
			&conn_info, sizeof(conn_info), &size, NULL)) {
			usbi_warn(ctx, "could not get node connection information for root hub '%s' port %lu: %s",
				priv->dev_id, ULONG_CAST(port_number), windows_error_str(0));
			continue;
		}

		if (conn_info.ConnectionStatus != DeviceConnected)
			continue;

		if (conn_info.Speed == UsbHighSpeed) {
			speed = LIBUSB_SPEED_HIGH;
			break;
		}
	}

make_descriptors:
	CloseHandle(handle);

	dev->device_descriptor.bLength = LIBUSB_DT_DEVICE_SIZE;
	dev->device_descriptor.bDescriptorType = LIBUSB_DT_DEVICE;
	dev->device_descriptor.bDeviceClass = LIBUSB_CLASS_HUB;
	if ((dev->device_descriptor.idVendor == 0) && (dev->device_descriptor.idProduct == 0)) {
		dev->device_descriptor.idVendor = 0x1d6b;	// Linux Foundation
		dev->device_descriptor.idProduct = (uint16_t)speed;
	}
	dev->device_descriptor.bcdDevice = 0x0100;
	dev->device_descriptor.bNumConfigurations = 1;

	switch (speed) {
	case LIBUSB_SPEED_SUPER_PLUS:
		dev->device_descriptor.bcdUSB = 0x0310;
		config_desc_length = ROOT_HUB_SS_CONFIG_DESC_LENGTH;
		ep_interval = 0x0c;	// 256ms
		break;
	case LIBUSB_SPEED_SUPER:
		dev->device_descriptor.bcdUSB = 0x0300;
		config_desc_length = ROOT_HUB_SS_CONFIG_DESC_LENGTH;
		ep_interval = 0x0c;	// 256ms
		break;
	case LIBUSB_SPEED_HIGH:
		dev->device_descriptor.bcdUSB = 0x0200;
		config_desc_length = ROOT_HUB_HS_CONFIG_DESC_LENGTH;
		ep_interval = 0x0c;	// 256ms
		break;
	case LIBUSB_SPEED_LOW:		// Not used, but keeps compiler happy
	case LIBUSB_SPEED_UNKNOWN:
		// This case means absolutely no information about this root hub was determined.
		// There is not much choice than to be pessimistic and label this as a
		// full-speed device.
		speed = LIBUSB_SPEED_FULL;
		// fallthrough
	case LIBUSB_SPEED_FULL:
		dev->device_descriptor.bcdUSB = 0x0110;
		config_desc_length = ROOT_HUB_FS_CONFIG_DESC_LENGTH;
		ep_interval = 0xff;	// 255ms
		break;
	default:			// Impossible, buts keeps compiler happy
		usbi_err(ctx, "program assertion failed - unknown root hub speed");
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	if (speed >= LIBUSB_SPEED_SUPER) {
		dev->device_descriptor.bDeviceProtocol = 0x03;	// USB 3.0 Hub
		dev->device_descriptor.bMaxPacketSize0 = 0x09;	// 2^9 bytes
	} else {
		dev->device_descriptor.bMaxPacketSize0 = 0x40;	// 64 bytes
	}

	dev->speed = speed;

	r = alloc_root_hub_config_desc(dev, num_ports, config_desc_length, ep_interval);
	if (r)
		usbi_err(ctx, "could not allocate config descriptor for root hub '%s'", priv->dev_id);

	return r;
}

/*
 * Populate a libusb device structure
 */
static int init_device(struct libusb_device *dev, struct libusb_device *parent_dev,
	uint8_t port_number, DEVINST devinst)
{
	struct libusb_context *ctx;
	struct libusb_device *tmp_dev;
	struct winusb_device_priv *priv, *parent_priv, *tmp_priv;
	USB_NODE_CONNECTION_INFORMATION_EX conn_info;
	USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2;
	HANDLE hub_handle;
	DWORD size;
	uint8_t bus_number, depth;
	int r;
	int ginfotimeout;

	priv = usbi_get_device_priv(dev);

	// If the device is already initialized, we can stop here
	if (priv->initialized)
		return LIBUSB_SUCCESS;

	if (parent_dev != NULL) { // Not a HCD root hub
		ctx = DEVICE_CTX(dev);
		parent_priv = usbi_get_device_priv(parent_dev);
		if (parent_priv->apib->id != USB_API_HUB) {
			usbi_warn(ctx, "parent for device '%s' is not a hub", priv->dev_id);
			return LIBUSB_ERROR_NOT_FOUND;
		}

		// Calculate depth and fetch bus number
		bus_number = parent_dev->bus_number;
		if (bus_number == 0) {
			tmp_dev = get_ancestor(ctx, devinst, &devinst);
			if (tmp_dev != parent_dev) {
				usbi_err(ctx, "program assertion failed - first ancestor is not parent");
				return LIBUSB_ERROR_NOT_FOUND;
			}
			libusb_unref_device(tmp_dev);

			for (depth = 1; bus_number == 0; depth++) {
				tmp_dev = get_ancestor(ctx, devinst, &devinst);
				if (tmp_dev == NULL) {
					usbi_warn(ctx, "ancestor for device '%s' not found at depth %u", priv->dev_id, depth);
					return LIBUSB_ERROR_NO_DEVICE;
				}
				if (tmp_dev->bus_number != 0) {
					bus_number = tmp_dev->bus_number;
					tmp_priv = usbi_get_device_priv(tmp_dev);
					depth += tmp_priv->depth;
				}
				libusb_unref_device(tmp_dev);
			}
		} else {
			depth = parent_priv->depth + 1;
		}

		if (bus_number == 0) {
			usbi_err(ctx, "program assertion failed - bus number not found for '%s'", priv->dev_id);
			return LIBUSB_ERROR_NOT_FOUND;
		}

		dev->bus_number = bus_number;
		dev->port_number = port_number;
		dev->parent_dev = parent_dev;
		priv->depth = depth;

		hub_handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
		if (hub_handle == INVALID_HANDLE_VALUE) {
			usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
			return LIBUSB_ERROR_ACCESS;
		}

		conn_info.ConnectionIndex = (ULONG)port_number;
		// coverity[tainted_data_argument]
		ginfotimeout = 20;
		do {
			if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, sizeof(conn_info),
				&conn_info, sizeof(conn_info), &size, NULL)) {
				usbi_warn(ctx, "could not get node connection information for device '%s': %s",
					priv->dev_id, windows_error_str(0));
				CloseHandle(hub_handle);
				return LIBUSB_ERROR_NO_DEVICE;
			}

			if (conn_info.ConnectionStatus == NoDeviceConnected) {
				usbi_err(ctx, "device '%s' is no longer connected!", priv->dev_id);
				CloseHandle(hub_handle);
				return LIBUSB_ERROR_NO_DEVICE;
			}

			if ((conn_info.DeviceDescriptor.bLength != LIBUSB_DT_DEVICE_SIZE)
				 || (conn_info.DeviceDescriptor.bDescriptorType != LIBUSB_DT_DEVICE)) {
				SleepEx(50, TRUE);
				continue;
			}

			static_assert(sizeof(dev->device_descriptor) == sizeof(conn_info.DeviceDescriptor),
				      "mismatch between libusb and OS device descriptor sizes");
			memcpy(&dev->device_descriptor, &conn_info.DeviceDescriptor, LIBUSB_DT_DEVICE_SIZE);
			usbi_localize_device_descriptor(&dev->device_descriptor);

			priv->active_config = conn_info.CurrentConfigurationValue;
			if (priv->active_config == 0) {
				usbi_dbg("0x%x:0x%x found %u configurations (not configured)",
					dev->device_descriptor.idVendor,
					dev->device_descriptor.idProduct,
					dev->device_descriptor.bNumConfigurations);
				SleepEx(50, TRUE);
			}
		} while (priv->active_config == 0 && --ginfotimeout >= 0);

		if ((conn_info.DeviceDescriptor.bLength != LIBUSB_DT_DEVICE_SIZE)
			 || (conn_info.DeviceDescriptor.bDescriptorType != LIBUSB_DT_DEVICE)) {
			usbi_err(ctx, "device '%s' has invalid descriptor!", priv->dev_id);
			CloseHandle(hub_handle);
			return LIBUSB_ERROR_OTHER;
		}

		if (priv->active_config == 0) {
			usbi_info(ctx, "0x%x:0x%x found %u configurations but device isn't configured, "
				"forcing current configuration to 1",
				dev->device_descriptor.idVendor,
				dev->device_descriptor.idProduct,
				dev->device_descriptor.bNumConfigurations);
			priv->active_config = 1;
		} else {
			usbi_dbg("found %u configurations (current config: %u)", dev->device_descriptor.bNumConfigurations, priv->active_config);
		}

		// Cache as many config descriptors as we can
		cache_config_descriptors(dev, hub_handle);

		// In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8
		if (windows_version >= WINDOWS_8) {
			conn_info_v2.ConnectionIndex = (ULONG)port_number;
			conn_info_v2.Length = sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2);
			conn_info_v2.SupportedUsbProtocols.Usb300 = 1;
			if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2,
				&conn_info_v2, sizeof(conn_info_v2), &conn_info_v2, sizeof(conn_info_v2), &size, NULL)) {
				usbi_warn(ctx, "could not get node connection information (V2) for device '%s': %s",
					priv->dev_id,  windows_error_str(0));
			} else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedPlusOrHigher) {
				conn_info.Speed = UsbSuperSpeedPlus;
			} else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) {
				conn_info.Speed = UsbSuperSpeed;
			}
		}

		CloseHandle(hub_handle);

		if (conn_info.DeviceAddress > UINT8_MAX)
			usbi_err(ctx, "program assertion failed - device address overflow");

		dev->device_address = (uint8_t)conn_info.DeviceAddress;

		switch (conn_info.Speed) {
		case UsbLowSpeed: dev->speed = LIBUSB_SPEED_LOW; break;
		case UsbFullSpeed: dev->speed = LIBUSB_SPEED_FULL; break;
		case UsbHighSpeed: dev->speed = LIBUSB_SPEED_HIGH; break;
		case UsbSuperSpeed: dev->speed = LIBUSB_SPEED_SUPER; break;
		case UsbSuperSpeedPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
		default:
			usbi_warn(ctx, "unknown device speed %u", conn_info.Speed);
			break;
		}
	} else {
		r = init_root_hub(dev);
		if (r)
			return r;
	}

	r = usbi_sanitize_device(dev);
	if (r)
		return r;

	priv->initialized = true;

	usbi_dbg("(bus: %u, addr: %u, depth: %u, port: %u): '%s'",
		dev->bus_number, dev->device_address, priv->depth, dev->port_number, priv->dev_id);

	return LIBUSB_SUCCESS;
}

static bool get_dev_port_number(HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data, DWORD *port_nr)
{
	char buffer[MAX_KEY_LENGTH];
	DWORD size;

	// First try SPDRP_LOCATION_INFORMATION, which returns a REG_SZ. The string *may* have a format
	// similar to "Port_#0002.Hub_#000D", in which case we can extract the port number. However, we
	// cannot extract the port if the returned string does not follow this format.
	if (pSetupDiGetDeviceRegistryPropertyA(dev_info, dev_info_data, SPDRP_LOCATION_INFORMATION,
			NULL, (PBYTE)buffer, sizeof(buffer), NULL)) {
		// Check for the required format.
		if (strncmp(buffer, "Port_#", 6) == 0) {
			*port_nr = atoi(buffer + 6);
			return true;
		}
	}

	// Next try SPDRP_LOCATION_PATHS, which returns a REG_MULTI_SZ (but we only examine the first
	// string in it). Each path has a format similar to,
	// "PCIROOT(B2)#PCI(0300)#PCI(0000)#USBROOT(0)#USB(1)#USB(2)#USBMI(3)", and the port number is
	// the number within the last "USB(x)" token.
	if (pSetupDiGetDeviceRegistryPropertyA(dev_info, dev_info_data, SPDRP_LOCATION_PATHS,
			NULL, (PBYTE)buffer, sizeof(buffer), NULL)) {
		// Find the last "#USB(x)" substring
		for (char *token = strrchr(buffer, '#'); token != NULL; token = strrchr(buffer, '#')) {
			if (strncmp(token, "#USB(", 5) == 0) {
				*port_nr = atoi(token + 5);
				return true;
			}
			// Shorten the string and try again.
			*token = '\0';
		}
	}

	// Lastly, try SPDRP_ADDRESS, which returns a REG_DWORD. The address *may* be the port number,
	// which is true for the Microsoft driver but may not be true for other drivers. However, we
	// have no other options here but to accept what it returns.
	return pSetupDiGetDeviceRegistryPropertyA(dev_info, dev_info_data, SPDRP_ADDRESS,
			NULL, (PBYTE)port_nr, sizeof(*port_nr), &size) && (size == sizeof(*port_nr));
}

static int enumerate_hcd_root_hub(struct libusb_context *ctx, const char *dev_id,
	uint8_t bus_number, DEVINST devinst)
{
	struct libusb_device *dev;
	struct winusb_device_priv *priv;
	unsigned long session_id;
	DEVINST child_devinst;

	if (CM_Get_Child(&child_devinst, devinst, 0) != CR_SUCCESS) {
		usbi_warn(ctx, "could not get child devinst for '%s'", dev_id);
		return LIBUSB_SUCCESS;
	}

	session_id = (unsigned long)child_devinst;
	dev = usbi_get_device_by_session_id(ctx, session_id);
	if (dev == NULL) {
		usbi_err(ctx, "program assertion failed - HCD '%s' child not found", dev_id);
		return LIBUSB_SUCCESS;
	}

	if (dev->bus_number == 0) {
		// Only do this once
		usbi_dbg("assigning HCD '%s' bus number %u", dev_id, bus_number);
		dev->bus_number = bus_number;

		if (sscanf(dev_id, "PCI\\VEN_%04hx&DEV_%04hx%*s", &dev->device_descriptor.idVendor, &dev->device_descriptor.idProduct) != 2)
			usbi_warn(ctx, "could not infer VID/PID of HCD root hub from '%s'", dev_id);

		priv = usbi_get_device_priv(dev);
		priv->root_hub = true;
	}

	libusb_unref_device(dev);
	return LIBUSB_SUCCESS;
}

// Returns the api type, or 0 if not found/unsupported
static void get_api_type(HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data,
	int *api, int *sub_api)
{
	// Precedence for filter drivers vs driver is in the order of this array
	struct driver_lookup lookup[3] = {
		{"\0\0", SPDRP_SERVICE, "driver"},
		{"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
		{"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
	};
	DWORD size, reg_type;
	unsigned k, l;
	int i, j;

	// Check the service & filter names to know the API we should use
	for (k = 0; k < 3; k++) {
		if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
			&reg_type, (PBYTE)lookup[k].list, MAX_KEY_LENGTH, &size)) {
			// Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
			if (lookup[k].reg_prop == SPDRP_SERVICE)
				// our buffers are MAX_KEY_LENGTH + 1 so we can overflow if needed
				lookup[k].list[strlen(lookup[k].list) + 1] = 0;

			// MULTI_SZ is a pain to work with. Turn it into something much more manageable
			// NB: none of the driver names we check against contain LIST_SEPARATOR,
			// (currently ';'), so even if an unsupported one does, it's not an issue
			for (l = 0; (lookup[k].list[l] != 0) || (lookup[k].list[l + 1] != 0); l++) {
				if (lookup[k].list[l] == 0)
					lookup[k].list[l] = LIST_SEPARATOR;
			}
			usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
		} else {
			if (GetLastError() != ERROR_INVALID_DATA)
				usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
			lookup[k].list[0] = 0;
		}
	}

	for (i = 2; i < USB_API_MAX; i++) {
		for (k = 0; k < 3; k++) {
			j = get_sub_api(lookup[k].list, i);
			if (j >= 0) {
				usbi_dbg("matched %s name against %s", lookup[k].designation,
					(i != USB_API_WINUSBX) ? usb_api_backend[i].designation : usb_api_backend[i].driver_name_list[j]);
				*api = i;
				*sub_api = j;
				return;
			}
		}
	}
}

static int set_composite_interface(struct libusb_context *ctx, struct libusb_device *dev,
	char *dev_interface_path, char *device_id, int api, int sub_api)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	int interface_number;
	const char *mi_str;

	// Because MI_## are not necessarily in sequential order (some composite
	// devices will have only MI_00 & MI_03 for instance), we retrieve the actual
	// interface number from the path's MI value
	mi_str = strstr(device_id, "MI_");
	if ((mi_str != NULL) && isdigit((unsigned char)mi_str[3]) && isdigit((unsigned char)mi_str[4])) {
		interface_number = ((mi_str[3] - '0') * 10) + (mi_str[4] - '0');
	} else {
		usbi_warn(ctx, "failure to read interface number for %s, using default value", device_id);
		interface_number = 0;
	}

	if (interface_number >= USB_MAXINTERFACES) {
		usbi_warn(ctx, "interface %d too large - ignoring interface path %s", interface_number, dev_interface_path);
		return LIBUSB_ERROR_ACCESS;
	}

	if (priv->usb_interface[interface_number].path != NULL) {
		if (api == USB_API_HID) {
			// HID devices can have multiple collections (COL##) for each MI_## interface
			usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
				interface_number, device_id);
			return LIBUSB_ERROR_ACCESS;
		}
		// In other cases, just use the latest data
		safe_free(priv->usb_interface[interface_number].path);
	}

	usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
	priv->usb_interface[interface_number].path = dev_interface_path;
	priv->usb_interface[interface_number].apib = &usb_api_backend[api];
	priv->usb_interface[interface_number].sub_api = sub_api;
	if ((api == USB_API_HID) && (priv->hid == NULL)) {
		priv->hid = calloc(1, sizeof(struct hid_device_priv));
		if (priv->hid == NULL)
			return LIBUSB_ERROR_NO_MEM;
	}

	return LIBUSB_SUCCESS;
}

static int set_hid_interface(struct libusb_context *ctx, struct libusb_device *dev,
	char *dev_interface_path)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	uint8_t i;

	if (priv->hid == NULL) {
		usbi_err(ctx, "program assertion failed - parent is not HID");
		return LIBUSB_ERROR_NO_DEVICE;
	} else if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
		usbi_err(ctx, "program assertion failed - max USB interfaces reached for HID device");
		return LIBUSB_ERROR_NO_DEVICE;
	}

	for (i = 0; i < priv->hid->nb_interfaces; i++) {
		if ((priv->usb_interface[i].path != NULL) && strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
			usbi_dbg("interface[%u] already set to %s", i, dev_interface_path);
			return LIBUSB_ERROR_ACCESS;
		}
	}

	priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
	priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
	usbi_dbg("interface[%u] = %s", priv->hid->nb_interfaces, dev_interface_path);
	priv->hid->nb_interfaces++;
	return LIBUSB_SUCCESS;
}

/*
 * get_device_list: libusb backend device enumeration function
 */
static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
{
	struct discovered_devs *discdevs;
	HDEVINFO *dev_info, dev_info_intf, dev_info_enum;
	SP_DEVINFO_DATA dev_info_data;
	DWORD _index = 0;
	GUID hid_guid;
	int r = LIBUSB_SUCCESS;
	int api, sub_api;
	unsigned int pass, i, j;
	char enumerator[16];
	char dev_id[MAX_PATH_LENGTH];
	struct libusb_device *dev, *parent_dev;
	struct winusb_device_priv *priv, *parent_priv;
	char *dev_interface_path = NULL;
	unsigned long session_id;
	DWORD size, port_nr, reg_type, install_state;
	HKEY key;
	char guid_string[MAX_GUID_STRING_LENGTH];
	GUID *if_guid;
	LONG s;
#define HUB_PASS 0
#define DEV_PASS 1
#define HCD_PASS 2
#define GEN_PASS 3
#define HID_PASS 4
#define EXT_PASS 5
	// Keep a list of guids that will be enumerated
#define GUID_SIZE_STEP 8
	const GUID **guid_list, **new_guid_list;
	unsigned int guid_size = GUID_SIZE_STEP;
	unsigned int nb_guids;
	// Keep a list of PnP enumerator strings that are found
	const char *usb_enumerator[8] = { "USB" };
	unsigned int nb_usb_enumerators = 1;
	unsigned int usb_enum_index = 0;
	// Keep a list of newly allocated devs to unref
#define UNREF_SIZE_STEP 16
	libusb_device **unref_list, **new_unref_list;
	unsigned int unref_size = UNREF_SIZE_STEP;
	unsigned int unref_cur = 0;

	// PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
	// PASS 2 : (re)enumerate HUBS
	// PASS 3 : (re)enumerate generic USB devices (including driverless)
	//           and list additional USB device interface GUIDs to explore
	// PASS 4 : (re)enumerate master USB devices that have a device interface
	// PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
	//           set the device interfaces.

	// Init the GUID table
	guid_list = malloc(guid_size * sizeof(void *));
	if (guid_list == NULL) {
		usbi_err(ctx, "failed to alloc guid list");
		return LIBUSB_ERROR_NO_MEM;
	}

	guid_list[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
	guid_list[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
	guid_list[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
	guid_list[GEN_PASS] = NULL;
	if (HidD_GetHidGuid != NULL) {
		HidD_GetHidGuid(&hid_guid);
		guid_list[HID_PASS] = &hid_guid;
	} else {
		guid_list[HID_PASS] = NULL;
	}
	nb_guids = EXT_PASS;

	unref_list = malloc(unref_size * sizeof(void *));
	if (unref_list == NULL) {
		usbi_err(ctx, "failed to alloc unref list");
		free((void *)guid_list);
		return LIBUSB_ERROR_NO_MEM;
	}

	dev_info_intf = pSetupDiGetClassDevsA(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (dev_info_intf == INVALID_HANDLE_VALUE) {
		usbi_err(ctx, "failed to obtain device info list: %s", windows_error_str(0));
		free(unref_list);
		free((void *)guid_list);
		return LIBUSB_ERROR_OTHER;
	}

	for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
//#define ENUM_DEBUG
#if defined(ENABLE_LOGGING) && defined(ENUM_DEBUG)
		const char * const passname[] = {"HUB", "DEV", "HCD", "GEN", "HID", "EXT"};
		usbi_dbg("#### PROCESSING %ss %s", passname[MIN(pass, EXT_PASS)], guid_to_string(guid_list[pass], guid_string));
#endif
		if ((pass == HID_PASS) && (guid_list[HID_PASS] == NULL))
			continue;

		dev_info = (pass != GEN_PASS) ? &dev_info_intf : &dev_info_enum;

		for (i = 0; ; i++) {
			// safe loop: free up any (unprotected) dynamic resource
			// NB: this is always executed before breaking the loop
			safe_free(dev_interface_path);
			priv = parent_priv = NULL;
			dev = parent_dev = NULL;

			// Safe loop: end of loop conditions
			if (r != LIBUSB_SUCCESS)
				break;

			if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
				usbi_warn(ctx, "program assertion failed - found more than %u buses, skipping the rest", UINT8_MAX);
				break;
			}

			if (pass != GEN_PASS) {
				// Except for GEN, all passes deal with device interfaces
				r = get_interface_details(ctx, *dev_info, &dev_info_data, guid_list[pass], &_index, &dev_interface_path);
				if ((r != LIBUSB_SUCCESS) || (dev_interface_path == NULL)) {
					_index = 0;
					break;
				}
			} else {
				// Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
				// being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
				// The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
				// The Intel Alpine Ridge USB 3.1 driver uses "IARUSB3"
				for (; usb_enum_index < nb_usb_enumerators; usb_enum_index++) {
					if (get_devinfo_data(ctx, dev_info, &dev_info_data, usb_enumerator[usb_enum_index], i))
						break;
					i = 0;
				}
				if (usb_enum_index == nb_usb_enumerators)
					break;
			}

			// Read the Device ID path
			if (!pSetupDiGetDeviceInstanceIdA(*dev_info, &dev_info_data, dev_id, sizeof(dev_id), NULL)) {
				usbi_warn(ctx, "could not read the device instance ID for devInst %lX, skipping",
					  ULONG_CAST(dev_info_data.DevInst));
				continue;
			}

#ifdef ENUM_DEBUG
			usbi_dbg("PRO: %s", dev_id);
#endif

			// Set API to use or get additional data from generic pass
			api = USB_API_UNSUPPORTED;
			sub_api = SUB_API_NOTSET;
			switch (pass) {
			case HCD_PASS:
				break;
			case HUB_PASS:
				api = USB_API_HUB;
				// Fetch the PnP enumerator class for this hub
				// This will allow us to enumerate all classes during the GEN pass
				if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME,
					NULL, (PBYTE)enumerator, sizeof(enumerator), NULL)) {
					usbi_err(ctx, "could not read enumerator string for device '%s': %s", dev_id, windows_error_str(0));
					LOOP_BREAK(LIBUSB_ERROR_OTHER);
				}
				for (j = 0; j < nb_usb_enumerators; j++) {
					if (strcmp(usb_enumerator[j], enumerator) == 0)
						break;
				}
				if (j == nb_usb_enumerators) {
					usbi_dbg("found new PnP enumerator string '%s'", enumerator);
					if (nb_usb_enumerators < ARRAYSIZE(usb_enumerator)) {
						usb_enumerator[nb_usb_enumerators] = _strdup(enumerator);
						if (usb_enumerator[nb_usb_enumerators] != NULL) {
							nb_usb_enumerators++;
						} else {
							usbi_err(ctx, "could not allocate enumerator string '%s'", enumerator);
							LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
						}
					} else {
						usbi_warn(ctx, "too many enumerator strings, some devices may not be accessible");
					}
				}
				break;
			case GEN_PASS:
				// We use the GEN pass to detect driverless devices...
				if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_DRIVER,
					NULL, NULL, 0, NULL) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
					usbi_info(ctx, "The following device has no driver: '%s'", dev_id);
					usbi_info(ctx, "libusb will not be able to access it");
				}
				// ...and to add the additional device interface GUIDs
				key = pSetupDiOpenDevRegKey(*dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
				if (key == INVALID_HANDLE_VALUE)
					break;
				// Look for both DeviceInterfaceGUIDs *and* DeviceInterfaceGUID, in that order
				size = sizeof(guid_string);
				s = pRegQueryValueExA(key, "DeviceInterfaceGUIDs", NULL, &reg_type,
					(LPBYTE)guid_string, &size);
				if (s == ERROR_FILE_NOT_FOUND)
					s = pRegQueryValueExA(key, "DeviceInterfaceGUID", NULL, &reg_type,
						(LPBYTE)guid_string, &size);
				pRegCloseKey(key);
				if (s == ERROR_FILE_NOT_FOUND) {
					break; /* no DeviceInterfaceGUID registered */
				} else if (s != ERROR_SUCCESS) {
					usbi_warn(ctx, "unexpected error from pRegQueryValueExA for '%s'", dev_id);
					break;
				}
				// https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexa#remarks
				// - "string may not have been stored with the proper terminating null characters"
				// - "Note that REG_MULTI_SZ strings could have two terminating null characters"
			        if ((reg_type == REG_SZ && size >= sizeof(guid_string) - sizeof(char))
				    || (reg_type == REG_MULTI_SZ && size >= sizeof(guid_string) - 2 * sizeof(char))) {
					if (nb_guids == guid_size) {
						new_guid_list = realloc((void *)guid_list, (guid_size + GUID_SIZE_STEP) * sizeof(void *));
						if (new_guid_list == NULL) {
							usbi_err(ctx, "failed to realloc guid list");
							LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
						}
						guid_list = new_guid_list;
						guid_size += GUID_SIZE_STEP;
					}
					if_guid = malloc(sizeof(*if_guid));
					if (if_guid == NULL) {
						usbi_err(ctx, "failed to alloc if_guid");
						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
					}
					if (!string_to_guid(guid_string, if_guid)) {
						usbi_warn(ctx, "device '%s' has malformed DeviceInterfaceGUID string '%s', skipping", dev_id, guid_string);
						free(if_guid);
					} else {
						// Check if we've already seen this GUID
						for (j = EXT_PASS; j < nb_guids; j++) {
							if (memcmp(guid_list[j], if_guid, sizeof(*if_guid)) == 0)
								break;
						}
						if (j == nb_guids) {
							usbi_dbg("extra GUID: %s", guid_string);
							guid_list[nb_guids++] = if_guid;
						} else {
							// Duplicate, ignore
							free(if_guid);
						}
					}
				} else {
					usbi_warn(ctx, "unexpected type/size of DeviceInterfaceGUID for '%s'", dev_id);
				}
				break;
			case HID_PASS:
				api = USB_API_HID;
				break;
			default:
				// Get the API type (after checking that the driver installation is OK)
				if ((!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
					NULL, (PBYTE)&install_state, sizeof(install_state), &size)) || (size != sizeof(install_state))) {
					usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
						dev_id, windows_error_str(0));
				} else if (install_state != 0) {
					usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %lu) - skipping",
						dev_id, ULONG_CAST(install_state));
					continue;
				}
				get_api_type(dev_info, &dev_info_data, &api, &sub_api);
				break;
			}

			// Find parent device (for the passes that need it)
			if (pass >= GEN_PASS) {
				parent_dev = get_ancestor(ctx, dev_info_data.DevInst, NULL);
				if (parent_dev == NULL) {
					// Root hubs will not have a parent
					dev = usbi_get_device_by_session_id(ctx, (unsigned long)dev_info_data.DevInst);
					if (dev != NULL) {
						priv = usbi_get_device_priv(dev);
						if (priv->root_hub)
							goto track_unref;
						libusb_unref_device(dev);
					}

					usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id);
					continue;
				}

				parent_priv = usbi_get_device_priv(parent_dev);
				// virtual USB devices are also listed during GEN - don't process these yet
				if ((pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB)) {
					libusb_unref_device(parent_dev);
					continue;
				}
			}

			// Create new or match existing device, using the devInst as session id
			if ((pass <= GEN_PASS) && (pass != HCD_PASS)) {	// For subsequent passes, we'll lookup the parent
				// These are the passes that create "new" devices
				session_id = (unsigned long)dev_info_data.DevInst;
				dev = usbi_get_device_by_session_id(ctx, session_id);
				if (dev == NULL) {
				alloc_device:
					usbi_dbg("allocating new device for session [%lX]", session_id);
					dev = usbi_alloc_device(ctx, session_id);
					if (dev == NULL)
						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);

					priv = winusb_device_priv_init(dev);
					priv->dev_id = _strdup(dev_id);
					priv->class_guid = dev_info_data.ClassGuid;
					if (priv->dev_id == NULL) {
						libusb_unref_device(dev);
						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
					}
				} else {
					usbi_dbg("found existing device for session [%lX]", session_id);

					priv = usbi_get_device_priv(dev);
					if (strcmp(priv->dev_id, dev_id) != 0) {
						usbi_dbg("device instance ID for session [%lX] changed", session_id);
						usbi_disconnect_device(dev);
						libusb_unref_device(dev);
						goto alloc_device;
					}
					if (!IsEqualGUID(&priv->class_guid, &dev_info_data.ClassGuid)) {
						usbi_dbg("device class GUID for session [%lX] changed", session_id);
						usbi_disconnect_device(dev);
						libusb_unref_device(dev);
						goto alloc_device;
					}
				}

			track_unref:
				// Keep track of devices that need unref
				if (unref_cur == unref_size) {
					new_unref_list = realloc(unref_list, (unref_size + UNREF_SIZE_STEP) * sizeof(void *));
					if (new_unref_list == NULL) {
						usbi_err(ctx, "could not realloc list for unref - aborting");
						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
					}
					unref_list = new_unref_list;
					unref_size += UNREF_SIZE_STEP;
				}
				unref_list[unref_cur++] = dev;
			}

			// Setup device
			switch (pass) {
			case HUB_PASS:
			case DEV_PASS:
				// If the device has already been setup, don't do it again
				if (priv->path != NULL)
					break;
				// Take care of API initialization
				priv->path = dev_interface_path;
				dev_interface_path = NULL;
				priv->apib = &usb_api_backend[api];
				priv->sub_api = sub_api;
				switch (api) {
				case USB_API_COMPOSITE:
				case USB_API_HUB:
					break;
				case USB_API_HID:
					priv->hid = calloc(1, sizeof(struct hid_device_priv));
					if (priv->hid == NULL)
						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
					break;
				default:
					// For other devices, the first interface is the same as the device
					priv->usb_interface[0].path = _strdup(priv->path);
					if (priv->usb_interface[0].path == NULL)
						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
					// The following is needed if we want API calls to work for both simple
					// and composite devices.
					for (j = 0; j < USB_MAXINTERFACES; j++)
						priv->usb_interface[j].apib = &usb_api_backend[api];
					break;
				}
				break;
			case HCD_PASS:
				r = enumerate_hcd_root_hub(ctx, dev_id, (uint8_t)(i + 1), dev_info_data.DevInst);
				break;
			case GEN_PASS:
				port_nr = 0;
				if (!get_dev_port_number(*dev_info, &dev_info_data, &port_nr))
					usbi_warn(ctx, "could not retrieve port number for device '%s': %s", dev_id, windows_error_str(0));
				r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_info_data.DevInst);
				if (r == LIBUSB_SUCCESS) {
					// Append device to the list of discovered devices
					discdevs = discovered_devs_append(*_discdevs, dev);
					if (!discdevs)
						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);

					*_discdevs = discdevs;
				} else {
					// Failed to initialize a single device doesn't stop us from enumerating all other devices,
					// but we skip it (don't add to list of discovered devices)
					usbi_warn(ctx, "failed to initialize device '%s'", priv->dev_id);
					r = LIBUSB_SUCCESS;
				}
				break;
			default: // HID_PASS and later
				if (parent_priv->apib->id == USB_API_HID || parent_priv->apib->id == USB_API_COMPOSITE) {
					if (parent_priv->apib->id == USB_API_HID) {
						usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
						r = set_hid_interface(ctx, parent_dev, dev_interface_path);
					} else {
						usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
						r = set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id, api, sub_api);
					}
					switch (r) {
					case LIBUSB_SUCCESS:
						dev_interface_path = NULL;
						break;
					case LIBUSB_ERROR_ACCESS:
						// interface has already been set => make sure dev_interface_path is freed then
						r = LIBUSB_SUCCESS;
						break;
					default:
						LOOP_BREAK(r);
						break;
					}
				}
				libusb_unref_device(parent_dev);
				break;
			}
		}
	}

	pSetupDiDestroyDeviceInfoList(dev_info_intf);

	// Free any additional GUIDs
	for (pass = EXT_PASS; pass < nb_guids; pass++)
		free((void *)guid_list[pass]);
	free((void *)guid_list);

	// Free any PnP enumerator strings
	for (i = 1; i < nb_usb_enumerators; i++)
		free((void *)usb_enumerator[i]);

	// Unref newly allocated devs
	for (i = 0; i < unref_cur; i++)
		libusb_unref_device(unref_list[i]);
	free(unref_list);

	return r;
}

static int winusb_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	PUSB_CONFIGURATION_DESCRIPTOR config_header;

	if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
		return LIBUSB_ERROR_NOT_FOUND;

	config_header = priv->config_descriptor[config_index];

	len = MIN(len, config_header->wTotalLength);
	memcpy(buffer, config_header, len);
	return (int)len;
}

static int winusb_get_config_descriptor_by_value(struct libusb_device *dev, uint8_t bConfigurationValue,
	void **buffer)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	PUSB_CONFIGURATION_DESCRIPTOR config_header;
	uint8_t index;

	if (priv->config_descriptor == NULL)
		return LIBUSB_ERROR_NOT_FOUND;

	for (index = 0; index < dev->device_descriptor.bNumConfigurations; index++) {
		config_header = priv->config_descriptor[index];
		if (config_header == NULL)
			continue;
		if (config_header->bConfigurationValue == bConfigurationValue) {
			*buffer = config_header;
			return (int)config_header->wTotalLength;
		}
	}

	return LIBUSB_ERROR_NOT_FOUND;
}

/*
 * return the cached copy of the active config descriptor
 */
static int winusb_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	void *config_desc;
	int r;

	if (priv->active_config == 0)
		return LIBUSB_ERROR_NOT_FOUND;

	r = winusb_get_config_descriptor_by_value(dev, priv->active_config, &config_desc);
	if (r < 0)
		return r;

	len = MIN(len, (size_t)r);
	memcpy(buffer, config_desc, len);
	return (int)len;
}

static int winusb_open(struct libusb_device_handle *dev_handle)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	CHECK_SUPPORTED_API(priv->apib, open);

	return priv->apib->open(SUB_API_NOTSET, dev_handle);
}

static void winusb_close(struct libusb_device_handle *dev_handle)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	if (priv->apib->close)
		priv->apib->close(SUB_API_NOTSET, dev_handle);
}

static int winusb_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	*config = priv->active_config;
	return LIBUSB_SUCCESS;
}

/*
 * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
 * does not currently expose a service that allows higher-level drivers to set
 * the configuration."
 */
static int winusb_set_configuration(struct libusb_device_handle *dev_handle, uint8_t config)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	int r = LIBUSB_SUCCESS;

	r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
		LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
		LIBUSB_REQUEST_SET_CONFIGURATION, config,
		0, NULL, 0, 1000);

	if (r == LIBUSB_SUCCESS)
		priv->active_config = config;

	return r;
}

static int winusb_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	int r;

	CHECK_SUPPORTED_API(priv->apib, claim_interface);

	safe_free(priv->usb_interface[iface].endpoint);
	priv->usb_interface[iface].nb_endpoints = 0;

	r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);

	if (r == LIBUSB_SUCCESS)
		r = windows_assign_endpoints(dev_handle, iface, 0);

	return r;
}

static int winusb_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	int r;

	CHECK_SUPPORTED_API(priv->apib, set_interface_altsetting);

	safe_free(priv->usb_interface[iface].endpoint);
	priv->usb_interface[iface].nb_endpoints = 0;

	r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);

	if (r == LIBUSB_SUCCESS)
		r = windows_assign_endpoints(dev_handle, iface, altsetting);

	return r;
}

static int winusb_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	CHECK_SUPPORTED_API(priv->apib, release_interface);

	return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
}

static int winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	CHECK_SUPPORTED_API(priv->apib, clear_halt);

	return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
}

static int winusb_reset_device(struct libusb_device_handle *dev_handle)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	CHECK_SUPPORTED_API(priv->apib, reset_device);

	return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
}

static void winusb_destroy_device(struct libusb_device *dev)
{
	winusb_device_priv_release(dev);
}

static void winusb_clear_transfer_priv(struct usbi_transfer *itransfer)
{
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	int sub_api = priv->sub_api;

	safe_free(transfer_priv->hid_buffer);

	if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS && sub_api == SUB_API_WINUSB) {
		if (transfer_priv->isoch_buffer_handle != NULL) {
			if (WinUSBX[sub_api].UnregisterIsochBuffer(transfer_priv->isoch_buffer_handle)) {
				transfer_priv->isoch_buffer_handle = NULL;
			} else {
				usbi_warn(TRANSFER_CTX(transfer), "failed to unregister WinUSB isoch buffer: %s", windows_error_str(0));
			}
		}
	}

	safe_free(transfer_priv->iso_context);

	// When auto claim is in use, attempt to release the auto-claimed interface
	auto_release(itransfer);
}

static int winusb_submit_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	int (*transfer_fn)(int, struct usbi_transfer *);

	switch (transfer->type) {
	case LIBUSB_TRANSFER_TYPE_CONTROL:
		transfer_fn = priv->apib->submit_control_transfer;
		break;
	case LIBUSB_TRANSFER_TYPE_BULK:
	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
		transfer_fn = priv->apib->submit_bulk_transfer;
		break;
	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
		transfer_fn = priv->apib->submit_iso_transfer;
		break;
	default:
		// Should not get here since windows_submit_transfer() validates
		// the transfer->type field
		usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	if (transfer_fn == NULL) {
		usbi_warn(TRANSFER_CTX(transfer),
			"unsupported transfer type %d (unrecognized device driver)",
			transfer->type);
		return LIBUSB_ERROR_NOT_SUPPORTED;
	}

	return transfer_fn(SUB_API_NOTSET, itransfer);
}

static int winusb_cancel_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);

	CHECK_SUPPORTED_API(priv->apib, cancel_transfer);

	return priv->apib->cancel_transfer(SUB_API_NOTSET, itransfer);
}

static enum libusb_transfer_status winusb_copy_transfer_data(struct usbi_transfer *itransfer, DWORD length)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);

	if (priv->apib->copy_transfer_data == NULL) {
		usbi_err(TRANSFER_CTX(transfer), "program assertion failed - no function to copy transfer data");
		return LIBUSB_TRANSFER_ERROR;
	}

	return priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, length);
}

// NB: MSVC6 does not support named initializers.
const struct windows_backend winusb_backend = {
	winusb_init,
	winusb_exit,
	winusb_get_device_list,
	winusb_open,
	winusb_close,
	winusb_get_active_config_descriptor,
	winusb_get_config_descriptor,
	winusb_get_config_descriptor_by_value,
	winusb_get_configuration,
	winusb_set_configuration,
	winusb_claim_interface,
	winusb_release_interface,
	winusb_set_interface_altsetting,
	winusb_clear_halt,
	winusb_reset_device,
	winusb_destroy_device,
	winusb_submit_transfer,
	winusb_cancel_transfer,
	winusb_clear_transfer_priv,
	winusb_copy_transfer_data,
};

/*
 * USB API backends
 */

static const char * const composite_driver_names[] = {"USBCCGP"};
static const char * const winusbx_driver_names[] = {"libusbK", "libusb0", "WinUSB"};
static const char * const hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
	{
		USB_API_UNSUPPORTED,
		"Unsupported API",
		NULL,	/* driver_name_list */
		0,	/* nb_driver_names */
		NULL,	/* init */
		NULL,	/* exit */
		NULL,	/* open */
		NULL,	/* close */
		NULL,	/* configure_endpoints */
		NULL,	/* claim_interface */
		NULL,	/* set_interface_altsetting */
		NULL,	/* release_interface */
		NULL,	/* clear_halt */
		NULL,	/* reset_device */
		NULL,	/* submit_bulk_transfer */
		NULL,	/* submit_iso_transfer */
		NULL,	/* submit_control_transfer */
		NULL,	/* cancel_transfer */
		NULL,	/* copy_transfer_data */
	},
	{
		USB_API_HUB,
		"HUB API",
		NULL,	/* driver_name_list */
		0,	/* nb_driver_names */
		NULL,	/* init */
		NULL,	/* exit */
		NULL,	/* open */
		NULL,	/* close */
		NULL,	/* configure_endpoints */
		NULL,	/* claim_interface */
		NULL,	/* set_interface_altsetting */
		NULL,	/* release_interface */
		NULL,	/* clear_halt */
		NULL,	/* reset_device */
		NULL,	/* submit_bulk_transfer */
		NULL,	/* submit_iso_transfer */
		NULL,	/* submit_control_transfer */
		NULL,	/* cancel_transfer */
		NULL,	/* copy_transfer_data */
	},
	{
		USB_API_COMPOSITE,
		"Composite API",
		composite_driver_names,
		ARRAYSIZE(composite_driver_names),
		NULL,	/* init */
		NULL,	/* exit */
		composite_open,
		composite_close,
		NULL,	/* configure_endpoints */
		composite_claim_interface,
		composite_set_interface_altsetting,
		composite_release_interface,
		composite_clear_halt,
		composite_reset_device,
		composite_submit_bulk_transfer,
		composite_submit_iso_transfer,
		composite_submit_control_transfer,
		composite_cancel_transfer,
		composite_copy_transfer_data,
	},
	{
		USB_API_WINUSBX,
		"WinUSB-like APIs",
		winusbx_driver_names,
		ARRAYSIZE(winusbx_driver_names),
		winusbx_init,
		winusbx_exit,
		winusbx_open,
		winusbx_close,
		winusbx_configure_endpoints,
		winusbx_claim_interface,
		winusbx_set_interface_altsetting,
		winusbx_release_interface,
		winusbx_clear_halt,
		winusbx_reset_device,
		winusbx_submit_bulk_transfer,
		winusbx_submit_iso_transfer,
		winusbx_submit_control_transfer,
		winusbx_cancel_transfer,
		winusbx_copy_transfer_data,
	},
	{
		USB_API_HID,
		"HID API",
		hid_driver_names,
		ARRAYSIZE(hid_driver_names),
		hid_init,
		hid_exit,
		hid_open,
		hid_close,
		NULL,	/* configure_endpoints */
		hid_claim_interface,
		hid_set_interface_altsetting,
		hid_release_interface,
		hid_clear_halt,
		hid_reset_device,
		hid_submit_bulk_transfer,
		NULL,	/* submit_iso_transfer */
		hid_submit_control_transfer,
		NULL,	/* cancel_transfer */
		hid_copy_transfer_data,
	},
};


/*
 * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
 */
#define WinUSB_Set(h, fn, required)										\
	do {											\
		WinUSBX[SUB_API_WINUSB].fn = (WinUsb_##fn##_t)GetProcAddress(h, "WinUsb_" #fn);	\
		if (required && (WinUSBX[SUB_API_WINUSB].fn == NULL)) {				\
			usbi_err(ctx, "GetProcAddress() failed for WinUsb_%s", #fn);		\
			goto cleanup_winusb;							\
		}										\
	} while (0)

#define libusbK_Set(sub_api, fn, required)								\
	do {											\
		pLibK_GetProcAddress((PVOID *)&WinUSBX[sub_api].fn, sub_api, KUSB_FNID_##fn);	\
		if (required && (WinUSBX[sub_api].fn == NULL)) {				\
			usbi_err(ctx, "LibK_GetProcAddress() failed for LibK_%s", #fn);		\
			goto cleanup_libusbk;							\
		}										\
	} while (0)

static bool winusbx_init(struct libusb_context *ctx)
{
	HMODULE hWinUSB, hlibusbK;

	hWinUSB = load_system_library(ctx, "WinUSB");
	if (hWinUSB != NULL) {
		WinUSB_Set(hWinUSB, AbortPipe, true);
		WinUSB_Set(hWinUSB, ControlTransfer, true);
		WinUSB_Set(hWinUSB, FlushPipe, true);
		WinUSB_Set(hWinUSB, Free, true);
		WinUSB_Set(hWinUSB, GetAssociatedInterface, true);
		WinUSB_Set(hWinUSB, Initialize, true);
		WinUSB_Set(hWinUSB, ReadPipe, true);
		WinUSB_Set(hWinUSB, ResetPipe, true);
		WinUSB_Set(hWinUSB, SetCurrentAlternateSetting, true);
		WinUSB_Set(hWinUSB, SetPipePolicy, true);
		WinUSB_Set(hWinUSB, WritePipe, true);

		// Check for isochronous transfers support (available starting with Windows 8.1)
		WinUSB_Set(hWinUSB, ReadIsochPipeAsap, false);
		if (WinUSBX[SUB_API_WINUSB].ReadIsochPipeAsap != NULL) {
			WinUSB_Set(hWinUSB, QueryPipeEx, true);
			WinUSB_Set(hWinUSB, RegisterIsochBuffer, true);
			WinUSB_Set(hWinUSB, UnregisterIsochBuffer, true);
			WinUSB_Set(hWinUSB, WriteIsochPipeAsap, true);
		}

		WinUSBX[SUB_API_WINUSB].hDll = hWinUSB;

		usbi_info(ctx, "WinUSB DLL available (%s isoch support)",
			(WinUSBX[SUB_API_WINUSB].ReadIsochPipeAsap != NULL) ? "with" : "without");

cleanup_winusb:
		if (WinUSBX[SUB_API_WINUSB].hDll == NULL) {
			usbi_err(ctx, "failed to initialize WinUSB");
			memset(&WinUSBX[SUB_API_WINUSB], 0, sizeof(WinUSBX[SUB_API_WINUSB]));
			FreeLibrary(hWinUSB);
			hWinUSB = NULL;
		}
	} else {
		usbi_info(ctx, "WinUSB DLL is not available");
	}

	hlibusbK = load_system_library(ctx, "libusbK");
	if (hlibusbK != NULL) {
		LibK_GetVersion_t pLibK_GetVersion;
		LibK_GetProcAddress_t pLibK_GetProcAddress;
		int sub_api = 0;

		pLibK_GetVersion = (LibK_GetVersion_t)GetProcAddress(hlibusbK, "LibK_GetVersion");
		if (pLibK_GetVersion != NULL) {
			KLIB_VERSION LibK_Version;

			pLibK_GetVersion(&LibK_Version);
			usbi_dbg("libusbK DLL found, version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
				LibK_Version.Micro, LibK_Version.Nano);
		} else {
			usbi_dbg("libusbK DLL found, version unknown");
		}

		pLibK_GetProcAddress = (LibK_GetProcAddress_t)GetProcAddress(hlibusbK, "LibK_GetProcAddress");
		if (pLibK_GetProcAddress == NULL) {
			usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
			goto cleanup_libusbk;
		}

		// NB: The below for loop works because the sub_api value for WinUSB
		// is a higher value than that of libusbK and libusb0
		for (; sub_api < SUB_API_WINUSB; sub_api++) {
			libusbK_Set(sub_api, AbortPipe, true);
			libusbK_Set(sub_api, ControlTransfer, true);
			libusbK_Set(sub_api, FlushPipe, true);
			libusbK_Set(sub_api, Free, true);
			libusbK_Set(sub_api, GetAssociatedInterface, true);
			libusbK_Set(sub_api, Initialize, true);
			libusbK_Set(sub_api, ReadPipe, true);
			libusbK_Set(sub_api, ResetPipe, true);
			libusbK_Set(sub_api, SetCurrentAlternateSetting, true);
			libusbK_Set(sub_api, SetPipePolicy, true);
			libusbK_Set(sub_api, WritePipe, true);

			// Optional isochronous support
			libusbK_Set(sub_api, IsoReadPipe, false);
			if (WinUSBX[sub_api].IsoReadPipe != NULL)
				libusbK_Set(sub_api, IsoWritePipe, true);

			// Optional device reset support
			libusbK_Set(sub_api, ResetDevice, false);

			WinUSBX[sub_api].hDll = hlibusbK;
		}

cleanup_libusbk:
		if (sub_api < SUB_API_WINUSB) {
			usbi_err(ctx, "failed to initialize libusbK");
			while (sub_api >= 0) {
				memset(&WinUSBX[sub_api], 0, sizeof(WinUSBX[sub_api]));
				sub_api--;
			}
			FreeLibrary(hlibusbK);
			hlibusbK = NULL;
		}
	} else {
		usbi_info(ctx, "libusbK DLL is not available");
	}

	if ((hWinUSB == NULL) && (hlibusbK == NULL)) {
		usbi_warn(ctx, "neither WinUSB nor libusbK DLLs were found, "
			"you will not be able to access devices outside of enumeration");
		return false;
	}

	return true;
}

static void winusbx_exit(void)
{
	bool loaded = false;
	HMODULE hDll;

	hDll = WinUSBX[SUB_API_LIBUSBK].hDll;
	if (hDll != NULL) {
		FreeLibrary(hDll);
		loaded = true;
	}

	hDll = WinUSBX[SUB_API_WINUSB].hDll;
	if (hDll != NULL) {
		FreeLibrary(hDll);
		loaded = true;
	}

	// Reset the WinUSBX API structures if something was loaded
	if (loaded)
		memset(&WinUSBX, 0, sizeof(WinUSBX));
}

// NB: open and close must ensure that they only handle interface of
// the right API type, as these functions can be called wholesale from
// composite_open(), with interfaces belonging to different APIs
static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	HANDLE file_handle;
	int i;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	// WinUSB requires a separate handle for each interface
	for (i = 0; i < USB_MAXINTERFACES; i++) {
		if ((priv->usb_interface[i].path != NULL)
				&& (priv->usb_interface[i].apib->id == USB_API_WINUSBX)) {
			file_handle = windows_open(dev_handle, priv->usb_interface[i].path, GENERIC_READ | GENERIC_WRITE);
			if (file_handle == INVALID_HANDLE_VALUE) {
				usbi_err(HANDLE_CTX(dev_handle), "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
				switch (GetLastError()) {
				case ERROR_FILE_NOT_FOUND: // The device was disconnected
					return LIBUSB_ERROR_NO_DEVICE;
				case ERROR_ACCESS_DENIED:
					return LIBUSB_ERROR_ACCESS;
				default:
					return LIBUSB_ERROR_IO;
				}
			}

			handle_priv->interface_handle[i].dev_handle = file_handle;
		}
	}

	return LIBUSB_SUCCESS;
}

static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	HANDLE handle;
	int i;

	if (sub_api == SUB_API_NOTSET)
		sub_api = priv->sub_api;

	if (WinUSBX[sub_api].hDll == NULL)
		return;

	if (priv->apib->id == USB_API_COMPOSITE) {
		// If this is a composite device, just free and close all WinUSB-like
		// interfaces directly (each is independent and not associated with another)
		for (i = 0; i < USB_MAXINTERFACES; i++) {
			if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
				handle = handle_priv->interface_handle[i].api_handle;
				if (HANDLE_VALID(handle))
					WinUSBX[sub_api].Free(handle);

				handle = handle_priv->interface_handle[i].dev_handle;
				if (HANDLE_VALID(handle))
					CloseHandle(handle);
			}
		}
	} else {
		// If this is a WinUSB device, free all interfaces above interface 0,
		// then free and close interface 0 last
		for (i = 1; i < USB_MAXINTERFACES; i++) {
			handle = handle_priv->interface_handle[i].api_handle;
			if (HANDLE_VALID(handle))
				WinUSBX[sub_api].Free(handle);
		}
		handle = handle_priv->interface_handle[0].api_handle;
		if (HANDLE_VALID(handle))
			WinUSBX[sub_api].Free(handle);

		handle = handle_priv->interface_handle[0].dev_handle;
		if (HANDLE_VALID(handle))
			CloseHandle(handle);
	}
}

static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
	UCHAR policy;
	ULONG timeout = 0;
	uint8_t endpoint_address;
	int i;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	// With handle and endpoints set (in parent), we can setup the default pipe properties
	// see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
	for (i = -1; i < priv->usb_interface[iface].nb_endpoints; i++) {
		endpoint_address = (i == -1) ? 0 : priv->usb_interface[iface].endpoint[i];
		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
			PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout))
			usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);

		if ((i == -1) || (sub_api == SUB_API_LIBUSB0))
			continue; // Other policies don't apply to control endpoint or libusb0

		policy = false;
		handle_priv->interface_handle[iface].zlp[endpoint_address] = WINUSB_ZLP_UNSET;
		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
			SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy))
			usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);

		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
			IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy))
			usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);

		policy = true;
		/* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
		   https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
			ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy))
			usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);

		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
			AUTO_CLEAR_STALL, sizeof(UCHAR), &policy))
			usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);

		if (sub_api == SUB_API_LIBUSBK) {
			if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
				ISO_ALWAYS_START_ASAP, sizeof(UCHAR), &policy))
				usbi_dbg("failed to enable ISO_ALWAYS_START_ASAP for endpoint %02X", endpoint_address);
		}
	}

	return LIBUSB_SUCCESS;
}

static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct libusb_context *ctx = HANDLE_CTX(dev_handle);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
	HDEVINFO dev_info;
	char *dev_interface_path = NULL;
	char *dev_interface_path_guid_start;
	char filter_path[] = "\\\\.\\libusb0-0000";
	bool found_filter = false;
	HANDLE file_handle, winusb_handle;
	DWORD err, _index;
	int r;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	// If the device is composite, but using the default Windows composite parent driver (usbccgp)
	// or if it's the first WinUSB-like interface, we get a handle through Initialize().
	if ((is_using_usbccgp) || (iface == 0)) {
		// composite device (independent interfaces) or interface 0
		file_handle = handle_priv->interface_handle[iface].dev_handle;
		if (!HANDLE_VALID(file_handle))
			return LIBUSB_ERROR_NOT_FOUND;

		if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
			handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
			err = GetLastError();
			switch (err) {
			case ERROR_BAD_COMMAND:
				// The device was disconnected
				usbi_err(ctx, "could not access interface %u: %s", iface, windows_error_str(0));
				return LIBUSB_ERROR_NO_DEVICE;
			default:
				// it may be that we're using the libusb0 filter driver.
				// TODO: can we move this whole business into the K/0 DLL?
				r = LIBUSB_SUCCESS;
				for (_index = 0; ; _index++) {
					safe_free(dev_interface_path);

					if (found_filter)
						break;

					r = get_interface_details_filter(ctx, &dev_info, _index, filter_path, &dev_interface_path);
					if ((r != LIBUSB_SUCCESS) || (dev_interface_path == NULL))
						break;

					// ignore GUID part
					dev_interface_path_guid_start = strchr(dev_interface_path, '{');
					if (dev_interface_path_guid_start == NULL)
						continue;
					*dev_interface_path_guid_start = '\0';

					if (strncmp(dev_interface_path, priv->usb_interface[iface].path, strlen(dev_interface_path)) == 0) {
						file_handle = windows_open(dev_handle, filter_path, GENERIC_READ | GENERIC_WRITE);
						if (file_handle != INVALID_HANDLE_VALUE) {
							if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
								// Replace the existing file handle with the working one
								CloseHandle(handle_priv->interface_handle[iface].dev_handle);
								handle_priv->interface_handle[iface].dev_handle = file_handle;
								found_filter = true;
							} else {
								usbi_err(ctx, "could not initialize filter driver for %s", filter_path);
								CloseHandle(file_handle);
							}
						} else {
							usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
						}
					}
				}
				if (r != LIBUSB_SUCCESS)
					return r;
				if (!found_filter) {
					usbi_err(ctx, "could not access interface %u: %s", iface, windows_error_str(err));
					return LIBUSB_ERROR_ACCESS;
				}
			}
		}
		handle_priv->interface_handle[iface].api_handle = winusb_handle;
	} else {
		// For all other interfaces, use GetAssociatedInterface()
		winusb_handle = handle_priv->interface_handle[0].api_handle;
		// It is a requirement for multiple interface devices on Windows that, to you
		// must first claim the first interface before you claim the others
		if (!HANDLE_VALID(winusb_handle)) {
			file_handle = handle_priv->interface_handle[0].dev_handle;
			if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
				handle_priv->interface_handle[0].api_handle = winusb_handle;
				usbi_warn(ctx, "auto-claimed interface 0 (required to claim %u with WinUSB)", iface);
			} else {
				usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %u with WinUSB): %s", iface, windows_error_str(0));
				return LIBUSB_ERROR_ACCESS;
			}
		}
		if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface - 1),
			&handle_priv->interface_handle[iface].api_handle)) {
			handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
			switch (GetLastError()) {
			case ERROR_NO_MORE_ITEMS:   // invalid iface
				return LIBUSB_ERROR_NOT_FOUND;
			case ERROR_BAD_COMMAND:     // The device was disconnected
				return LIBUSB_ERROR_NO_DEVICE;
			case ERROR_ALREADY_EXISTS:  // already claimed
				return LIBUSB_ERROR_BUSY;
			default:
				usbi_err(ctx, "could not claim interface %u: %s", iface, windows_error_str(0));
				return LIBUSB_ERROR_ACCESS;
			}
		}
		handle_priv->interface_handle[iface].dev_handle = handle_priv->interface_handle[0].dev_handle;
	}
	usbi_dbg("claimed interface %u", iface);
	handle_priv->active_interface = iface;

	return LIBUSB_SUCCESS;
}

static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	HANDLE winusb_handle;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	winusb_handle = handle_priv->interface_handle[iface].api_handle;
	if (!HANDLE_VALID(winusb_handle))
		return LIBUSB_ERROR_NOT_FOUND;

	WinUSBX[sub_api].Free(winusb_handle);
	handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;

	return LIBUSB_SUCCESS;
}

/*
 * Return the first valid interface (of the same API type), for control transfers
 */
static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	int i;

	if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
		usbi_dbg("unsupported API ID");
		return -1;
	}

	for (i = 0; i < USB_MAXINTERFACES; i++) {
	if (HANDLE_VALID(handle_priv->interface_handle[i].dev_handle)
			&& HANDLE_VALID(handle_priv->interface_handle[i].api_handle)
			&& (priv->usb_interface[i].apib->id == api_id))
		return i;
	}

	return -1;
}

/*
* Check a specific interface is valid (of the same API type), for control transfers
*/
static int check_valid_interface(struct libusb_device_handle *dev_handle, unsigned short interface, int api_id)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	if (interface >= USB_MAXINTERFACES)
		return -1;

	if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
		usbi_dbg("unsupported API ID");
		return -1;
	}

	// try the requested interface
	if (HANDLE_VALID(handle_priv->interface_handle[interface].dev_handle)
		&& HANDLE_VALID(handle_priv->interface_handle[interface].api_handle)
		&& (priv->usb_interface[interface].apib->id == api_id))
		return interface;

	return -1;
}

/*
 * Lookup interface by endpoint address. -1 if not found
 */
static int interface_by_endpoint(struct winusb_device_priv *priv,
	struct winusb_device_handle_priv *handle_priv, uint8_t endpoint_address)
{
	int i, j;

	for (i = 0; i < USB_MAXINTERFACES; i++) {
		if (!HANDLE_VALID(handle_priv->interface_handle[i].api_handle))
			continue;
		if (priv->usb_interface[i].endpoint == NULL)
			continue;
		for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) {
			if (priv->usb_interface[i].endpoint[j] == endpoint_address)
				return i;
		}
	}

	return -1;
}

static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
	PWINUSB_SETUP_PACKET setup = (PWINUSB_SETUP_PACKET)transfer->buffer;
	ULONG size;
	HANDLE winusb_handle;
	OVERLAPPED *overlapped;
	int current_interface;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;

	// Windows places upper limits on the control transfer size
	// See: https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-bandwidth-allocation#maximum-transfer-size
	if (size > MAX_CTRL_BUFFER_LENGTH)
		return LIBUSB_ERROR_INVALID_PARAM;

	if ((setup->RequestType & 0x1F) == LIBUSB_RECIPIENT_INTERFACE)
		current_interface = check_valid_interface(transfer->dev_handle, setup->Index & 0xff, USB_API_WINUSBX);
	else
		current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
	if (current_interface < 0) {
		if (auto_claim(transfer, &current_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS)
			return LIBUSB_ERROR_NOT_FOUND;
	}

	usbi_dbg("will use interface %d", current_interface);

	winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
	set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
	overlapped = get_transfer_priv_overlapped(itransfer);

	// Sending of set configuration control requests from WinUSB creates issues, except when using libusb0.sys
	if (sub_api != SUB_API_LIBUSB0
			&& (LIBUSB_REQ_TYPE(setup->RequestType) == LIBUSB_REQUEST_TYPE_STANDARD)
			&& (setup->Request == LIBUSB_REQUEST_SET_CONFIGURATION)) {
		if (setup->Value != priv->active_config) {
			usbi_warn(TRANSFER_CTX(transfer), "cannot set configuration other than the default one");
			return LIBUSB_ERROR_NOT_SUPPORTED;
		}
		windows_force_sync_completion(itransfer, 0);
	} else {
		if (!WinUSBX[sub_api].ControlTransfer(winusb_handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, overlapped)) {
			if (GetLastError() != ERROR_IO_PENDING) {
				usbi_warn(TRANSFER_CTX(transfer), "ControlTransfer failed: %s", windows_error_str(0));
				return LIBUSB_ERROR_IO;
			}
		}
	}

	transfer_priv->interface_number = (uint8_t)current_interface;

	return LIBUSB_SUCCESS;
}

static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	HANDLE winusb_handle;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	winusb_handle = handle_priv->interface_handle[iface].api_handle;
	if (!HANDLE_VALID(winusb_handle)) {
		usbi_err(HANDLE_CTX(dev_handle), "interface must be claimed first");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, altsetting)) {
		usbi_err(HANDLE_CTX(dev_handle), "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_IO;
	}

	return LIBUSB_SUCCESS;
}


static void WINAPI winusbx_native_iso_transfer_continue_stream_callback(struct libusb_transfer *transfer)
{
	// If this callback is invoked, this means that we attempted to set ContinueStream
	// to TRUE when calling Read/WriteIsochPipeAsap in winusbx_do_iso_transfer.
	// The role of this callback is to fallback to ContinueStream = FALSE if the transfer
	// did not succeed.

	struct winusb_transfer_priv *transfer_priv =
		get_winusb_transfer_priv(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer));
	bool fallback = (transfer->status != LIBUSB_TRANSFER_COMPLETED);
	int idx;

	// Restore the user callback
	transfer->callback = transfer_priv->iso_user_callback;

	for (idx = 0; idx < transfer->num_iso_packets && !fallback; idx++) {
		if (transfer->iso_packet_desc[idx].status != LIBUSB_TRANSFER_COMPLETED)
			fallback = true;
	}

	if (!fallback) {
		// If the transfer was successful, we restore the user callback and call it.
		if (transfer->callback)
			transfer->callback(transfer);
	} else {
		// If the transfer wasn't successful we reschedule the transfer while forcing it
		// not to continue the stream. This might results in a 5-ms delay.
		transfer_priv->iso_break_stream = TRUE;
		libusb_submit_transfer(transfer);
	}
}
static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	HANDLE winusb_handle;
	OVERLAPPED *overlapped;
	BOOL ret;
	int current_interface;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
	if (current_interface < 0) {
		usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);

	winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
	set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
	overlapped = get_transfer_priv_overlapped(itransfer);

	if ((sub_api == SUB_API_LIBUSBK) || (sub_api == SUB_API_LIBUSB0)) {
		int i;
		UINT offset;
		size_t iso_ctx_size;
		PKISO_CONTEXT iso_context;

		if (WinUSBX[sub_api].IsoReadPipe == NULL) {
			usbi_warn(TRANSFER_CTX(transfer), "libusbK DLL does not support isoch transfers");
			return LIBUSB_ERROR_NOT_SUPPORTED;
		}

		iso_ctx_size = sizeof(KISO_CONTEXT) + (transfer->num_iso_packets * sizeof(KISO_PACKET));
		transfer_priv->iso_context = iso_context = calloc(1, iso_ctx_size);
		if (transfer_priv->iso_context == NULL)
			return LIBUSB_ERROR_NO_MEM;

		// start ASAP
		iso_context->StartFrame = 0;
		iso_context->NumberOfPackets = (SHORT)transfer->num_iso_packets;

		// convert the transfer packet lengths to iso_packet offsets
		offset = 0;
		for (i = 0; i < transfer->num_iso_packets; i++) {
			iso_context->IsoPackets[i].offset = offset;
			offset += transfer->iso_packet_desc[i].length;
		}

		if (IS_XFERIN(transfer)) {
			usbi_dbg("reading %d iso packets", transfer->num_iso_packets);
			ret = WinUSBX[sub_api].IsoReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context);
		} else {
			usbi_dbg("writing %d iso packets", transfer->num_iso_packets);
			ret = WinUSBX[sub_api].IsoWritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context);
		}

		if (!ret && GetLastError() != ERROR_IO_PENDING) {
			usbi_err(TRANSFER_CTX(transfer), "IsoReadPipe/IsoWritePipe failed: %s", windows_error_str(0));
			return LIBUSB_ERROR_IO;
		}

		transfer_priv->interface_number = (uint8_t)current_interface;

		return LIBUSB_SUCCESS;
	} else if (sub_api == SUB_API_WINUSB) {
		WINUSB_PIPE_INFORMATION_EX pipe_info_ex = { 0 };
		WINUSB_ISOCH_BUFFER_HANDLE buffer_handle;
		ULONG iso_transfer_size_multiple;
		int out_transfer_length = 0;
		int idx;

		// Depending on the version of Microsoft WinUSB, isochronous transfers may not be supported.
		if (WinUSBX[sub_api].ReadIsochPipeAsap == NULL) {
			usbi_warn(TRANSFER_CTX(transfer), "WinUSB DLL does not support isoch transfers");
			return LIBUSB_ERROR_NOT_SUPPORTED;
		}

		if (sizeof(struct libusb_iso_packet_descriptor) != sizeof(USBD_ISO_PACKET_DESCRIPTOR)) {
			usbi_err(TRANSFER_CTX(transfer), "size of WinUsb and libusb isoch packet descriptors don't match");
			return LIBUSB_ERROR_NOT_SUPPORTED;
		}

		// Query the pipe extended information to find the pipe index corresponding to the endpoint.
		for (idx = 0; idx < priv->usb_interface[current_interface].nb_endpoints; ++idx) {
			ret = WinUSBX[sub_api].QueryPipeEx(winusb_handle, (UINT8)priv->usb_interface[current_interface].current_altsetting, (UCHAR)idx, &pipe_info_ex);
			if (!ret) {
				usbi_err(TRANSFER_CTX(transfer), "couldn't query interface settings for USB pipe with index %d. Error: %s", idx, windows_error_str(0));
				return LIBUSB_ERROR_NOT_FOUND;
			}

			if (pipe_info_ex.PipeId == transfer->endpoint && pipe_info_ex.PipeType == UsbdPipeTypeIsochronous)
				break;
		}

		// Make sure we found the index.
		if (idx == priv->usb_interface[current_interface].nb_endpoints) {
			usbi_err(TRANSFER_CTX(transfer), "couldn't find isoch endpoint 0x%02x", transfer->endpoint);
			return LIBUSB_ERROR_NOT_FOUND;
		}

		if (IS_XFERIN(transfer)) {
			int interval = pipe_info_ex.Interval;

			// For high-speed and SuperSpeed device, the interval is 2**(bInterval-1).
			if (transfer->dev_handle->dev->speed >= LIBUSB_SPEED_HIGH)
				interval = (1 << (pipe_info_ex.Interval - 1));

			// WinUSB only supports isoch transfers spanning a full USB frames. Later, we might be smarter about this
			// and allocate a temporary buffer. However, this is harder than it seems as its destruction would depend on overlapped
			// IO...
			iso_transfer_size_multiple = (pipe_info_ex.MaximumBytesPerInterval * 8) / interval;
			if (transfer->length % iso_transfer_size_multiple != 0) {
				usbi_err(TRANSFER_CTX(transfer), "length of isoch buffer must be a multiple of the MaximumBytesPerInterval * 8 / Interval");
				return LIBUSB_ERROR_INVALID_PARAM;
			}
		} else {
			// If this is an OUT transfer, we make sure the isoch packets are contiguous as this isn't supported otherwise.
			bool size_should_be_zero = false;

			for (idx = 0; idx < transfer->num_iso_packets; ++idx) {
				if ((size_should_be_zero && transfer->iso_packet_desc[idx].length != 0) ||
					(transfer->iso_packet_desc[idx].length != pipe_info_ex.MaximumBytesPerInterval && idx + 1 < transfer->num_iso_packets && transfer->iso_packet_desc[idx + 1].length > 0)) {
					usbi_err(TRANSFER_CTX(transfer), "isoch packets for OUT transfer with WinUSB must be contiguous in memory");
					return LIBUSB_ERROR_INVALID_PARAM;
				}

				size_should_be_zero = (transfer->iso_packet_desc[idx].length == 0);
				out_transfer_length += transfer->iso_packet_desc[idx].length;
			}
		}

		if (transfer_priv->isoch_buffer_handle != NULL) {
			if (WinUSBX[sub_api].UnregisterIsochBuffer(transfer_priv->isoch_buffer_handle)) {
				transfer_priv->isoch_buffer_handle = NULL;
			} else {
				usbi_err(TRANSFER_CTX(transfer), "failed to unregister WinUSB isoch buffer: %s", windows_error_str(0));
				return LIBUSB_ERROR_OTHER;
			}
		}

		// Register the isoch buffer to the operating system.
		ret = WinUSBX[sub_api].RegisterIsochBuffer(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, &buffer_handle);
		if (!ret) {
			usbi_err(TRANSFER_CTX(transfer), "failed to register WinUSB isoch buffer: %s", windows_error_str(0));
			return LIBUSB_ERROR_NO_MEM;
		}

		// Important note: the WinUSB_Read/WriteIsochPipeAsap API requires a ContinueStream parameter that tells whether the isochronous
		// stream must be continued or if the WinUSB driver can schedule the transfer at its convenience. Profiling subsequent transfers
		// with ContinueStream = FALSE showed that 5 frames, i.e. about 5 milliseconds, were left empty between each transfer. This
		// is critical as this greatly diminish the achievable isochronous bandwidth. We solved the problem using the following strategy:
		// - Transfers are first scheduled with ContinueStream = TRUE and with winusbx_iso_transfer_continue_stream_callback as user callback.
		// - If the transfer succeeds, winusbx_iso_transfer_continue_stream_callback restore the user callback and calls its.
		// - If the transfer fails, winusbx_iso_transfer_continue_stream_callback reschedule the transfer and force ContinueStream = FALSE.
		if (!transfer_priv->iso_break_stream) {
			transfer_priv->iso_user_callback = transfer->callback;
			transfer->callback = winusbx_native_iso_transfer_continue_stream_callback;
		}

		// Initiate the transfers.
		if (IS_XFERIN(transfer))
			ret = WinUSBX[sub_api].ReadIsochPipeAsap(buffer_handle, 0, transfer->length, !transfer_priv->iso_break_stream, transfer->num_iso_packets, (PUSBD_ISO_PACKET_DESCRIPTOR)transfer->iso_packet_desc, overlapped);
		else
			ret = WinUSBX[sub_api].WriteIsochPipeAsap(buffer_handle, 0, out_transfer_length, !transfer_priv->iso_break_stream, overlapped);

		if (!ret && GetLastError() != ERROR_IO_PENDING) {
			usbi_err(TRANSFER_CTX(transfer), "ReadIsochPipeAsap/WriteIsochPipeAsap failed: %s", windows_error_str(0));
			if (!WinUSBX[sub_api].UnregisterIsochBuffer(buffer_handle))
				usbi_warn(TRANSFER_CTX(transfer), "failed to unregister WinUSB isoch buffer: %s", windows_error_str(0));
			return LIBUSB_ERROR_IO;
		}

		// Restore the ContinueStream parameter to TRUE.
		transfer_priv->iso_break_stream = FALSE;

		transfer_priv->isoch_buffer_handle = buffer_handle;

		transfer_priv->interface_number = (uint8_t)current_interface;

		return LIBUSB_SUCCESS;
	} else {
		PRINT_UNSUPPORTED_API(winusbx_submit_iso_transfer);
		return LIBUSB_ERROR_NOT_SUPPORTED;
	}
}

static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	HANDLE winusb_handle;
	OVERLAPPED *overlapped;
	BOOL ret;
	int current_interface;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
	if (current_interface < 0) {
		usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);

	winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
	set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
	overlapped = get_transfer_priv_overlapped(itransfer);

	if (IS_XFERIN(transfer)) {
		usbi_dbg("reading %d bytes", transfer->length);
		ret = WinUSBX[sub_api].ReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped);
	} else {
		// Set SHORT_PACKET_TERMINATE if ZLP requested.
		// Changing this can be a problem with packets in flight, so only allow on the first transfer.
		UCHAR policy = (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) != 0;
		uint8_t* current_zlp = &handle_priv->interface_handle[current_interface].zlp[transfer->endpoint];
		if (*current_zlp == WINUSB_ZLP_UNSET) {
			if (policy &&
				!WinUSBX[sub_api].SetPipePolicy(winusb_handle, transfer->endpoint,
				SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
				usbi_err(TRANSFER_CTX(transfer), "failed to set SHORT_PACKET_TERMINATE for endpoint %02X", transfer->endpoint);
				return LIBUSB_ERROR_NOT_SUPPORTED;
			}
			*current_zlp = policy ? WINUSB_ZLP_ON : WINUSB_ZLP_OFF;
		} else if (policy != (*current_zlp == WINUSB_ZLP_ON)) {
			usbi_err(TRANSFER_CTX(transfer), "cannot change ZERO_PACKET for endpoint %02X on Windows", transfer->endpoint);
			return LIBUSB_ERROR_NOT_SUPPORTED;
		}

		usbi_dbg("writing %d bytes", transfer->length);
		ret = WinUSBX[sub_api].WritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped);
	}

	if (!ret && GetLastError() != ERROR_IO_PENDING) {
		usbi_err(TRANSFER_CTX(transfer), "ReadPipe/WritePipe failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_IO;
	}

	transfer_priv->interface_number = (uint8_t)current_interface;

	return LIBUSB_SUCCESS;
}

static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	HANDLE winusb_handle;
	int current_interface;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
	if (current_interface < 0) {
		usbi_err(HANDLE_CTX(dev_handle), "unable to match endpoint to an open interface - cannot clear");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
	winusb_handle = handle_priv->interface_handle[current_interface].api_handle;

	if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
		usbi_err(HANDLE_CTX(dev_handle), "ResetPipe failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_NO_DEVICE;
	}

	return LIBUSB_SUCCESS;
}

static int winusbx_cancel_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	int current_interface = transfer_priv->interface_number;
	HANDLE handle;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	usbi_dbg("will use interface %d", current_interface);

	handle = handle_priv->interface_handle[current_interface].api_handle;
	if (!WinUSBX[sub_api].AbortPipe(handle, transfer->endpoint)) {
		usbi_err(TRANSFER_CTX(transfer), "AbortPipe failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_NO_DEVICE;
	}

	return LIBUSB_SUCCESS;
}

/*
 * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
 * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
 * "WinUSB does not support host-initiated reset port and cycle port operations" and
 * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
 * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
 * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
 */
// TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	HANDLE winusb_handle;
	int i, j;

	CHECK_WINUSBX_AVAILABLE(sub_api);

	// Reset any available pipe (except control)
	for (i = 0; i < USB_MAXINTERFACES; i++) {
		winusb_handle = handle_priv->interface_handle[i].api_handle;
		if (HANDLE_VALID(winusb_handle)) {
			for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) {
				usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
				if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))
					usbi_err(HANDLE_CTX(dev_handle), "AbortPipe (pipe address %02X) failed: %s",
						priv->usb_interface[i].endpoint[j], windows_error_str(0));

				// FlushPipe seems to fail on OUT pipes
				if (IS_EPIN(priv->usb_interface[i].endpoint[j])
						&& (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])))
					usbi_err(HANDLE_CTX(dev_handle), "FlushPipe (pipe address %02X) failed: %s",
						priv->usb_interface[i].endpoint[j], windows_error_str(0));

				if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))
					usbi_err(HANDLE_CTX(dev_handle), "ResetPipe (pipe address %02X) failed: %s",
						priv->usb_interface[i].endpoint[j], windows_error_str(0));
			}
		}
	}

	// libusbK & libusb0 have the ability to issue an actual device reset
	if ((sub_api != SUB_API_WINUSB) && (WinUSBX[sub_api].ResetDevice != NULL)) {
		winusb_handle = handle_priv->interface_handle[0].api_handle;
		if (HANDLE_VALID(winusb_handle))
			WinUSBX[sub_api].ResetDevice(winusb_handle);
	}

	return LIBUSB_SUCCESS;
}

static enum libusb_transfer_status winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	int i;

	if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
		// for isochronous, need to copy the individual iso packet actual_lengths and statuses
		if ((sub_api == SUB_API_LIBUSBK) || (sub_api == SUB_API_LIBUSB0)) {
			// iso only supported on libusbk-based backends for now
			PKISO_CONTEXT iso_context = transfer_priv->iso_context;
			for (i = 0; i < transfer->num_iso_packets; i++) {
				transfer->iso_packet_desc[i].actual_length = iso_context->IsoPackets[i].actual_length;
				// TODO translate USDB_STATUS codes http://msdn.microsoft.com/en-us/library/ff539136(VS.85).aspx to libusb_transfer_status
				//transfer->iso_packet_desc[i].status = transfer_priv->iso_context->IsoPackets[i].status;
			}
		} else if (sub_api == SUB_API_WINUSB) {
			if (IS_XFERIN(transfer)) {
				/* Convert isochronous packet descriptor between Windows and libusb representation.
				 * Both representation are guaranteed to have the same length in bytes.*/
				PUSBD_ISO_PACKET_DESCRIPTOR usbd_iso_packet_desc = (PUSBD_ISO_PACKET_DESCRIPTOR)transfer->iso_packet_desc;
				for (i = 0; i < transfer->num_iso_packets; i++) {
					unsigned int packet_length = (i < transfer->num_iso_packets - 1) ? (usbd_iso_packet_desc[i + 1].Offset - usbd_iso_packet_desc[i].Offset) : usbd_iso_packet_desc[i].Length;
					unsigned int actual_length = usbd_iso_packet_desc[i].Length;
					USBD_STATUS status = usbd_iso_packet_desc[i].Status;

					transfer->iso_packet_desc[i].length = packet_length;
					transfer->iso_packet_desc[i].actual_length = actual_length;
					transfer->iso_packet_desc[i].status = usbd_status_to_libusb_transfer_status(status);
				}
			} else {
				for (i = 0; i < transfer->num_iso_packets; i++) {
					transfer->iso_packet_desc[i].status = LIBUSB_TRANSFER_COMPLETED;
				}
			}
		} else {
			// This should only occur if backend is not set correctly or other backend isoc is partially implemented
			PRINT_UNSUPPORTED_API(copy_transfer_data);
			return LIBUSB_TRANSFER_ERROR;
		}
	}

	itransfer->transferred += (int)length;
	return LIBUSB_TRANSFER_COMPLETED;
}

/*
 * Internal HID Support functions (from libusb-win32)
 * Note that functions that complete data transfer synchronously must return
 * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
 */
static int _hid_get_hid_descriptor(struct hid_device_priv *dev, void *data, size_t *size);
static int _hid_get_report_descriptor(struct hid_device_priv *dev, void *data, size_t *size);

static int _hid_wcslen(WCHAR *str)
{
	int i = 0;

	while (str[i] && (str[i] != 0x409))
		i++;

	return i;
}

static int _hid_get_device_descriptor(struct hid_device_priv *hid_priv, void *data, size_t *size)
{
	struct libusb_device_descriptor d;

	d.bLength = LIBUSB_DT_DEVICE_SIZE;
	d.bDescriptorType = LIBUSB_DT_DEVICE;
	d.bcdUSB = 0x0200; /* 2.00 */
	d.bDeviceClass = 0;
	d.bDeviceSubClass = 0;
	d.bDeviceProtocol = 0;
	d.bMaxPacketSize0 = 64; /* fix this! */
	d.idVendor = (uint16_t)hid_priv->vid;
	d.idProduct = (uint16_t)hid_priv->pid;
	d.bcdDevice = 0x0100;
	d.iManufacturer = hid_priv->string_index[0];
	d.iProduct = hid_priv->string_index[1];
	d.iSerialNumber = hid_priv->string_index[2];
	d.bNumConfigurations = 1;

	if (*size > LIBUSB_DT_DEVICE_SIZE)
		*size = LIBUSB_DT_DEVICE_SIZE;
	memcpy(data, &d, *size);

	return LIBUSB_COMPLETED;
}

static int _hid_get_config_descriptor(struct hid_device_priv *hid_priv, void *data, size_t *size)
{
	char num_endpoints = 0;
	size_t config_total_len = 0;
	char tmp[HID_MAX_CONFIG_DESC_SIZE];
	struct libusb_config_descriptor *cd;
	struct libusb_interface_descriptor *id;
	struct libusb_hid_descriptor *hd;
	struct libusb_endpoint_descriptor *ed;
	size_t tmp_size;

	if (hid_priv->input_report_size)
		num_endpoints++;
	if (hid_priv->output_report_size)
		num_endpoints++;

	config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
		+ LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;

	cd = (struct libusb_config_descriptor *)tmp;
	id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
	hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
		+ LIBUSB_DT_INTERFACE_SIZE);
	ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
		+ LIBUSB_DT_INTERFACE_SIZE
		+ LIBUSB_DT_HID_SIZE);

	cd->bLength = LIBUSB_DT_CONFIG_SIZE;
	cd->bDescriptorType = LIBUSB_DT_CONFIG;
	cd->wTotalLength = (uint16_t)config_total_len;
	cd->bNumInterfaces = 1;
	cd->bConfigurationValue = 1;
	cd->iConfiguration = 0;
	cd->bmAttributes = 1 << 7; /* bus powered */
	cd->MaxPower = 50;

	id->bLength = LIBUSB_DT_INTERFACE_SIZE;
	id->bDescriptorType = LIBUSB_DT_INTERFACE;
	id->bInterfaceNumber = 0;
	id->bAlternateSetting = 0;
	id->bNumEndpoints = num_endpoints;
	id->bInterfaceClass = 3;
	id->bInterfaceSubClass = 0;
	id->bInterfaceProtocol = 0;
	id->iInterface = 0;

	tmp_size = LIBUSB_DT_HID_SIZE;
	_hid_get_hid_descriptor(hid_priv, hd, &tmp_size);

	if (hid_priv->input_report_size) {
		ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
		ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
		ed->bEndpointAddress = HID_IN_EP;
		ed->bmAttributes = 3;
		ed->wMaxPacketSize = hid_priv->input_report_size - 1;
		ed->bInterval = 10;
		ed = (struct libusb_endpoint_descriptor *)((char *)ed + LIBUSB_DT_ENDPOINT_SIZE);
	}

	if (hid_priv->output_report_size) {
		ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
		ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
		ed->bEndpointAddress = HID_OUT_EP;
		ed->bmAttributes = 3;
		ed->wMaxPacketSize = hid_priv->output_report_size - 1;
		ed->bInterval = 10;
	}

	if (*size > config_total_len)
		*size = config_total_len;
	memcpy(data, tmp, *size);

	return LIBUSB_COMPLETED;
}

static int _hid_get_string_descriptor(struct hid_device_priv *hid_priv, int _index,
	void *data, size_t *size, HANDLE hid_handle)
{
	void *tmp = NULL;
	WCHAR string[MAX_USB_STRING_LENGTH];
	size_t tmp_size = 0;
	int i;

	/* language ID, EN-US */
	char string_langid[] = {0x09, 0x04};

	if (_index == 0) {
		tmp = string_langid;
		tmp_size = sizeof(string_langid) + 2;
	} else {
		for (i = 0; i < 3; i++) {
			if (_index == (hid_priv->string_index[i])) {
				tmp = hid_priv->string[i];
				tmp_size = (_hid_wcslen(hid_priv->string[i]) + 1) * sizeof(WCHAR);
				break;
			}
		}

		if (i == 3) {
			if (!HidD_GetIndexedString(hid_handle, _index, string, sizeof(string)))
				return LIBUSB_ERROR_INVALID_PARAM;
			tmp = string;
			tmp_size = (_hid_wcslen(string) + 1) * sizeof(WCHAR);
		}
	}

	if (!tmp_size)
		return LIBUSB_ERROR_INVALID_PARAM;

	if (tmp_size < *size)
		*size = tmp_size;

	// 2 byte header
	((uint8_t *)data)[0] = (uint8_t)*size;
	((uint8_t *)data)[1] = LIBUSB_DT_STRING;
	memcpy((uint8_t *)data + 2, tmp, *size - 2);

	return LIBUSB_COMPLETED;
}

static int _hid_get_hid_descriptor(struct hid_device_priv *hid_priv, void *data, size_t *size)
{
	struct libusb_hid_descriptor d;
	uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
	size_t report_len = MAX_HID_DESCRIPTOR_SIZE;

	_hid_get_report_descriptor(hid_priv, tmp, &report_len);

	d.bLength = LIBUSB_DT_HID_SIZE;
	d.bDescriptorType = LIBUSB_DT_HID;
	d.bcdHID = 0x0110; /* 1.10 */
	d.bCountryCode = 0;
	d.bNumDescriptors = 1;
	d.bClassDescriptorType = LIBUSB_DT_REPORT;
	d.wClassDescriptorLength = (uint16_t)report_len;

	if (*size > LIBUSB_DT_HID_SIZE)
		*size = LIBUSB_DT_HID_SIZE;
	memcpy(data, &d, *size);

	return LIBUSB_COMPLETED;
}

static int _hid_get_report_descriptor(struct hid_device_priv *hid_priv, void *data, size_t *size)
{
	uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
	size_t i = 0;

	/* usage page */
	d[i++] = 0x06; d[i++] = hid_priv->usagePage & 0xFF; d[i++] = hid_priv->usagePage >> 8;
	/* usage */
	d[i++] = 0x09; d[i++] = (uint8_t)hid_priv->usage;
	/* start collection (application) */
	d[i++] = 0xA1; d[i++] = 0x01;
	/* input report */
	if (hid_priv->input_report_size) {
		/* usage (vendor defined) */
		d[i++] = 0x09; d[i++] = 0x01;
		/* logical minimum (0) */
		d[i++] = 0x15; d[i++] = 0x00;
		/* logical maximum (255) */
		d[i++] = 0x25; d[i++] = 0xFF;
		/* report size (8 bits) */
		d[i++] = 0x75; d[i++] = 0x08;
		/* report count */
		d[i++] = 0x95; d[i++] = (uint8_t)hid_priv->input_report_size - 1;
		/* input (data, variable, absolute) */
		d[i++] = 0x81; d[i++] = 0x00;
	}
	/* output report */
	if (hid_priv->output_report_size) {
		/* usage (vendor defined) */
		d[i++] = 0x09; d[i++] = 0x02;
		/* logical minimum (0) */
		d[i++] = 0x15; d[i++] = 0x00;
		/* logical maximum (255) */
		d[i++] = 0x25; d[i++] = 0xFF;
		/* report size (8 bits) */
		d[i++] = 0x75; d[i++] = 0x08;
		/* report count */
		d[i++] = 0x95; d[i++] = (uint8_t)hid_priv->output_report_size - 1;
		/* output (data, variable, absolute) */
		d[i++] = 0x91; d[i++] = 0x00;
	}
	/* feature report */
	if (hid_priv->feature_report_size) {
		/* usage (vendor defined) */
		d[i++] = 0x09; d[i++] = 0x03;
		/* logical minimum (0) */
		d[i++] = 0x15; d[i++] = 0x00;
		/* logical maximum (255) */
		d[i++] = 0x25; d[i++] = 0xFF;
		/* report size (8 bits) */
		d[i++] = 0x75; d[i++] = 0x08;
		/* report count */
		d[i++] = 0x95; d[i++] = (uint8_t)hid_priv->feature_report_size - 1;
		/* feature (data, variable, absolute) */
		d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
	}

	/* end collection */
	d[i++] = 0xC0;

	if (*size > i)
		*size = i;
	memcpy(data, d, *size);

	return LIBUSB_COMPLETED;
}

static int _hid_get_descriptor(struct libusb_device *dev, HANDLE hid_handle, int recipient,
	int type, int _index, void *data, size_t *size)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	UNUSED(recipient);

	switch (type) {
	case LIBUSB_DT_DEVICE:
		usbi_dbg("LIBUSB_DT_DEVICE");
		return _hid_get_device_descriptor(priv->hid, data, size);
	case LIBUSB_DT_CONFIG:
		usbi_dbg("LIBUSB_DT_CONFIG");
		if (!_index)
			return _hid_get_config_descriptor(priv->hid, data, size);
		return LIBUSB_ERROR_INVALID_PARAM;
	case LIBUSB_DT_STRING:
		usbi_dbg("LIBUSB_DT_STRING");
		return _hid_get_string_descriptor(priv->hid, _index, data, size, hid_handle);
	case LIBUSB_DT_HID:
		usbi_dbg("LIBUSB_DT_HID");
		if (!_index)
			return _hid_get_hid_descriptor(priv->hid, data, size);
		return LIBUSB_ERROR_INVALID_PARAM;
	case LIBUSB_DT_REPORT:
		usbi_dbg("LIBUSB_DT_REPORT");
		if (!_index)
			return _hid_get_report_descriptor(priv->hid, data, size);
		return LIBUSB_ERROR_INVALID_PARAM;
	case LIBUSB_DT_PHYSICAL:
		usbi_dbg("LIBUSB_DT_PHYSICAL");
		if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
			return LIBUSB_COMPLETED;
		return LIBUSB_ERROR_OTHER;
	}

	usbi_warn(DEVICE_CTX(dev), "unsupported");
	return LIBUSB_ERROR_NOT_SUPPORTED;
}

static int _hid_get_report(struct libusb_device *dev, HANDLE hid_handle, int id, void *data,
	struct winusb_transfer_priv *tp, size_t size, OVERLAPPED *overlapped, int report_type)
{
	DWORD ioctl_code, expected_size = (DWORD)size;
	uint8_t *buf;

	if (tp->hid_buffer != NULL)
		usbi_err(DEVICE_CTX(dev), "program assertion failed - hid_buffer is not NULL");

	if ((size == 0) || (size > MAX_HID_REPORT_SIZE)) {
		usbi_warn(DEVICE_CTX(dev), "invalid size (%"PRIuPTR")", (uintptr_t)size);
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	switch (report_type) {
	case HID_REPORT_TYPE_INPUT:
		ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
		break;
	case HID_REPORT_TYPE_FEATURE:
		ioctl_code = IOCTL_HID_GET_FEATURE;
		break;
	default:
		usbi_warn(DEVICE_CTX(dev), "unknown HID report type %d", report_type);
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	// Add a trailing byte to detect overflows
	buf = calloc(1, expected_size + 1);
	if (buf == NULL)
		return LIBUSB_ERROR_NO_MEM;

	buf[0] = (uint8_t)id; // Must be set always
	usbi_dbg("report ID: 0x%02X", buf[0]);

	// NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
	if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size + 1,
		buf, expected_size + 1, NULL, overlapped)) {
		if (GetLastError() != ERROR_IO_PENDING) {
			usbi_err(DEVICE_CTX(dev), "failed to read HID Report: %s", windows_error_str(0));
			free(buf);
			return LIBUSB_ERROR_IO;
		}
	}

	// Asynchronous wait
	tp->hid_buffer = buf;
	tp->hid_dest = data; // copy dest, as not necessarily the start of the transfer buffer
	tp->hid_expected_size = expected_size;

	return LIBUSB_SUCCESS;
}

static int _hid_set_report(struct libusb_device *dev, HANDLE hid_handle, int id, void *data,
	struct winusb_transfer_priv *tp, size_t size, OVERLAPPED *overlapped, int report_type)
{
	DWORD ioctl_code, write_size = (DWORD)size;
	// If an id is reported, we must allow MAX_HID_REPORT_SIZE + 1
	size_t max_report_size = MAX_HID_REPORT_SIZE + (id ? 1 : 0);
	uint8_t *buf;

	if (tp->hid_buffer != NULL)
		usbi_err(DEVICE_CTX(dev), "program assertion failed - hid_buffer is not NULL");

	if ((size == 0) || (size > max_report_size)) {
		usbi_warn(DEVICE_CTX(dev), "invalid size (%"PRIuPTR")", (uintptr_t)size);
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	switch (report_type) {
	case HID_REPORT_TYPE_OUTPUT:
		ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
		break;
	case HID_REPORT_TYPE_FEATURE:
		ioctl_code = IOCTL_HID_SET_FEATURE;
		break;
	default:
		usbi_warn(DEVICE_CTX(dev), "unknown HID report type %d", report_type);
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	usbi_dbg("report ID: 0x%02X", id);
	// When report IDs are not used (i.e. when id == 0), we must add
	// a null report ID. Otherwise, we just use original data buffer
	if (id == 0)
		write_size++;

	buf = malloc(write_size);
	if (buf == NULL)
		return LIBUSB_ERROR_NO_MEM;

	if (id == 0) {
		buf[0] = 0;
		memcpy(buf + 1, data, size);
	} else {
		// This seems like a waste, but if we don't duplicate the
		// data, we'll get issues when freeing hid_buffer
		memcpy(buf, data, size);
		if (buf[0] != id)
			usbi_warn(DEVICE_CTX(dev), "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
	}

	// NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
	if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
		buf, write_size, NULL, overlapped)) {
		if (GetLastError() != ERROR_IO_PENDING) {
			usbi_err(DEVICE_CTX(dev), "failed to write HID Output Report: %s", windows_error_str(0));
			free(buf);
			return LIBUSB_ERROR_IO;
		}
	}

	tp->hid_buffer = buf;
	tp->hid_dest = NULL;
	return LIBUSB_SUCCESS;
}

static int _hid_class_request(struct libusb_device *dev, HANDLE hid_handle, int request_type,
	int request, int value, int _index, void *data, struct winusb_transfer_priv *tp,
	size_t size, OVERLAPPED *overlapped)
{
	int report_type = (value >> 8) & 0xFF;
	int report_id = value & 0xFF;

	UNUSED(_index);

	if ((LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
			&& (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE))
		return LIBUSB_ERROR_INVALID_PARAM;

	if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
		return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);

	if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
		return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);

	return LIBUSB_ERROR_INVALID_PARAM;
}

/*
 * HID API functions
 */
static bool hid_init(struct libusb_context *ctx)
{
	DLL_GET_HANDLE(ctx, hid);

	DLL_LOAD_FUNC(hid, HidD_GetAttributes, true);
	DLL_LOAD_FUNC(hid, HidD_GetHidGuid, true);
	DLL_LOAD_FUNC(hid, HidD_GetPreparsedData, true);
	DLL_LOAD_FUNC(hid, HidD_FreePreparsedData, true);
	DLL_LOAD_FUNC(hid, HidD_GetManufacturerString, true);
	DLL_LOAD_FUNC(hid, HidD_GetProductString, true);
	DLL_LOAD_FUNC(hid, HidD_GetSerialNumberString, true);
	DLL_LOAD_FUNC(hid, HidD_GetIndexedString, true);
	DLL_LOAD_FUNC(hid, HidP_GetCaps, true);
	DLL_LOAD_FUNC(hid, HidD_SetNumInputBuffers, true);
	DLL_LOAD_FUNC(hid, HidD_GetPhysicalDescriptor, true);
	DLL_LOAD_FUNC(hid, HidD_FlushQueue, true);
	DLL_LOAD_FUNC(hid, HidP_GetValueCaps, true);

	return true;
}

static void hid_exit(void)
{
	DLL_FREE_HANDLE(hid);
}

// NB: open and close must ensure that they only handle interface of
// the right API type, as these functions can be called wholesale from
// composite_open(), with interfaces belonging to different APIs
static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct libusb_device *dev = dev_handle->dev;
	struct winusb_device_priv *priv = usbi_get_device_priv(dev);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	HIDD_ATTRIBUTES hid_attributes;
	PHIDP_PREPARSED_DATA preparsed_data = NULL;
	HIDP_CAPS capabilities;
	HIDP_VALUE_CAPS *value_caps;
	HANDLE hid_handle = INVALID_HANDLE_VALUE;
	int i, j;
	// report IDs handling
	ULONG size[3];
	int nb_ids[2]; // zero and nonzero report IDs
#if defined(ENABLE_LOGGING)
	const char * const type[3] = {"input", "output", "feature"};
#endif

	UNUSED(sub_api);
	CHECK_HID_AVAILABLE;

	if (priv->hid == NULL) {
		usbi_err(HANDLE_CTX(dev_handle), "program assertion failed - private HID structure is uninitialized");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	for (i = 0; i < USB_MAXINTERFACES; i++) {
		if ((priv->usb_interface[i].path != NULL)
				&& (priv->usb_interface[i].apib->id == USB_API_HID)) {
			hid_handle = windows_open(dev_handle, priv->usb_interface[i].path, GENERIC_READ | GENERIC_WRITE);
			/*
			 * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
			 * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
			 * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
			 * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
			 * HidD_GetFeature (if the device supports Feature reports)."
			 */
			if (hid_handle == INVALID_HANDLE_VALUE) {
				usbi_warn(HANDLE_CTX(dev_handle), "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
				hid_handle = windows_open(dev_handle, priv->usb_interface[i].path, 0);
				if (hid_handle == INVALID_HANDLE_VALUE) {
					usbi_err(HANDLE_CTX(dev_handle), "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
					switch (GetLastError()) {
					case ERROR_FILE_NOT_FOUND: // The device was disconnected
						return LIBUSB_ERROR_NO_DEVICE;
					case ERROR_ACCESS_DENIED:
						return LIBUSB_ERROR_ACCESS;
					default:
						return LIBUSB_ERROR_IO;
					}
				}
				priv->usb_interface[i].restricted_functionality = true;
			}
			handle_priv->interface_handle[i].api_handle = hid_handle;
		}
	}

	hid_attributes.Size = sizeof(hid_attributes);
	do {
		if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
			usbi_err(HANDLE_CTX(dev_handle), "could not gain access to HID top collection (HidD_GetAttributes)");
			break;
		}

		priv->hid->vid = hid_attributes.VendorID;
		priv->hid->pid = hid_attributes.ProductID;

		// Set the maximum available input buffer size
		for (i = 32; HidD_SetNumInputBuffers(hid_handle, i); i *= 2);
		usbi_dbg("set maximum input buffer size to %d", i / 2);

		// Get the maximum input and output report size
		if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
			usbi_err(HANDLE_CTX(dev_handle), "could not read HID preparsed data (HidD_GetPreparsedData)");
			break;
		}
		if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
			usbi_err(HANDLE_CTX(dev_handle), "could not parse HID capabilities (HidP_GetCaps)");
			break;
		}

		// Find out if interrupt will need report IDs
		size[0] = capabilities.NumberInputValueCaps;
		size[1] = capabilities.NumberOutputValueCaps;
		size[2] = capabilities.NumberFeatureValueCaps;
		for (j = HidP_Input; j <= HidP_Feature; j++) {
			usbi_dbg("%lu HID %s report value(s) found", ULONG_CAST(size[j]), type[j]);
			priv->hid->uses_report_ids[j] = false;
			if (size[j] > 0) {
				value_caps = calloc(size[j], sizeof(HIDP_VALUE_CAPS));
				if ((value_caps != NULL)
						&& (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
						&& (size[j] >= 1)) {
					nb_ids[0] = 0;
					nb_ids[1] = 0;
					for (i = 0; i < (int)size[j]; i++) {
						usbi_dbg("  Report ID: 0x%02X", value_caps[i].ReportID);
						if (value_caps[i].ReportID != 0)
							nb_ids[1]++;
						else
							nb_ids[0]++;
					}
					if (nb_ids[1] != 0) {
						if (nb_ids[0] != 0)
							usbi_warn(HANDLE_CTX(dev_handle), "program assertion failed - zero and nonzero report IDs used for %s",
								type[j]);
						priv->hid->uses_report_ids[j] = true;
					}
				} else {
					usbi_warn(HANDLE_CTX(dev_handle), "  could not process %s report IDs", type[j]);
				}
				free(value_caps);
			}
		}

		// Set the report sizes
		priv->hid->input_report_size = capabilities.InputReportByteLength;
		priv->hid->output_report_size = capabilities.OutputReportByteLength;
		priv->hid->feature_report_size = capabilities.FeatureReportByteLength;

		// Store usage and usagePage values
		priv->hid->usage = capabilities.Usage;
		priv->hid->usagePage = capabilities.UsagePage;

		// Fetch string descriptors
		priv->hid->string_index[0] = dev->device_descriptor.iManufacturer;
		if (priv->hid->string_index[0] != 0)
			HidD_GetManufacturerString(hid_handle, priv->hid->string[0], sizeof(priv->hid->string[0]));
		else
			priv->hid->string[0][0] = 0;

		priv->hid->string_index[1] = dev->device_descriptor.iProduct;
		if (priv->hid->string_index[1] != 0)
			HidD_GetProductString(hid_handle, priv->hid->string[1], sizeof(priv->hid->string[1]));
		else
			priv->hid->string[1][0] = 0;

		priv->hid->string_index[2] = dev->device_descriptor.iSerialNumber;
		if (priv->hid->string_index[2] != 0)
			HidD_GetSerialNumberString(hid_handle, priv->hid->string[2], sizeof(priv->hid->string[2]));
		else
			priv->hid->string[2][0] = 0;
	} while (0);

	if (preparsed_data)
		HidD_FreePreparsedData(preparsed_data);

	return LIBUSB_SUCCESS;
}

static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	HANDLE file_handle;
	int i;

	UNUSED(sub_api);

	if (DLL_HANDLE_NAME(hid) == NULL)
		return;

	for (i = 0; i < USB_MAXINTERFACES; i++) {
		if (priv->usb_interface[i].apib->id == USB_API_HID) {
			file_handle = handle_priv->interface_handle[i].api_handle;
			if (HANDLE_VALID(file_handle))
				CloseHandle(file_handle);
		}
	}
}

static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	UNUSED(sub_api);
	CHECK_HID_AVAILABLE;

	// NB: Disconnection detection is not possible in this function
	if (priv->usb_interface[iface].path == NULL)
		return LIBUSB_ERROR_NOT_FOUND; // invalid iface

	// We use dev_handle as a flag for interface claimed
	if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED)
		return LIBUSB_ERROR_BUSY; // already claimed

	handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;

	usbi_dbg("claimed interface %u", iface);
	handle_priv->active_interface = iface;

	return LIBUSB_SUCCESS;
}

static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	UNUSED(sub_api);
	CHECK_HID_AVAILABLE;

	if (priv->usb_interface[iface].path == NULL)
		return LIBUSB_ERROR_NOT_FOUND; // invalid iface

	if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED)
		return LIBUSB_ERROR_NOT_FOUND; // invalid iface

	handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;

	return LIBUSB_SUCCESS;
}

static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
{
	UNUSED(sub_api);
	UNUSED(iface);

	CHECK_HID_AVAILABLE;

	if (altsetting != 0) {
		usbi_err(HANDLE_CTX(dev_handle), "set interface altsetting not supported for altsetting >0");
		return LIBUSB_ERROR_NOT_SUPPORTED;
	}

	return LIBUSB_SUCCESS;
}

static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct libusb_device_handle *dev_handle = transfer->dev_handle;
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer;
	HANDLE hid_handle;
	OVERLAPPED *overlapped;
	int current_interface;
	uint8_t config;
	size_t size;
	int r;

	UNUSED(sub_api);
	CHECK_HID_AVAILABLE;

	safe_free(transfer_priv->hid_buffer);
	transfer_priv->hid_dest = NULL;
	size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;

	if (size > MAX_CTRL_BUFFER_LENGTH)
		return LIBUSB_ERROR_INVALID_PARAM;

	current_interface = get_valid_interface(dev_handle, USB_API_HID);
	if (current_interface < 0) {
		if (auto_claim(transfer, &current_interface, USB_API_HID) != LIBUSB_SUCCESS)
			return LIBUSB_ERROR_NOT_FOUND;
	}

	usbi_dbg("will use interface %d", current_interface);

	hid_handle = handle_priv->interface_handle[current_interface].api_handle;
	set_transfer_priv_handle(itransfer, hid_handle);
	overlapped = get_transfer_priv_overlapped(itransfer);

	switch (LIBUSB_REQ_TYPE(setup->RequestType)) {
	case LIBUSB_REQUEST_TYPE_STANDARD:
		switch (setup->Request) {
		case LIBUSB_REQUEST_GET_DESCRIPTOR:
			r = _hid_get_descriptor(dev_handle->dev, hid_handle, LIBUSB_REQ_RECIPIENT(setup->RequestType),
				(setup->Value >> 8) & 0xFF, setup->Value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
			break;
		case LIBUSB_REQUEST_GET_CONFIGURATION:
			r = winusb_get_configuration(dev_handle, &config);
			if (r == LIBUSB_SUCCESS) {
				size = 1;
				((uint8_t *)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = config;
				r = LIBUSB_COMPLETED;
			}
			break;
		case LIBUSB_REQUEST_SET_CONFIGURATION:
			if (setup->Value == priv->active_config) {
				r = LIBUSB_COMPLETED;
			} else {
				usbi_warn(TRANSFER_CTX(transfer), "cannot set configuration other than the default one");
				r = LIBUSB_ERROR_NOT_SUPPORTED;
			}
			break;
		case LIBUSB_REQUEST_GET_INTERFACE:
			size = 1;
			((uint8_t *)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
			r = LIBUSB_COMPLETED;
			break;
		case LIBUSB_REQUEST_SET_INTERFACE:
			r = hid_set_interface_altsetting(0, dev_handle, (uint8_t)setup->Index, (uint8_t)setup->Value);
			if (r == LIBUSB_SUCCESS)
				r = LIBUSB_COMPLETED;
			break;
		default:
			usbi_warn(TRANSFER_CTX(transfer), "unsupported HID control request");
			return LIBUSB_ERROR_NOT_SUPPORTED;
		}
		break;
	case LIBUSB_REQUEST_TYPE_CLASS:
		r = _hid_class_request(dev_handle->dev, hid_handle, setup->RequestType, setup->Request, setup->Value,
			setup->Index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
			size, overlapped);
		break;
	default:
		usbi_warn(TRANSFER_CTX(transfer), "unsupported HID control request");
		return LIBUSB_ERROR_NOT_SUPPORTED;
	}

	if (r < 0)
		return r;

	if (r == LIBUSB_COMPLETED) {
		// Force request to be completed synchronously. Transferred size has been set by previous call
		windows_force_sync_completion(itransfer, (ULONG)size);
		r = LIBUSB_SUCCESS;
	}

	transfer_priv->interface_number = (uint8_t)current_interface;

	return LIBUSB_SUCCESS;
}

static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	HANDLE hid_handle;
	OVERLAPPED *overlapped;
	bool direction_in;
	BOOL ret;
	int current_interface, length;

	UNUSED(sub_api);
	CHECK_HID_AVAILABLE;

	if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET))
		return LIBUSB_ERROR_NOT_SUPPORTED;

	transfer_priv->hid_dest = NULL;
	safe_free(transfer_priv->hid_buffer);

	current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
	if (current_interface < 0) {
		usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);

	hid_handle = handle_priv->interface_handle[current_interface].api_handle;
	set_transfer_priv_handle(itransfer, hid_handle);
	overlapped = get_transfer_priv_overlapped(itransfer);
	direction_in = IS_XFERIN(transfer);

	// If report IDs are not in use, an extra prefix byte must be added
	if (((direction_in) && (!priv->hid->uses_report_ids[0]))
			|| ((!direction_in) && (!priv->hid->uses_report_ids[1])))
		length = transfer->length + 1;
	else
		length = transfer->length;

	// Add a trailing byte to detect overflows on input
	transfer_priv->hid_buffer = calloc(1, length + 1);
	if (transfer_priv->hid_buffer == NULL)
		return LIBUSB_ERROR_NO_MEM;

	transfer_priv->hid_expected_size = length;

	if (direction_in) {
		transfer_priv->hid_dest = transfer->buffer;
		usbi_dbg("reading %d bytes (report ID: 0x00)", length);
		ret = ReadFile(hid_handle, transfer_priv->hid_buffer, length + 1, NULL, overlapped);
	} else {
		if (!priv->hid->uses_report_ids[1])
			memcpy(transfer_priv->hid_buffer + 1, transfer->buffer, transfer->length);
		else
			// We could actually do without the calloc and memcpy in this case
			memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);

		usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
		ret = WriteFile(hid_handle, transfer_priv->hid_buffer, length, NULL, overlapped);
	}

	if (!ret && GetLastError() != ERROR_IO_PENDING) {
		usbi_err(TRANSFER_CTX(transfer), "HID transfer failed: %s", windows_error_str(0));
		safe_free(transfer_priv->hid_buffer);
		return LIBUSB_ERROR_IO;
	}

	transfer_priv->interface_number = (uint8_t)current_interface;

	return LIBUSB_SUCCESS;
}

static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	HANDLE hid_handle;
	int current_interface;

	UNUSED(sub_api);
	CHECK_HID_AVAILABLE;

	// Flushing the queues on all interfaces is the best we can achieve
	for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
		hid_handle = handle_priv->interface_handle[current_interface].api_handle;
		if (HANDLE_VALID(hid_handle))
			HidD_FlushQueue(hid_handle);
	}

	return LIBUSB_SUCCESS;
}

static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	HANDLE hid_handle;
	int current_interface;

	UNUSED(sub_api);
	CHECK_HID_AVAILABLE;

	current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
	if (current_interface < 0) {
		usbi_err(HANDLE_CTX(dev_handle), "unable to match endpoint to an open interface - cannot clear");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
	hid_handle = handle_priv->interface_handle[current_interface].api_handle;

	// No endpoint selection with Microsoft's implementation, so we try to flush the
	// whole interface. Should be OK for most case scenarios
	if (!HidD_FlushQueue(hid_handle)) {
		usbi_err(HANDLE_CTX(dev_handle), "Flushing of HID queue failed: %s", windows_error_str(0));
		// Device was probably disconnected
		return LIBUSB_ERROR_NO_DEVICE;
	}

	return LIBUSB_SUCCESS;
}

// This extra function is only needed for HID
static enum libusb_transfer_status hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	enum libusb_transfer_status r = LIBUSB_TRANSFER_COMPLETED;

	UNUSED(sub_api);

	if (transfer_priv->hid_buffer != NULL) {
		// If we have a valid hid_buffer, it means the transfer was async
		if (transfer_priv->hid_dest != NULL) { // Data readout
			if (length > 0) {
				// First, check for overflow
				if ((size_t)length > transfer_priv->hid_expected_size) {
					usbi_err(TRANSFER_CTX(transfer), "OVERFLOW!");
					length = (DWORD)transfer_priv->hid_expected_size;
					r = LIBUSB_TRANSFER_OVERFLOW;
				}

				if (transfer_priv->hid_buffer[0] == 0) {
					// Discard the 1 byte report ID prefix
					length--;
					memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer + 1, length);
				} else {
					memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, length);
				}
			}
			transfer_priv->hid_dest = NULL;
		}
		// For write, we just need to free the hid buffer
		safe_free(transfer_priv->hid_buffer);
	}

	itransfer->transferred += (int)length;
	return r;
}


/*
 * Composite API functions
 */
static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	int i, r = LIBUSB_ERROR_NOT_FOUND;
	// SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID
	bool available[SUB_API_MAX + 1];

	UNUSED(sub_api);

	for (i = 0; i < SUB_API_MAX + 1; i++)
		available[i] = false;

	for (i = 0; i < USB_MAXINTERFACES; i++) {
		switch (priv->usb_interface[i].apib->id) {
		case USB_API_WINUSBX:
			if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
				available[priv->usb_interface[i].sub_api] = true;
			break;
		case USB_API_HID:
			available[SUB_API_MAX] = true;
			break;
		default:
			break;
		}
	}

	for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers
		if (available[i]) {
			r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
			if (r != LIBUSB_SUCCESS)
				return r;
		}
	}

	if (available[SUB_API_MAX]) { // HID driver
		r = hid_open(SUB_API_NOTSET, dev_handle);

		// On Windows 10 version 1903 (OS Build 18362) and later Windows blocks attempts to
		// open HID devices with a U2F usage unless running as administrator. We ignore this
		// failure and proceed without the HID device opened.
		if (r == LIBUSB_ERROR_ACCESS) {
			usbi_dbg("ignoring access denied error while opening HID interface of composite device");
			r = LIBUSB_SUCCESS;
		}
	}

	return r;
}

static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	int i;
	// SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID
	bool available[SUB_API_MAX + 1];

	UNUSED(sub_api);

	for (i = 0; i < SUB_API_MAX + 1; i++)
		available[i] = false;

	for (i = 0; i < USB_MAXINTERFACES; i++) {
		switch (priv->usb_interface[i].apib->id) {
		case USB_API_WINUSBX:
			if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
				available[priv->usb_interface[i].sub_api] = true;
			break;
		case USB_API_HID:
			available[SUB_API_MAX] = true;
			break;
		default:
			break;
		}
	}

	for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers
		if (available[i])
			usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
	}

	if (available[SUB_API_MAX]) // HID driver
		hid_close(SUB_API_NOTSET, dev_handle);
}

static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	UNUSED(sub_api);
	CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, claim_interface);

	return priv->usb_interface[iface].apib->
		claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
}

static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	UNUSED(sub_api);
	CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, set_interface_altsetting);

	return priv->usb_interface[iface].apib->
		set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
}

static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);

	UNUSED(sub_api);
	CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, release_interface);

	return priv->usb_interface[iface].apib->
		release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
}

static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	struct libusb_config_descriptor *conf_desc;
	WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer;
	int iface, pass, r;

	UNUSED(sub_api);

	// Interface shouldn't matter for control, but it does in practice, with Windows'
	// restrictions with regards to accessing HID keyboards and mice. Try to target
	// a specific interface first, if possible.
	switch (LIBUSB_REQ_RECIPIENT(setup->RequestType)) {
	case LIBUSB_RECIPIENT_INTERFACE:
		iface = setup->Index & 0xFF;
		break;
	case LIBUSB_RECIPIENT_ENDPOINT:
		r = libusb_get_active_config_descriptor(transfer->dev_handle->dev, &conf_desc);
		if (r == LIBUSB_SUCCESS) {
			iface = get_interface_by_endpoint(conf_desc, (setup->Index & 0xFF));
			libusb_free_config_descriptor(conf_desc);
			break;
		}
		// No break if not able to determine interface
		// Fall through
	default:
		iface = -1;
		break;
	}

	// Try and target a specific interface if the control setup indicates such
	if ((iface >= 0) && (iface < USB_MAXINTERFACES)) {
		usbi_dbg("attempting control transfer targeted to interface %d", iface);
		if ((priv->usb_interface[iface].path != NULL)
				&& (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) {
			r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
			if (r == LIBUSB_SUCCESS)
				return r;
		}
	}

	// Either not targeted to a specific interface or no luck in doing so.
	// Try a 2 pass approach with all interfaces.
	for (pass = 0; pass < 2; pass++) {
		for (iface = 0; iface < USB_MAXINTERFACES; iface++) {
			if ((priv->usb_interface[iface].path != NULL)
					&& (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) {
				if ((pass == 0) && (priv->usb_interface[iface].restricted_functionality)) {
					usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", iface);
					continue;
				}
				usbi_dbg("using interface %d", iface);
				r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
				// If not supported on this API, it may be supported on another, so don't give up yet!!
				if (r == LIBUSB_ERROR_NOT_SUPPORTED)
					continue;
				return r;
			}
		}
	}

	usbi_err(TRANSFER_CTX(transfer), "no libusb supported interfaces to complete request");
	return LIBUSB_ERROR_NOT_FOUND;
}

static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	int current_interface;

	UNUSED(sub_api);

	current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
	if (current_interface < 0) {
		usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, submit_bulk_transfer);

	return priv->usb_interface[current_interface].apib->
		submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);
}

static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	int current_interface;

	UNUSED(sub_api);

	current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
	if (current_interface < 0) {
		usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, submit_iso_transfer);

	return priv->usb_interface[current_interface].apib->
		submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);
}

static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
{
	struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	int current_interface;

	UNUSED(sub_api);

	current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
	if (current_interface < 0) {
		usbi_err(HANDLE_CTX(dev_handle), "unable to match endpoint to an open interface - cannot clear");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, clear_halt);

	return priv->usb_interface[current_interface].apib->
		clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);
}

static int composite_cancel_transfer(int sub_api, struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	int current_interface = transfer_priv->interface_number;

	UNUSED(sub_api);

	if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
		usbi_err(TRANSFER_CTX(transfer), "program assertion failed - invalid interface_number");
		return LIBUSB_ERROR_NOT_FOUND;
	}

	CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, cancel_transfer);

	return priv->usb_interface[current_interface].apib->
		cancel_transfer(priv->usb_interface[current_interface].sub_api, itransfer);
}

static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
{
	struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
	int i, r;
	bool available[SUB_API_MAX];

	UNUSED(sub_api);

	for (i = 0; i < SUB_API_MAX; i++)
		available[i] = false;

	for (i = 0; i < USB_MAXINTERFACES; i++) {
		if ((priv->usb_interface[i].apib->id == USB_API_WINUSBX)
				&& (priv->usb_interface[i].sub_api != SUB_API_NOTSET))
			available[priv->usb_interface[i].sub_api] = true;
	}

	for (i = 0; i < SUB_API_MAX; i++) {
		if (available[i]) {
			r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
			if (r != LIBUSB_SUCCESS)
				return r;
		}
	}

	return LIBUSB_SUCCESS;
}

static enum libusb_transfer_status composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
	struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
	int current_interface = transfer_priv->interface_number;

	UNUSED(sub_api);
	if (priv->usb_interface[current_interface].apib->copy_transfer_data == NULL) {
		usbi_err(TRANSFER_CTX(transfer), "program assertion failed - no function to copy transfer data");
		return LIBUSB_TRANSFER_ERROR;
	}

	return priv->usb_interface[current_interface].apib->
		copy_transfer_data(priv->usb_interface[current_interface].sub_api, itransfer, length);
}
