/*
 * windows backend for libusb 1.0
 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
 * 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 <stdio.h>

#include "libusbi.h"
#include "windows_common.h"

#define EPOCH_TIME	UINT64_C(116444736000000000)	// 1970.01.01 00:00:000 in MS Filetime

#define STATUS_SUCCESS	((ULONG_PTR)0UL)

// Public
enum windows_version windows_version = WINDOWS_UNDEFINED;

// Global variables for init/exit
static unsigned int init_count;
static bool usbdk_available;

/*
* Converts a windows error to human readable string
* uses retval as errorcode, or, if 0, use GetLastError()
*/
#if defined(ENABLE_LOGGING)
const char *windows_error_str(DWORD error_code)
{
	static char err_string[256];

	DWORD size;
	int len;

	if (error_code == 0)
		error_code = GetLastError();

	len = sprintf(err_string, "[%lu] ", ULONG_CAST(error_code));

	// Translate codes returned by SetupAPI. The ones we are dealing with are either
	// in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
	// See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
	switch (error_code & 0xE0000000) {
	case 0:
		error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
		break;
	case 0xE0000000:
		error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
		break;
	default:
		break;
	}

	size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			&err_string[len], sizeof(err_string) - len, NULL);
	if (size == 0) {
		DWORD format_error = GetLastError();
		if (format_error)
			snprintf(err_string, sizeof(err_string),
				"Windows error code %lu (FormatMessage error code %lu)",
				ULONG_CAST(error_code), ULONG_CAST(format_error));
		else
			snprintf(err_string, sizeof(err_string), "Unknown error code %lu",
				ULONG_CAST(error_code));
	} else {
		// Remove CRLF from end of message, if present
		size_t pos = len + size - 2;
		if (err_string[pos] == '\r')
			err_string[pos] = '\0';
	}

	return err_string;
}
#endif

/*
 * Dynamically loads a DLL from the Windows system directory.  Unlike the
 * LoadLibraryA() function, this function will not search through any
 * directories to try and find the library.
 */
HMODULE load_system_library(struct libusb_context *ctx, const char *name)
{
	char library_path[MAX_PATH];
	char *filename_start;
	UINT length;

	length = GetSystemDirectoryA(library_path, sizeof(library_path));
	if ((length == 0) || (length >= (UINT)sizeof(library_path))) {
		usbi_err(ctx, "program assertion failed - could not get system directory");
		return NULL;
	}

	filename_start = library_path + length;
	// Append '\' + name + ".dll" + NUL
	length += 1 + (UINT)strlen(name) + 4 + 1;
	if (length >= (UINT)sizeof(library_path)) {
		usbi_err(ctx, "program assertion failed - library path buffer overflow");
		return NULL;
	}

	sprintf(filename_start, "\\%s.dll", name);
	return LoadLibraryA(library_path);
}

/* Hash table functions - modified From glibc 2.3.2:
   [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
   [Knuth]            The Art of Computer Programming, part 3 (6.4)  */

#define HTAB_SIZE 1021UL	// *MUST* be a prime number!!

typedef struct htab_entry {
	unsigned long used;
	char *str;
} htab_entry;

static htab_entry *htab_table;
static usbi_mutex_t htab_mutex;
static unsigned long htab_filled;

/* Before using the hash table we must allocate memory for it.
   We allocate one element more as the found prime number says.
   This is done for more effective indexing as explained in the
   comment for the hash function.  */
static bool htab_create(struct libusb_context *ctx)
{
	if (htab_table != NULL) {
		usbi_err(ctx, "program assertion failed - hash table already allocated");
		return true;
	}

	// Create a mutex
	usbi_mutex_init(&htab_mutex);

	usbi_dbg("using %lu entries hash table", HTAB_SIZE);
	htab_filled = 0;

	// allocate memory and zero out.
	htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
	if (htab_table == NULL) {
		usbi_err(ctx, "could not allocate space for hash table");
		return false;
	}

	return true;
}

