2 * windows backend for libusb 1.0
3 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4 * With contributions from Michael Plante, Orin Eman et al.
5 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
6 * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
7 * Hash table functions adapted from glibc, by Ulrich Drepper et al.
8 * Major code testing contribution by Xiaofan Chen
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "windows_common.h"
35 #define EPOCH_TIME UINT64_C(116444736000000000) // 1970.01.01 00:00:000 in MS Filetime
37 #define STATUS_SUCCESS ((ULONG_PTR)0UL)
40 enum windows_version windows_version = WINDOWS_UNDEFINED;
42 // Global variables for init/exit
43 static unsigned int init_count;
44 static bool usbdk_available;
46 #if !defined(HAVE_CLOCK_GETTIME)
47 // Global variables for clock_gettime mechanism
48 static uint64_t hires_ticks_to_ps;
49 static uint64_t hires_frequency;
53 * Converts a windows error to human readable string
54 * uses retval as errorcode, or, if 0, use GetLastError()
56 #if defined(ENABLE_LOGGING)
57 const char *windows_error_str(DWORD error_code)
59 static char err_string[256];
65 error_code = GetLastError();
67 len = sprintf(err_string, "[%lu] ", ULONG_CAST(error_code));
69 // Translate codes returned by SetupAPI. The ones we are dealing with are either
70 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
71 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
72 switch (error_code & 0xE0000000) {
74 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
77 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
83 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
84 NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
85 &err_string[len], sizeof(err_string) - len, NULL);
87 DWORD format_error = GetLastError();
89 snprintf(err_string, sizeof(err_string),
90 "Windows error code %lu (FormatMessage error code %lu)",
91 ULONG_CAST(error_code), ULONG_CAST(format_error));
93 snprintf(err_string, sizeof(err_string), "Unknown error code %lu",
94 ULONG_CAST(error_code));
96 // Remove CRLF from end of message, if present
97 size_t pos = len + size - 2;
98 if (err_string[pos] == '\r')
99 err_string[pos] = '\0';
106 /* Hash table functions - modified From glibc 2.3.2:
107 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
108 [Knuth] The Art of Computer Programming, part 3 (6.4) */
110 #define HTAB_SIZE 1021UL // *MUST* be a prime number!!
112 typedef struct htab_entry {
117 static htab_entry *htab_table;
118 static usbi_mutex_t htab_mutex;
119 static unsigned long htab_filled;
121 /* Before using the hash table we must allocate memory for it.
122 We allocate one element more as the found prime number says.
123 This is done for more effective indexing as explained in the
124 comment for the hash function. */
125 static bool htab_create(struct libusb_context *ctx)
127 if (htab_table != NULL) {
128 usbi_err(ctx, "program assertion falied - hash table already allocated");
133 usbi_mutex_init(&htab_mutex);
135 usbi_dbg("using %lu entries hash table", HTAB_SIZE);
138 // allocate memory and zero out.
139 htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
140 if (htab_table == NULL) {
141 usbi_err(ctx, "could not allocate space for hash table");
148 /* After using the hash table it has to be destroyed. */
149 static void htab_destroy(void)
153 if (htab_table == NULL)
156 for (i = 0; i < HTAB_SIZE; i++)
157 free(htab_table[i].str);
159 safe_free(htab_table);
161 usbi_mutex_destroy(&htab_mutex);
164 /* This is the search function. It uses double hashing with open addressing.
165 We use a trick to speed up the lookup. The table is created with one
166 more element available. This enables us to use the index zero special.
167 This index will never be used because we store the first hash index in
168 the field used where zero means not used. Every other value means used.
169 The used field can be used as a first fast comparison for equality of
170 the stored and the parameter value. This helps to prevent unnecessary
171 expensive calls of strcmp. */
172 unsigned long htab_hash(const char *str)
174 unsigned long hval, hval2;
176 unsigned long r = 5381UL;
178 const char *sz = str;
183 // Compute main hash value (algorithm suggested by Nokia)
184 while ((c = *sz++) != 0)
185 r = ((r << 5) + r) + c;
189 // compute table hash: simply take the modulus
190 hval = r % HTAB_SIZE;
194 // Try the first index
197 // Mutually exclusive access (R/W lock would be better)
198 usbi_mutex_lock(&htab_mutex);
200 if (htab_table[idx].used) {
201 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
202 goto out_unlock; // existing hash
204 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
206 // Second hash function, as suggested in [Knuth]
207 hval2 = 1UL + hval % (HTAB_SIZE - 2);
210 // Because size is prime this guarantees to step through all available indexes
212 idx = HTAB_SIZE + idx - hval2;
216 // If we visited all entries leave the loop unsuccessfully
220 // If entry is found use it.
221 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
223 } while (htab_table[idx].used);
226 // Not found => New entry
228 // If the table is full return an error
229 if (htab_filled >= HTAB_SIZE) {
230 usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
235 htab_table[idx].str = _strdup(str);
236 if (htab_table[idx].str == NULL) {
237 usbi_err(NULL, "could not duplicate string for hash table");
242 htab_table[idx].used = hval;
246 usbi_mutex_unlock(&htab_mutex);
251 enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS status)
253 if (USBD_SUCCESS(status))
254 return LIBUSB_TRANSFER_COMPLETED;
257 case USBD_STATUS_TIMEOUT:
258 return LIBUSB_TRANSFER_TIMED_OUT;
259 case USBD_STATUS_CANCELED:
260 return LIBUSB_TRANSFER_CANCELLED;
261 case USBD_STATUS_ENDPOINT_HALTED:
262 return LIBUSB_TRANSFER_STALL;
263 case USBD_STATUS_DEVICE_GONE:
264 return LIBUSB_TRANSFER_NO_DEVICE;
266 usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", ULONG_CAST(status));
267 return LIBUSB_TRANSFER_ERROR;
272 * Make a transfer complete synchronously
274 void windows_force_sync_completion(struct usbi_transfer *itransfer, ULONG size)
276 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
277 OVERLAPPED *overlapped = &transfer_priv->overlapped;
279 usbi_dbg("transfer %p, length %lu", USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), size);
281 overlapped->Internal = (ULONG_PTR)STATUS_SUCCESS;
282 overlapped->InternalHigh = (ULONG_PTR)size;
284 usbi_signal_transfer_completion(itransfer);
287 static void windows_init_clock(void)
289 #if !defined(HAVE_CLOCK_GETTIME)
290 LARGE_INTEGER li_frequency;
292 // Microsoft says that the QueryPerformanceFrequency() and
293 // QueryPerformanceCounter() functions always succeed on XP and later
294 QueryPerformanceFrequency(&li_frequency);
296 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
297 // to picoseconds to compute the tv_nsecs part in clock_gettime
298 hires_frequency = li_frequency.QuadPart;
299 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
300 usbi_dbg("hires timer frequency: %"PRIu64" Hz", hires_frequency);
304 /* Windows version detection */
305 static BOOL is_x64(void)
309 // Detect if we're running a 32 or 64 bit system
310 if (sizeof(uintptr_t) < 8) {
311 IsWow64Process(GetCurrentProcess(), &ret);
319 static enum windows_version get_windows_version(void)
321 enum windows_version winver;
322 OSVERSIONINFOEXA vi, vi2;
323 unsigned major, minor, version;
324 ULONGLONG major_equal, minor_equal;
325 const char *w, *arch;
328 memset(&vi, 0, sizeof(vi));
329 vi.dwOSVersionInfoSize = sizeof(vi);
330 if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
331 memset(&vi, 0, sizeof(vi));
332 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
333 if (!GetVersionExA((OSVERSIONINFOA *)&vi))
334 return WINDOWS_UNDEFINED;
337 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
338 return WINDOWS_UNDEFINED;
340 if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
341 // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
342 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
344 major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
345 for (major = vi.dwMajorVersion; major <= 9; major++) {
346 memset(&vi2, 0, sizeof(vi2));
347 vi2.dwOSVersionInfoSize = sizeof(vi2);
348 vi2.dwMajorVersion = major;
349 if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
352 if (vi.dwMajorVersion < major) {
353 vi.dwMajorVersion = major;
354 vi.dwMinorVersion = 0;
357 minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
358 for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
359 memset(&vi2, 0, sizeof(vi2));
360 vi2.dwOSVersionInfoSize = sizeof(vi2);
361 vi2.dwMinorVersion = minor;
362 if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
365 vi.dwMinorVersion = minor;
373 if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
374 return WINDOWS_UNDEFINED;
376 ws = (vi.wProductType <= VER_NT_WORKSTATION);
377 version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
379 case 0x50: winver = WINDOWS_2000; w = "2000"; break;
380 case 0x51: winver = WINDOWS_XP; w = "XP"; break;
381 case 0x52: winver = WINDOWS_2003; w = "2003"; break;
382 case 0x60: winver = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break;
383 case 0x61: winver = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break;
384 case 0x62: winver = WINDOWS_8; w = (ws ? "8" : "2012"); break;
385 case 0x63: winver = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break;
386 case 0x64: // Early Windows 10 Insider Previews and Windows Server 2017 Technical Preview 1 used version 6.4
387 case 0xA0: winver = WINDOWS_10; w = (ws ? "10" : "2016"); break;
390 return WINDOWS_UNDEFINED;
391 winver = WINDOWS_11_OR_LATER;
395 arch = is_x64() ? "64-bit" : "32-bit";
397 if (vi.wServicePackMinor)
398 usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
399 else if (vi.wServicePackMajor)
400 usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
402 usbi_dbg("Windows %s %s", w, arch);
407 static unsigned __stdcall windows_iocp_thread(void *arg)
409 struct libusb_context *ctx = arg;
410 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
411 HANDLE iocp = priv->completion_port;
413 ULONG_PTR completion_key;
414 OVERLAPPED *overlapped;
415 struct windows_transfer_priv *transfer_priv;
416 struct usbi_transfer *itransfer;
418 usbi_dbg("I/O completion thread started");
422 if (!GetQueuedCompletionStatus(iocp, &num_bytes, &completion_key, &overlapped, INFINITE) && (overlapped == NULL)) {
423 usbi_err(ctx, "GetQueuedCompletionStatus failed: %s", windows_error_str(0));
427 if (overlapped == NULL) {
429 if (completion_key != (ULONG_PTR)ctx)
430 usbi_err(ctx, "program assertion failed - overlapped is NULL");
434 transfer_priv = container_of(overlapped, struct windows_transfer_priv, overlapped);
435 itransfer = (struct usbi_transfer *)((unsigned char *)transfer_priv + PTR_ALIGN(sizeof(*transfer_priv)));
436 usbi_dbg("transfer %p completed, length %lu",
437 USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(num_bytes));
438 usbi_signal_transfer_completion(itransfer);
441 usbi_dbg("I/O completion thread exiting");
446 static int windows_init(struct libusb_context *ctx)
448 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
449 char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
451 bool winusb_backend_init = false;
454 sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
455 mutex = CreateMutexA(NULL, FALSE, mutex_name);
457 usbi_err(ctx, "could not create mutex: %s", windows_error_str(0));
458 return LIBUSB_ERROR_NO_MEM;
461 // A successful wait gives this thread ownership of the mutex
462 // => any concurent wait stalls until the mutex is released
463 if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
464 usbi_err(ctx, "failure to access mutex: %s", windows_error_str(0));
466 return LIBUSB_ERROR_NO_MEM;
469 // NB: concurrent usage supposes that init calls are equally balanced with
470 // exit calls. If init is called more than exit, we will not exit properly
471 if (++init_count == 1) { // First init?
472 windows_version = get_windows_version();
473 if (windows_version == WINDOWS_UNDEFINED) {
474 usbi_err(ctx, "failed to detect Windows version");
475 r = LIBUSB_ERROR_NOT_SUPPORTED;
477 } else if (windows_version < WINDOWS_VISTA) {
478 usbi_err(ctx, "Windows version is too old");
479 r = LIBUSB_ERROR_NOT_SUPPORTED;
483 windows_init_clock();
485 if (!htab_create(ctx)) {
486 r = LIBUSB_ERROR_NO_MEM;
490 r = winusb_backend.init(ctx);
491 if (r != LIBUSB_SUCCESS)
493 winusb_backend_init = true;
495 r = usbdk_backend.init(ctx);
496 if (r == LIBUSB_SUCCESS) {
497 usbi_dbg("UsbDk backend is available");
498 usbdk_available = true;
500 usbi_info(ctx, "UsbDk backend is not available");
501 // Do not report this as an error
505 // By default, new contexts will use the WinUSB backend
506 priv->backend = &winusb_backend;
508 r = LIBUSB_ERROR_NO_MEM;
510 // Use an I/O completion port to manage all transfers for this context
511 priv->completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
512 if (priv->completion_port == NULL) {
513 usbi_err(ctx, "failed to create I/O completion port: %s", windows_error_str(0));
517 // And a dedicated thread to wait for I/O completions
518 priv->completion_port_thread = (HANDLE)_beginthreadex(NULL, 0, windows_iocp_thread, ctx, 0, NULL);
519 if (priv->completion_port_thread == NULL) {
520 usbi_err(ctx, "failed to create I/O completion port thread");
521 CloseHandle(priv->completion_port);
527 init_exit: // Holds semaphore here
528 if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
529 if (usbdk_available) {
530 usbdk_backend.exit(ctx);
531 usbdk_available = false;
533 if (winusb_backend_init)
534 winusb_backend.exit(ctx);
544 static void windows_exit(struct libusb_context *ctx)
546 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
547 char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
550 sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
551 mutex = CreateMutexA(NULL, FALSE, mutex_name);
555 // A successful wait gives this thread ownership of the mutex
556 // => any concurent wait stalls until the mutex is released
557 if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
558 usbi_err(ctx, "failed to access mutex: %s", windows_error_str(0));
563 // A NULL completion status will indicate to the thread that it is time to exit
564 if (!PostQueuedCompletionStatus(priv->completion_port, 0, (ULONG_PTR)ctx, NULL))
565 usbi_err(ctx, "failed to post I/O completion: %s", windows_error_str(0));
567 if (WaitForSingleObject(priv->completion_port_thread, INFINITE) == WAIT_FAILED)
568 usbi_err(ctx, "failed to wait for I/O completion port thread: %s", windows_error_str(0));
570 CloseHandle(priv->completion_port_thread);
571 CloseHandle(priv->completion_port);
573 // Only works if exits and inits are balanced exactly
574 if (--init_count == 0) { // Last exit
575 if (usbdk_available) {
576 usbdk_backend.exit(ctx);
577 usbdk_available = false;
579 winusb_backend.exit(ctx);
587 static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
589 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
593 switch ((int)option) {
594 case LIBUSB_OPTION_USE_USBDK:
595 if (usbdk_available) {
596 usbi_dbg("switching context %p to use UsbDk backend", ctx);
597 priv->backend = &usbdk_backend;
599 usbi_err(ctx, "UsbDk backend not available");
600 return LIBUSB_ERROR_NOT_FOUND;
602 return LIBUSB_SUCCESS;
604 return LIBUSB_ERROR_NOT_SUPPORTED;
608 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
610 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
611 return priv->backend->get_device_list(ctx, discdevs);
614 static int windows_open(struct libusb_device_handle *dev_handle)
616 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
617 return priv->backend->open(dev_handle);
620 static void windows_close(struct libusb_device_handle *dev_handle)
622 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
623 priv->backend->close(dev_handle);
626 static int windows_get_active_config_descriptor(struct libusb_device *dev,
627 void *buffer, size_t len)
629 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
630 return priv->backend->get_active_config_descriptor(dev, buffer, len);
633 static int windows_get_config_descriptor(struct libusb_device *dev,
634 uint8_t config_index, void *buffer, size_t len)
636 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
637 return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
640 static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
641 uint8_t bConfigurationValue, void **buffer)
643 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
644 return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
647 static int windows_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config)
649 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
650 return priv->backend->get_configuration(dev_handle, config);
653 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
655 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
658 return priv->backend->set_configuration(dev_handle, (uint8_t)config);
661 static int windows_claim_interface(struct libusb_device_handle *dev_handle, uint8_t interface_number)
663 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
664 return priv->backend->claim_interface(dev_handle, interface_number);
667 static int windows_release_interface(struct libusb_device_handle *dev_handle, uint8_t interface_number)
669 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
670 return priv->backend->release_interface(dev_handle, interface_number);
673 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
674 uint8_t interface_number, uint8_t altsetting)
676 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
677 return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
680 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
682 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
683 return priv->backend->clear_halt(dev_handle, endpoint);
686 static int windows_reset_device(struct libusb_device_handle *dev_handle)
688 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
689 return priv->backend->reset_device(dev_handle);
692 static void windows_destroy_device(struct libusb_device *dev)
694 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
695 priv->backend->destroy_device(dev);
698 static int windows_submit_transfer(struct usbi_transfer *itransfer)
700 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
701 struct libusb_context *ctx = TRANSFER_CTX(transfer);
702 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
703 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
706 switch (transfer->type) {
707 case LIBUSB_TRANSFER_TYPE_CONTROL:
708 case LIBUSB_TRANSFER_TYPE_BULK:
709 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
710 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
712 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
713 usbi_warn(ctx, "bulk stream transfers are not yet supported on this platform");
714 return LIBUSB_ERROR_NOT_SUPPORTED;
716 usbi_err(ctx, "unknown endpoint type %d", transfer->type);
717 return LIBUSB_ERROR_INVALID_PARAM;
720 if (transfer_priv->handle != NULL) {
721 usbi_err(ctx, "program assertion failed - transfer HANDLE is not NULL");
722 transfer_priv->handle = NULL;
725 r = priv->backend->submit_transfer(itransfer);
726 if (r != LIBUSB_SUCCESS) {
727 // Always call the backend's clear_transfer_priv() function on failure
728 priv->backend->clear_transfer_priv(itransfer);
729 transfer_priv->handle = NULL;
733 // The backend should set the HANDLE used for each submitted transfer
734 // by calling set_transfer_priv_handle()
735 if (transfer_priv->handle == NULL)
736 usbi_err(ctx, "program assertion failed - transfer HANDLE is NULL after transfer was submitted");
741 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
743 struct windows_context_priv *priv = usbi_get_context_priv(ITRANSFER_CTX(itransfer));
744 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
746 // Try CancelIoEx() on the transfer
747 // If that fails, fall back to the backend's cancel_transfer()
748 // function if it is available
749 if (CancelIoEx(transfer_priv->handle, &transfer_priv->overlapped))
750 return LIBUSB_SUCCESS;
751 else if (GetLastError() == ERROR_NOT_FOUND)
752 return LIBUSB_ERROR_NOT_FOUND;
754 if (priv->backend->cancel_transfer)
755 return priv->backend->cancel_transfer(itransfer);
757 usbi_warn(ITRANSFER_CTX(itransfer), "cancellation not supported for this transfer's driver");
758 return LIBUSB_ERROR_NOT_SUPPORTED;
761 static int windows_handle_transfer_completion(struct usbi_transfer *itransfer)
763 struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
764 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
765 const struct windows_backend *backend = priv->backend;
766 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
767 enum libusb_transfer_status status, istatus;
768 DWORD result, bytes_transferred;
770 if (GetOverlappedResult(transfer_priv->handle, &transfer_priv->overlapped, &bytes_transferred, FALSE))
773 result = GetLastError();
775 usbi_dbg("handling transfer %p completion with errcode %lu, length %lu",
776 USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(result), ULONG_CAST(bytes_transferred));
780 status = backend->copy_transfer_data(itransfer, bytes_transferred);
782 case ERROR_GEN_FAILURE:
783 usbi_dbg("detected endpoint stall");
784 status = LIBUSB_TRANSFER_STALL;
786 case ERROR_SEM_TIMEOUT:
787 usbi_dbg("detected semaphore timeout");
788 status = LIBUSB_TRANSFER_TIMED_OUT;
790 case ERROR_OPERATION_ABORTED:
791 istatus = backend->copy_transfer_data(itransfer, bytes_transferred);
792 if (istatus != LIBUSB_TRANSFER_COMPLETED)
793 usbi_dbg("failed to copy partial data in aborted operation: %d", (int)istatus);
795 usbi_dbg("detected operation aborted");
796 status = LIBUSB_TRANSFER_CANCELLED;
798 case ERROR_FILE_NOT_FOUND:
799 case ERROR_DEVICE_NOT_CONNECTED:
800 case ERROR_NO_SUCH_DEVICE:
801 usbi_dbg("detected device removed");
802 status = LIBUSB_TRANSFER_NO_DEVICE;
805 usbi_err(ctx, "detected I/O error %lu: %s",
806 ULONG_CAST(result), windows_error_str(result));
807 status = LIBUSB_TRANSFER_ERROR;
811 transfer_priv->handle = NULL;
813 // Backend-specific cleanup
814 backend->clear_transfer_priv(itransfer);
816 if (status == LIBUSB_TRANSFER_CANCELLED)
817 return usbi_handle_transfer_cancellation(itransfer);
819 return usbi_handle_transfer_completion(itransfer, status);
822 #if !defined(HAVE_CLOCK_GETTIME)
823 int usbi_clock_gettime(int clk_id, struct timespec *tp)
825 LARGE_INTEGER hires_counter;
826 #if !defined(_MSC_VER) || (_MSC_VER < 1900)
828 ULARGE_INTEGER rtime;
832 case USBI_CLOCK_MONOTONIC:
833 if (hires_frequency) {
834 QueryPerformanceCounter(&hires_counter);
835 tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
836 tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) * hires_ticks_to_ps) / UINT64_C(1000));
839 // Return real-time if monotonic was not detected @ timer init
841 case USBI_CLOCK_REALTIME:
842 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
843 if (!timespec_get(tp, TIME_UTC)) {
848 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
849 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
850 // Note however that our resolution is bounded by the Windows system time
851 // functions and is at best of the order of 1 ms (or, usually, worse)
852 GetSystemTimeAsFileTime(&filetime);
853 rtime.LowPart = filetime.dwLowDateTime;
854 rtime.HighPart = filetime.dwHighDateTime;
855 rtime.QuadPart -= EPOCH_TIME;
856 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
857 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
867 // NB: MSVC6 does not support named initializers.
868 const struct usbi_os_backend usbi_backend = {
870 USBI_CAP_HAS_HID_ACCESS,
874 windows_get_device_list,
875 NULL, /* hotplug_poll */
876 NULL, /* wrap_sys_device */
879 windows_get_active_config_descriptor,
880 windows_get_config_descriptor,
881 windows_get_config_descriptor_by_value,
882 windows_get_configuration,
883 windows_set_configuration,
884 windows_claim_interface,
885 windows_release_interface,
886 windows_set_interface_altsetting,
888 windows_reset_device,
889 NULL, /* alloc_streams */
890 NULL, /* free_streams */
891 NULL, /* dev_mem_alloc */
892 NULL, /* dev_mem_free */
893 NULL, /* kernel_driver_active */
894 NULL, /* detach_kernel_driver */
895 NULL, /* attach_kernel_driver */
896 windows_destroy_device,
897 windows_submit_transfer,
898 windows_cancel_transfer,
899 NULL, /* clear_transfer_priv */
900 NULL, /* handle_events */
901 windows_handle_transfer_completion,
902 sizeof(struct windows_context_priv),
903 sizeof(union windows_device_priv),
904 sizeof(union windows_device_handle_priv),
905 sizeof(struct windows_transfer_priv),