/* After using the hash table it has to be destroyed.  */
static void htab_destroy(void)
{
	unsigned long i;

	if (htab_table == NULL)
		return;

	for (i = 0; i < HTAB_SIZE; i++)
		free(htab_table[i].str);

	safe_free(htab_table);

	usbi_mutex_destroy(&htab_mutex);
}

/* This is the search function. It uses double hashing with open addressing.
   We use a trick to speed up the lookup. The table is created with one
   more element available. This enables us to use the index zero special.
   This index will never be used because we store the first hash index in
   the field used where zero means not used. Every other value means used.
   The used field can be used as a first fast comparison for equality of
   the stored and the parameter value. This helps to prevent unnecessary
   expensive calls of strcmp.  */
unsigned long htab_hash(const char *str)
{
	unsigned long hval, hval2;
	unsigned long idx;
	unsigned long r = 5381UL;
	int c;
	const char *sz = str;

	if (str == NULL)
		return 0;

	// Compute main hash value (algorithm suggested by Nokia)
	while ((c = *sz++) != 0)
		r = ((r << 5) + r) + c;
	if (r == 0)
		++r;

	// compute table hash: simply take the modulus
	hval = r % HTAB_SIZE;
	if (hval == 0)
		++hval;

	// Try the first index
	idx = hval;

	// Mutually exclusive access (R/W lock would be better)
	usbi_mutex_lock(&htab_mutex);

	if (htab_table[idx].used) {
		if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
			goto out_unlock; // existing hash

		usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);

		// Second hash function, as suggested in [Knuth]
		hval2 = 1UL + hval % (HTAB_SIZE - 2);

		do {
			// Because size is prime this guarantees to step through all available indexes
			if (idx <= hval2)
				idx = HTAB_SIZE + idx - hval2;
			else
				idx -= hval2;

			// If we visited all entries leave the loop unsuccessfully
			if (idx == hval)
				break;

			// If entry is found use it.
			if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
				goto out_unlock;
		} while (htab_table[idx].used);
	}

	// Not found => New entry

	// If the table is full return an error
	if (htab_filled >= HTAB_SIZE) {
		usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
		idx = 0UL;
		goto out_unlock;
	}

	htab_table[idx].str = _strdup(str);
	if (htab_table[idx].str == NULL) {
		usbi_err(NULL, "could not duplicate string for hash table");
		idx = 0UL;
		goto out_unlock;
	}

	htab_table[idx].used = hval;
	++htab_filled;

out_unlock:
	usbi_mutex_unlock(&htab_mutex);

	return idx;
}

enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS status)
{
	if (USBD_SUCCESS(status))
		return LIBUSB_TRANSFER_COMPLETED;

	switch (status) {
	case USBD_STATUS_TIMEOUT:
		return LIBUSB_TRANSFER_TIMED_OUT;
	case USBD_STATUS_CANCELED:
		return LIBUSB_TRANSFER_CANCELLED;
	case USBD_STATUS_ENDPOINT_HALTED:
		return LIBUSB_TRANSFER_STALL;
	case USBD_STATUS_DEVICE_GONE:
		return LIBUSB_TRANSFER_NO_DEVICE;
	default:
		usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", ULONG_CAST(status));
		return LIBUSB_TRANSFER_ERROR;
	}
}

/*
 * Make a transfer complete synchronously
 */
void windows_force_sync_completion(struct usbi_transfer *itransfer, ULONG size)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct windows_context_priv *priv = usbi_get_context_priv(TRANSFER_CTX(transfer));
	struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
	OVERLAPPED *overlapped = &transfer_priv->overlapped;

	usbi_dbg("transfer %p, length %lu", transfer, ULONG_CAST(size));

	overlapped->Internal = (ULONG_PTR)STATUS_SUCCESS;
	overlapped->InternalHigh = (ULONG_PTR)size;

	if (!PostQueuedCompletionStatus(priv->completion_port, (DWORD)size, (ULONG_PTR)transfer->dev_handle, overlapped))
		usbi_err(TRANSFER_CTX(transfer), "failed to post I/O completion: %s", windows_error_str(0));
}

/* Windows version detection */
static BOOL is_x64(void)
{
	BOOL ret = FALSE;

	// Detect if we're running a 32 or 64 bit system
	if (sizeof(uintptr_t) < 8) {
		IsWow64Process(GetCurrentProcess(), &ret);
	} else {
		ret = TRUE;
	}

	return ret;
}

static enum windows_version get_windows_version(void)
{
	enum windows_version winver;
	OSVERSIONINFOEXA vi, vi2;
	unsigned major, minor, version;
	ULONGLONG major_equal, minor_equal;
	const char *w, *arch;
	bool ws;

	memset(&vi, 0, sizeof(vi));
	vi.dwOSVersionInfoSize = sizeof(vi);
	if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
		memset(&vi, 0, sizeof(vi));
		vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
		if (!GetVersionExA((OSVERSIONINFOA *)&vi))
			return WINDOWS_UNDEFINED;
	}

	if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
		return WINDOWS_UNDEFINED;

	if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
		// Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
		// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx

		major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
		for (major = vi.dwMajorVersion; major <= 9; major++) {
			memset(&vi2, 0, sizeof(vi2));
			vi2.dwOSVersionInfoSize = sizeof(vi2);
			vi2.dwMajorVersion = major;
			if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
				continue;

			if (vi.dwMajorVersion < major) {
				vi.dwMajorVersion = major;
				vi.dwMinorVersion = 0;
			}

			minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
			for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
				memset(&vi2, 0, sizeof(vi2));
				vi2.dwOSVersionInfoSize = sizeof(vi2);
				vi2.dwMinorVersion = minor;
				if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
					continue;

				vi.dwMinorVersion = minor;
				break;
			}

			break;
		}
	}

	if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
		return WINDOWS_UNDEFINED;

	ws = (vi.wProductType <= VER_NT_WORKSTATION);
	version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
	switch (version) {
	case 0x50: winver = WINDOWS_2000;  w = "2000"; break;
	case 0x51: winver = WINDOWS_XP;	   w = "XP";   break;
	case 0x52: winver = WINDOWS_2003;  w = "2003"; break;
	case 0x60: winver = WINDOWS_VISTA; w = (ws ? "Vista" : "2008");	 break;
	case 0x61: winver = WINDOWS_7;	   w = (ws ? "7" : "2008_R2");	 break;
	case 0x62: winver = WINDOWS_8;	   w = (ws ? "8" : "2012");	 break;
	case 0x63: winver = WINDOWS_8_1;   w = (ws ? "8.1" : "2012_R2"); break;
	case 0x64: // Early Windows 10 Insider Previews and Windows Server 2017 Technical Preview 1 used version 6.4
	case 0xA0: winver = WINDOWS_10;	   w = (ws ? "10" : "2016");	 break;
	default:
		if (version < 0x50)
			return WINDOWS_UNDEFINED;
		winver = WINDOWS_11_OR_LATER;
		w = "11 or later";
	}

	arch = is_x64() ? "64-bit" : "32-bit";

	if (vi.wServicePackMinor)
		usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
	else if (vi.wServicePackMajor)
		usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
	else
		usbi_dbg("Windows %s %s", w, arch);

	return winver;
}

static unsigned __stdcall windows_iocp_thread(void *arg)
{
	struct libusb_context *ctx = arg;
	struct windows_context_priv *priv = usbi_get_context_priv(ctx);
	HANDLE iocp = priv->completion_port;
	DWORD num_bytes;
	ULONG_PTR completion_key;
	OVERLAPPED *overlapped;
	struct libusb_device_handle *dev_handle;
	struct windows_device_handle_priv *handle_priv;
	struct windows_transfer_priv *transfer_priv;
	struct usbi_transfer *itransfer;
	bool found;

	usbi_dbg("I/O completion thread started");

	while (true) {
		overlapped = NULL;
		if (!GetQueuedCompletionStatus(iocp, &num_bytes, &completion_key, &overlapped, INFINITE) && (overlapped == NULL)) {
			usbi_err(ctx, "GetQueuedCompletionStatus failed: %s", windows_error_str(0));
			break;
		}

		if (overlapped == NULL) {
			// Signal to quit
			if (completion_key != (ULONG_PTR)ctx)
				usbi_err(ctx, "program assertion failed - overlapped is NULL");
			break;
		}

		// Find the transfer associated with the OVERLAPPED that just completed.
		// If we cannot find a match, the I/O operation originated from outside of libusb
		// (e.g. within libusbK) and we need to ignore it.
		dev_handle = (struct libusb_device_handle *)completion_key;
		handle_priv = usbi_get_device_handle_priv(dev_handle);
		found = false;
		usbi_mutex_lock(&dev_handle->lock);
		list_for_each_entry(transfer_priv, &handle_priv->active_transfers, list, struct windows_transfer_priv) {
			if (overlapped == &transfer_priv->overlapped) {
				// This OVERLAPPED belongs to us, remove the transfer from the device handle's list
				list_del(&transfer_priv->list);
				found = true;
				break;
			}
		}
		usbi_mutex_unlock(&dev_handle->lock);

		if (!found) {
			usbi_dbg("ignoring overlapped %p for handle %p (device %u.%u)",
				overlapped, dev_handle, dev_handle->dev->bus_number, dev_handle->dev->device_address);
			continue;
		}

		itransfer = (struct usbi_transfer *)((unsigned char *)transfer_priv + PTR_ALIGN(sizeof(*transfer_priv)));
		usbi_dbg("transfer %p completed, length %lu",
			 USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(num_bytes));
		usbi_signal_transfer_completion(itransfer);
	}

	usbi_dbg("I/O completion thread exiting");

	return 0;
}

static int windows_init(struct libusb_context *ctx)
{
	struct windows_context_priv *priv = usbi_get_context_priv(ctx);
	char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
	HANDLE mutex;
	bool winusb_backend_init = false;
	int r;

	sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
	mutex = CreateMutexA(NULL, FALSE, mutex_name);
	if (mutex == NULL) {
		usbi_err(ctx, "could not create mutex: %s", windows_error_str(0));
		return LIBUSB_ERROR_NO_MEM;
	}

	// A successful wait gives this thread ownership of the mutex
	// => any concurrent wait stalls until the mutex is released
	if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
		usbi_err(ctx, "failure to access mutex: %s", windows_error_str(0));
		CloseHandle(mutex);
		return LIBUSB_ERROR_NO_MEM;
	}

	// NB: concurrent usage supposes that init calls are equally balanced with
	// exit calls. If init is called more than exit, we will not exit properly
	if (++init_count == 1) { // First init?
		windows_version = get_windows_version();
		if (windows_version == WINDOWS_UNDEFINED) {
			usbi_err(ctx, "failed to detect Windows version");
			r = LIBUSB_ERROR_NOT_SUPPORTED;
			goto init_exit;
		} else if (windows_version < WINDOWS_VISTA) {
			usbi_err(ctx, "Windows version is too old");
			r = LIBUSB_ERROR_NOT_SUPPORTED;
			goto init_exit;
		}

		if (!htab_create(ctx)) {
			r = LIBUSB_ERROR_NO_MEM;
			goto init_exit;
		}

		r = winusb_backend.init(ctx);
		if (r != LIBUSB_SUCCESS)
			goto init_exit;
		winusb_backend_init = true;

		r = usbdk_backend.init(ctx);
		if (r == LIBUSB_SUCCESS) {
			usbi_dbg("UsbDk backend is available");
			usbdk_available = true;
		} else {
			usbi_info(ctx, "UsbDk backend is not available");
			// Do not report this as an error
		}
	}

	// By default, new contexts will use the WinUSB backend
	priv->backend = &winusb_backend;

	r = LIBUSB_ERROR_NO_MEM;

	// Use an I/O completion port to manage all transfers for this context
	priv->completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
	if (priv->completion_port == NULL) {
		usbi_err(ctx, "failed to create I/O completion port: %s", windows_error_str(0));
		goto init_exit;
	}

	// And a dedicated thread to wait for I/O completions
	priv->completion_port_thread = (HANDLE)_beginthreadex(NULL, 0, windows_iocp_thread, ctx, 0, NULL);
	if (priv->completion_port_thread == NULL) {
		usbi_err(ctx, "failed to create I/O completion port thread");
		CloseHandle(priv->completion_port);
		goto init_exit;
	}

	r = LIBUSB_SUCCESS;

init_exit: // Holds semaphore here
	if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
		if (usbdk_available) {
			usbdk_backend.exit(ctx);
			usbdk_available = false;
		}
		if (winusb_backend_init)
			winusb_backend.exit(ctx);
		htab_destroy();
		--init_count;
	}

	ReleaseMutex(mutex);
	CloseHandle(mutex);
	return r;
}

static void windows_exit(struct libusb_context *ctx)
{
	struct windows_context_priv *priv = usbi_get_context_priv(ctx);
	char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
	HANDLE mutex;

	sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
	mutex = CreateMutexA(NULL, FALSE, mutex_name);
	if (mutex == NULL)
		return;

	// A successful wait gives this thread ownership of the mutex
	// => any concurrent wait stalls until the mutex is released
	if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
		usbi_err(ctx, "failed to access mutex: %s", windows_error_str(0));
		CloseHandle(mutex);
		return;
	}

	// A NULL completion status will indicate to the thread that it is time to exit
	if (!PostQueuedCompletionStatus(priv->completion_port, 0, (ULONG_PTR)ctx, NULL))
		usbi_err(ctx, "failed to post I/O completion: %s", windows_error_str(0));

	if (WaitForSingleObject(priv->completion_port_thread, INFINITE) == WAIT_FAILED)
		usbi_err(ctx, "failed to wait for I/O completion port thread: %s", windows_error_str(0));

	CloseHandle(priv->completion_port_thread);
	CloseHandle(priv->completion_port);

	// Only works if exits and inits are balanced exactly
	if (--init_count == 0) { // Last exit
		if (usbdk_available) {
			usbdk_backend.exit(ctx);
			usbdk_available = false;
		}
		winusb_backend.exit(ctx);
		htab_destroy();
	}

	ReleaseMutex(mutex);
	CloseHandle(mutex);
}

static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
{
	struct windows_context_priv *priv = usbi_get_context_priv(ctx);

	UNUSED(ap);

	if (option == LIBUSB_OPTION_USE_USBDK) {
		if (!usbdk_available) {
			usbi_err(ctx, "UsbDk backend not available");
			return LIBUSB_ERROR_NOT_FOUND;
		}
		usbi_dbg("switching context %p to use UsbDk backend", ctx);
		priv->backend = &usbdk_backend;
		return LIBUSB_SUCCESS;
	}

	return LIBUSB_ERROR_NOT_SUPPORTED;
}

static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
{
	struct windows_context_priv *priv = usbi_get_context_priv(ctx);
	return priv->backend->get_device_list(ctx, discdevs);
}

static int windows_open(struct libusb_device_handle *dev_handle)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	struct windows_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);

	list_init(&handle_priv->active_transfers);
	return priv->backend->open(dev_handle);
}

static void windows_close(struct libusb_device_handle *dev_handle)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	priv->backend->close(dev_handle);
}

static int windows_get_active_config_descriptor(struct libusb_device *dev,
	void *buffer, size_t len)
{
	struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
	return priv->backend->get_active_config_descriptor(dev, buffer, len);
}

static int windows_get_config_descriptor(struct libusb_device *dev,
	uint8_t config_index, void *buffer, size_t len)
{
	struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
	return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
}

static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
	uint8_t bConfigurationValue, void **buffer)
{
	struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
	return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
}

static int windows_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	return priv->backend->get_configuration(dev_handle, config);
}

static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	if (config == -1)
		config = 0;
	return priv->backend->set_configuration(dev_handle, (uint8_t)config);
}

static int windows_claim_interface(struct libusb_device_handle *dev_handle, uint8_t interface_number)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	return priv->backend->claim_interface(dev_handle, interface_number);
}

static int windows_release_interface(struct libusb_device_handle *dev_handle, uint8_t interface_number)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	return priv->backend->release_interface(dev_handle, interface_number);
}

static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
	uint8_t interface_number, uint8_t altsetting)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
}

static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	return priv->backend->clear_halt(dev_handle, endpoint);
}

static int windows_reset_device(struct libusb_device_handle *dev_handle)
{
	struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
	return priv->backend->reset_device(dev_handle);
}

static void windows_destroy_device(struct libusb_device *dev)
{
	struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
	priv->backend->destroy_device(dev);
}

static int windows_submit_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct libusb_device_handle *dev_handle = transfer->dev_handle;
	struct libusb_context *ctx = HANDLE_CTX(dev_handle);
	struct windows_context_priv *priv = usbi_get_context_priv(ctx);
	struct windows_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
	struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
	int r;

	switch (transfer->type) {
	case LIBUSB_TRANSFER_TYPE_CONTROL:
	case LIBUSB_TRANSFER_TYPE_BULK:
	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
		break;
	case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
		usbi_warn(ctx, "bulk stream transfers are not yet supported on this platform");
		return LIBUSB_ERROR_NOT_SUPPORTED;
	default:
		usbi_err(ctx, "unknown endpoint type %d", transfer->type);
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	if (transfer_priv->handle != NULL) {
		usbi_err(ctx, "program assertion failed - transfer HANDLE is not NULL");
		transfer_priv->handle = NULL;
	}

	// Add transfer to the device handle's list
	usbi_mutex_lock(&dev_handle->lock);
	list_add_tail(&transfer_priv->list, &handle_priv->active_transfers);
	usbi_mutex_unlock(&dev_handle->lock);

	r = priv->backend->submit_transfer(itransfer);
	if (r != LIBUSB_SUCCESS) {
		// Remove the unsuccessful transfer from the device handle's list
		usbi_mutex_lock(&dev_handle->lock);
		list_del(&transfer_priv->list);
		usbi_mutex_unlock(&dev_handle->lock);

		// Always call the backend's clear_transfer_priv() function on failure
		priv->backend->clear_transfer_priv(itransfer);
		transfer_priv->handle = NULL;
		return r;
	}

	// The backend should set the HANDLE used for each submitted transfer
	// by calling set_transfer_priv_handle()
	if (transfer_priv->handle == NULL)
		usbi_err(ctx, "program assertion failed - transfer HANDLE is NULL after transfer was submitted");

	return r;
}

static int windows_cancel_transfer(struct usbi_transfer *itransfer)
{
	struct windows_context_priv *priv = usbi_get_context_priv(ITRANSFER_CTX(itransfer));
	struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);

	// Try CancelIoEx() on the transfer
	// If that fails, fall back to the backend's cancel_transfer()
	// function if it is available
	if (CancelIoEx(transfer_priv->handle, &transfer_priv->overlapped))
		return LIBUSB_SUCCESS;
	else if (GetLastError() == ERROR_NOT_FOUND)
		return LIBUSB_ERROR_NOT_FOUND;

	if (priv->backend->cancel_transfer)
		return priv->backend->cancel_transfer(itransfer);

	usbi_warn(ITRANSFER_CTX(itransfer), "cancellation not supported for this transfer's driver");
	return LIBUSB_ERROR_NOT_SUPPORTED;
}

static int windows_handle_transfer_completion(struct usbi_transfer *itransfer)
{
	struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
	struct windows_context_priv *priv = usbi_get_context_priv(ctx);
	const struct windows_backend *backend = priv->backend;
	struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
	enum libusb_transfer_status status, istatus;
	DWORD result, bytes_transferred;

	if (GetOverlappedResult(transfer_priv->handle, &transfer_priv->overlapped, &bytes_transferred, FALSE))
		result = NO_ERROR;
	else
		result = GetLastError();

	usbi_dbg("handling transfer %p completion with errcode %lu, length %lu",
		 USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(result), ULONG_CAST(bytes_transferred));

	switch (result) {
	case NO_ERROR:
		status = backend->copy_transfer_data(itransfer, bytes_transferred);
		break;
	case ERROR_GEN_FAILURE:
		usbi_dbg("detected endpoint stall");
		status = LIBUSB_TRANSFER_STALL;
		break;
	case ERROR_SEM_TIMEOUT:
		usbi_dbg("detected semaphore timeout");
		status = LIBUSB_TRANSFER_TIMED_OUT;
		break;
	case ERROR_OPERATION_ABORTED:
		istatus = backend->copy_transfer_data(itransfer, bytes_transferred);
		if (istatus != LIBUSB_TRANSFER_COMPLETED)
			usbi_dbg("failed to copy partial data in aborted operation: %d", (int)istatus);

		usbi_dbg("detected operation aborted");
		status = LIBUSB_TRANSFER_CANCELLED;
		break;
	case ERROR_FILE_NOT_FOUND:
	case ERROR_DEVICE_NOT_CONNECTED:
	case ERROR_NO_SUCH_DEVICE:
		usbi_dbg("detected device removed");
		status = LIBUSB_TRANSFER_NO_DEVICE;
		break;
	default:
		usbi_err(ctx, "detected I/O error %lu: %s",
			ULONG_CAST(result), windows_error_str(result));
		status = LIBUSB_TRANSFER_ERROR;
		break;
	}

	transfer_priv->handle = NULL;

	// Backend-specific cleanup
	backend->clear_transfer_priv(itransfer);

	if (status == LIBUSB_TRANSFER_CANCELLED)
		return usbi_handle_transfer_cancellation(itransfer);
	else
		return usbi_handle_transfer_completion(itransfer, status);
}

void usbi_get_monotonic_time(struct timespec *tp)
{
	static LONG hires_counter_init;
	static uint64_t hires_ticks_to_ps;
	static uint64_t hires_frequency;
	LARGE_INTEGER hires_counter;

	if (InterlockedExchange(&hires_counter_init, 1L) == 0L) {
		LARGE_INTEGER li_frequency;

		// Microsoft says that the QueryPerformanceFrequency() and
		// QueryPerformanceCounter() functions always succeed on XP and later
		QueryPerformanceFrequency(&li_frequency);

		// The hires frequency can go as high as 4 GHz, so we'll use a conversion
		// to picoseconds to compute the tv_nsecs part
		hires_frequency = li_frequency.QuadPart;
		hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
	}

	QueryPerformanceCounter(&hires_counter);
	tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
	tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) * hires_ticks_to_ps) / UINT64_C(1000));
}

// NB: MSVC6 does not support named initializers.
const struct usbi_os_backend usbi_backend = {
	"Windows",
	USBI_CAP_HAS_HID_ACCESS,
	windows_init,
	windows_exit,
	windows_set_option,
	windows_get_device_list,
	NULL,	/* hotplug_poll */
	NULL,	/* wrap_sys_device */
	windows_open,
	windows_close,
	windows_get_active_config_descriptor,
	windows_get_config_descriptor,
	windows_get_config_descriptor_by_value,
	windows_get_configuration,
	windows_set_configuration,
	windows_claim_interface,
	windows_release_interface,
	windows_set_interface_altsetting,
	windows_clear_halt,
	windows_reset_device,
	NULL,	/* alloc_streams */
	NULL,	/* free_streams */
	NULL,	/* dev_mem_alloc */
	NULL,	/* dev_mem_free */
	NULL,	/* kernel_driver_active */
	NULL,	/* detach_kernel_driver */
	NULL,	/* attach_kernel_driver */
	windows_destroy_device,
	windows_submit_transfer,
	windows_cancel_transfer,
	NULL,	/* clear_transfer_priv */
	NULL,	/* handle_events */
	windows_handle_transfer_completion,
	sizeof(struct windows_context_priv),
	sizeof(union windows_device_priv),
	sizeof(struct windows_device_handle_priv),
	sizeof(struct windows_transfer_priv),
};
