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
32 #include "windows_common.h"
34 #define EPOCH_TIME UINT64_C(116444736000000000) // 1970.01.01 00:00:000 in MS Filetime
36 #define STATUS_SUCCESS ((ULONG_PTR)0UL)
39 enum windows_version windows_version = WINDOWS_UNDEFINED;
41 // Global variables for init/exit
42 static unsigned int init_count;
43 static bool usbdk_available;
45 #if !defined(HAVE_CLOCK_GETTIME)
46 // Global variables for clock_gettime mechanism
47 static uint64_t hires_ticks_to_ps;
48 static uint64_t hires_frequency;
52 * Converts a windows error to human readable string
53 * uses retval as errorcode, or, if 0, use GetLastError()
55 #if defined(ENABLE_LOGGING)
56 const char *windows_error_str(DWORD error_code)
58 static char err_string[256];
64 error_code = GetLastError();
66 len = sprintf(err_string, "[%lu] ", ULONG_CAST(error_code));
68 // Translate codes returned by SetupAPI. The ones we are dealing with are either
69 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
70 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
71 switch (error_code & 0xE0000000) {
73 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
76 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
82 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
83 NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
84 &err_string[len], sizeof(err_string) - len, NULL);
86 DWORD format_error = GetLastError();
88 snprintf(err_string, sizeof(err_string),
89 "Windows error code %lu (FormatMessage error code %lu)",
90 ULONG_CAST(error_code), ULONG_CAST(format_error));
92 snprintf(err_string, sizeof(err_string), "Unknown error code %lu",
93 ULONG_CAST(error_code));
95 // Remove CRLF from end of message, if present
96 size_t pos = len + size - 2;
97 if (err_string[pos] == '\r')
98 err_string[pos] = '\0';
105 /* Hash table functions - modified From glibc 2.3.2:
106 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
107 [Knuth] The Art of Computer Programming, part 3 (6.4) */
109 #define HTAB_SIZE 1021UL // *MUST* be a prime number!!
111 typedef struct htab_entry {
116 static htab_entry *htab_table;
117 static usbi_mutex_t htab_mutex;
118 static unsigned long htab_filled;
120 /* Before using the hash table we must allocate memory for it.
121 We allocate one element more as the found prime number says.
122 This is done for more effective indexing as explained in the
123 comment for the hash function. */
124 static bool htab_create(struct libusb_context *ctx)
126 if (htab_table != NULL) {
127 usbi_err(ctx, "program assertion falied - hash table already allocated");
132 usbi_mutex_init(&htab_mutex);
134 usbi_dbg("using %lu entries hash table", HTAB_SIZE);
137 // allocate memory and zero out.
138 htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
139 if (htab_table == NULL) {
140 usbi_err(ctx, "could not allocate space for hash table");
147 /* After using the hash table it has to be destroyed. */
148 static void htab_destroy(void)
152 if (htab_table == NULL)
155 for (i = 0; i < HTAB_SIZE; i++)
156 free(htab_table[i].str);
158 safe_free(htab_table);
160 usbi_mutex_destroy(&htab_mutex);
163 /* This is the search function. It uses double hashing with open addressing.
164 We use a trick to speed up the lookup. The table is created with one
165 more element available. This enables us to use the index zero special.
166 This index will never be used because we store the first hash index in
167 the field used where zero means not used. Every other value means used.
168 The used field can be used as a first fast comparison for equality of
169 the stored and the parameter value. This helps to prevent unnecessary
170 expensive calls of strcmp. */
171 unsigned long htab_hash(const char *str)
173 unsigned long hval, hval2;
175 unsigned long r = 5381UL;
177 const char *sz = str;
182 // Compute main hash value (algorithm suggested by Nokia)
183 while ((c = *sz++) != 0)
184 r = ((r << 5) + r) + c;
188 // compute table hash: simply take the modulus
189 hval = r % HTAB_SIZE;
193 // Try the first index
196 // Mutually exclusive access (R/W lock would be better)
197 usbi_mutex_lock(&htab_mutex);
199 if (htab_table[idx].used) {
200 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
201 goto out_unlock; // existing hash
203 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
205 // Second hash function, as suggested in [Knuth]
206 hval2 = 1UL + hval % (HTAB_SIZE - 2);
209 // Because size is prime this guarantees to step through all available indexes
211 idx = HTAB_SIZE + idx - hval2;
215 // If we visited all entries leave the loop unsuccessfully
219 // If entry is found use it.
220 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
222 } while (htab_table[idx].used);
225 // Not found => New entry
227 // If the table is full return an error
228 if (htab_filled >= HTAB_SIZE) {
229 usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
234 htab_table[idx].str = _strdup(str);
235 if (htab_table[idx].str == NULL) {
236 usbi_err(NULL, "could not duplicate string for hash table");
241 htab_table[idx].used = hval;
245 usbi_mutex_unlock(&htab_mutex);
250 enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS status)
252 if (USBD_SUCCESS(status))
253 return LIBUSB_TRANSFER_COMPLETED;
256 case USBD_STATUS_TIMEOUT:
257 return LIBUSB_TRANSFER_TIMED_OUT;
258 case USBD_STATUS_CANCELED:
259 return LIBUSB_TRANSFER_CANCELLED;
260 case USBD_STATUS_ENDPOINT_HALTED:
261 return LIBUSB_TRANSFER_STALL;
262 case USBD_STATUS_DEVICE_GONE:
263 return LIBUSB_TRANSFER_NO_DEVICE;
265 usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", ULONG_CAST(status));
266 return LIBUSB_TRANSFER_ERROR;
271 * Make a transfer complete synchronously
273 void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
275 overlapped->Internal = (ULONG_PTR)STATUS_SUCCESS;
276 overlapped->InternalHigh = (ULONG_PTR)size;
277 SetEvent(overlapped->hEvent);
280 static void windows_init_clock(void)
282 #if !defined(HAVE_CLOCK_GETTIME)
283 LARGE_INTEGER li_frequency;
285 // Microsoft says that the QueryPerformanceFrequency() and
286 // QueryPerformanceCounter() functions always succeed on XP and later
287 QueryPerformanceFrequency(&li_frequency);
289 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
290 // to picoseconds to compute the tv_nsecs part in clock_gettime
291 hires_frequency = li_frequency.QuadPart;
292 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
293 usbi_dbg("hires timer frequency: %"PRIu64" Hz", hires_frequency);
297 /* Windows version detection */
298 static BOOL is_x64(void)
302 // Detect if we're running a 32 or 64 bit system
303 if (sizeof(uintptr_t) < 8) {
304 IsWow64Process(GetCurrentProcess(), &ret);
312 static void get_windows_version(void)
314 OSVERSIONINFOEXA vi, vi2;
315 const char *arch, *w = NULL;
316 unsigned major, minor, version;
317 ULONGLONG major_equal, minor_equal;
320 windows_version = WINDOWS_UNDEFINED;
322 memset(&vi, 0, sizeof(vi));
323 vi.dwOSVersionInfoSize = sizeof(vi);
324 if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
325 memset(&vi, 0, sizeof(vi));
326 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
327 if (!GetVersionExA((OSVERSIONINFOA *)&vi))
331 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
334 if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
335 // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
336 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
338 major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
339 for (major = vi.dwMajorVersion; major <= 9; major++) {
340 memset(&vi2, 0, sizeof(vi2));
341 vi2.dwOSVersionInfoSize = sizeof(vi2);
342 vi2.dwMajorVersion = major;
343 if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
346 if (vi.dwMajorVersion < major) {
347 vi.dwMajorVersion = major;
348 vi.dwMinorVersion = 0;
351 minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
352 for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
353 memset(&vi2, 0, sizeof(vi2));
354 vi2.dwOSVersionInfoSize = sizeof(vi2);
355 vi2.dwMinorVersion = minor;
356 if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
359 vi.dwMinorVersion = minor;
367 if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
370 ws = (vi.wProductType <= VER_NT_WORKSTATION);
371 version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
373 case 0x50: windows_version = WINDOWS_2000; w = "2000"; break;
374 case 0x51: windows_version = WINDOWS_XP; w = "XP"; break;
375 case 0x52: windows_version = WINDOWS_2003; w = "2003"; break;
376 case 0x60: windows_version = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break;
377 case 0x61: windows_version = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break;
378 case 0x62: windows_version = WINDOWS_8; w = (ws ? "8" : "2012"); break;
379 case 0x63: windows_version = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break;
380 case 0x64: // Early Windows 10 Insider Previews and Windows Server 2017 Technical Preview 1 used version 6.4
381 case 0xA0: windows_version = WINDOWS_10; w = (ws ? "10" : "2016"); break;
383 if (version < 0x50) {
386 windows_version = WINDOWS_11_OR_LATER;
391 arch = is_x64() ? "64-bit" : "32-bit";
393 if (vi.wServicePackMinor)
394 usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
395 else if (vi.wServicePackMajor)
396 usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
398 usbi_dbg("Windows %s %s", w, arch);
401 static void windows_transfer_callback(const struct windows_backend *backend,
402 struct usbi_transfer *itransfer, DWORD error, DWORD bytes_transferred)
404 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
405 enum libusb_transfer_status status, istatus;
407 usbi_dbg("handling I/O completion with errcode %lu, length %lu",
408 ULONG_CAST(error), ULONG_CAST(bytes_transferred));
412 status = backend->copy_transfer_data(itransfer, bytes_transferred);
414 case ERROR_GEN_FAILURE:
415 usbi_dbg("detected endpoint stall");
416 status = LIBUSB_TRANSFER_STALL;
418 case ERROR_SEM_TIMEOUT:
419 usbi_dbg("detected semaphore timeout");
420 status = LIBUSB_TRANSFER_TIMED_OUT;
422 case ERROR_OPERATION_ABORTED:
423 istatus = backend->copy_transfer_data(itransfer, bytes_transferred);
424 if (istatus != LIBUSB_TRANSFER_COMPLETED)
425 usbi_dbg("failed to copy partial data in aborted operation: %d", (int)istatus);
427 usbi_dbg("detected operation aborted");
428 status = LIBUSB_TRANSFER_CANCELLED;
430 case ERROR_FILE_NOT_FOUND:
431 case ERROR_DEVICE_NOT_CONNECTED:
432 usbi_dbg("detected device removed");
433 status = LIBUSB_TRANSFER_NO_DEVICE;
436 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %lu: %s",
437 ULONG_CAST(error), windows_error_str(error));
438 status = LIBUSB_TRANSFER_ERROR;
443 usbi_close(transfer_priv->pollable_fd.fd);
444 transfer_priv->pollable_fd = INVALID_WINFD;
445 transfer_priv->handle = NULL;
447 // Backend-specific cleanup
448 backend->clear_transfer_priv(itransfer);
450 if (status == LIBUSB_TRANSFER_CANCELLED)
451 usbi_handle_transfer_cancellation(itransfer);
453 usbi_handle_transfer_completion(itransfer, status);
456 static int windows_init(struct libusb_context *ctx)
458 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
459 char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
461 int r = LIBUSB_ERROR_OTHER;
462 bool winusb_backend_init = false;
464 sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
465 mutex = CreateMutexA(NULL, FALSE, mutex_name);
467 usbi_err(ctx, "could not create mutex: %s", windows_error_str(0));
468 return LIBUSB_ERROR_NO_MEM;
471 // A successful wait gives this thread ownership of the mutex
472 // => any concurent wait stalls until the mutex is released
473 if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
474 usbi_err(ctx, "failure to access mutex: %s", windows_error_str(0));
476 return LIBUSB_ERROR_NO_MEM;
479 // NB: concurrent usage supposes that init calls are equally balanced with
480 // exit calls. If init is called more than exit, we will not exit properly
481 if (++init_count == 1) { // First init?
482 get_windows_version();
484 if (windows_version == WINDOWS_UNDEFINED) {
485 usbi_err(ctx, "failed to detect Windows version");
486 r = LIBUSB_ERROR_NOT_SUPPORTED;
490 windows_init_clock();
492 if (!htab_create(ctx))
495 r = winusb_backend.init(ctx);
496 if (r != LIBUSB_SUCCESS)
498 winusb_backend_init = true;
500 r = usbdk_backend.init(ctx);
501 if (r == LIBUSB_SUCCESS) {
502 usbi_dbg("UsbDk backend is available");
503 usbdk_available = true;
505 usbi_info(ctx, "UsbDk backend is not available");
506 // Do not report this as an error
511 // By default, new contexts will use the WinUSB backend
512 priv->backend = &winusb_backend;
516 init_exit: // Holds semaphore here
517 if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
518 if (winusb_backend_init)
519 winusb_backend.exit(ctx);
529 static void windows_exit(struct libusb_context *ctx)
531 char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
534 sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
535 mutex = CreateMutexA(NULL, FALSE, mutex_name);
539 // A successful wait gives this thread ownership of the mutex
540 // => any concurent wait stalls until the mutex is released
541 if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
542 usbi_err(ctx, "failed to access mutex: %s", windows_error_str(0));
547 // Only works if exits and inits are balanced exactly
548 if (--init_count == 0) { // Last exit
549 if (usbdk_available) {
550 usbdk_backend.exit(ctx);
551 usbdk_available = false;
553 winusb_backend.exit(ctx);
561 static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
563 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
568 case LIBUSB_OPTION_USE_USBDK:
569 if (usbdk_available) {
570 usbi_dbg("switching context %p to use UsbDk backend", ctx);
571 priv->backend = &usbdk_backend;
573 usbi_err(ctx, "UsbDk backend not available");
574 return LIBUSB_ERROR_NOT_FOUND;
576 return LIBUSB_SUCCESS;
578 return LIBUSB_ERROR_NOT_SUPPORTED;
582 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
584 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
585 return priv->backend->get_device_list(ctx, discdevs);
588 static int windows_open(struct libusb_device_handle *dev_handle)
590 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
591 return priv->backend->open(dev_handle);
594 static void windows_close(struct libusb_device_handle *dev_handle)
596 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
597 priv->backend->close(dev_handle);
600 static int windows_get_device_descriptor(struct libusb_device *dev,
601 unsigned char *buffer, int *host_endian)
603 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
605 return priv->backend->get_device_descriptor(dev, buffer);
608 static int windows_get_active_config_descriptor(struct libusb_device *dev,
609 unsigned char *buffer, size_t len, int *host_endian)
611 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
613 return priv->backend->get_active_config_descriptor(dev, buffer, len);
616 static int windows_get_config_descriptor(struct libusb_device *dev,
617 uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
619 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
621 return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
624 static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
625 uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian)
627 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
629 return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
632 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
634 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
635 return priv->backend->get_configuration(dev_handle, config);
638 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
640 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
641 return priv->backend->set_configuration(dev_handle, config);
644 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
646 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
647 return priv->backend->claim_interface(dev_handle, interface_number);
650 static int windows_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
652 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
653 return priv->backend->release_interface(dev_handle, interface_number);
656 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
657 int interface_number, int altsetting)
659 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
660 return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
663 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
665 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
666 return priv->backend->clear_halt(dev_handle, endpoint);
669 static int windows_reset_device(struct libusb_device_handle *dev_handle)
671 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
672 return priv->backend->reset_device(dev_handle);
675 static void windows_destroy_device(struct libusb_device *dev)
677 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
678 priv->backend->destroy_device(dev);
681 static int windows_submit_transfer(struct usbi_transfer *itransfer)
683 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
684 struct libusb_context *ctx = TRANSFER_CTX(transfer);
685 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
686 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
690 switch (transfer->type) {
691 case LIBUSB_TRANSFER_TYPE_CONTROL:
692 events = (transfer->buffer[0] & LIBUSB_ENDPOINT_IN) ? POLLIN : POLLOUT;
694 case LIBUSB_TRANSFER_TYPE_BULK:
695 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
696 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
697 events = IS_XFERIN(transfer) ? POLLIN : POLLOUT;
699 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
700 usbi_warn(ctx, "bulk stream transfers are not yet supported on this platform");
701 return LIBUSB_ERROR_NOT_SUPPORTED;
703 usbi_err(ctx, "unknown endpoint type %d", transfer->type);
704 return LIBUSB_ERROR_INVALID_PARAM;
707 // Because a Windows OVERLAPPED is used for poll emulation,
708 // a pollable fd is created and stored with each transfer
709 transfer_priv->pollable_fd = usbi_create_fd();
710 if (transfer_priv->pollable_fd.fd < 0) {
711 usbi_err(ctx, "failed to create pollable fd");
712 return LIBUSB_ERROR_NO_MEM;
715 if (transfer_priv->handle != NULL) {
716 usbi_err(ctx, "program assertion failed - transfer HANDLE is not NULL");
717 transfer_priv->handle = NULL;
720 r = priv->backend->submit_transfer(itransfer);
721 if (r != LIBUSB_SUCCESS) {
722 // Always call the backend's clear_transfer_priv() function on failure
723 priv->backend->clear_transfer_priv(itransfer);
724 // Release the pollable fd since it won't be used
725 usbi_close(transfer_priv->pollable_fd.fd);
726 transfer_priv->pollable_fd = INVALID_WINFD;
727 transfer_priv->handle = NULL;
731 // The backend should set the HANDLE used for each submitted transfer
732 // by calling set_transfer_priv_handle()
733 if (transfer_priv->handle == NULL)
734 usbi_err(ctx, "program assertion failed - transfer HANDLE is NULL after transfer was submitted");
736 // We don't want to start monitoring the pollable fd before the transfer
737 // has been submitted, so start monitoring it now. Note that if the
738 // usbi_add_pollfd() function fails, the user will never get notified
739 // that the transfer has completed. We don't attempt any cleanup if this
740 // happens because the transfer is already in progress and could even have
742 if (usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, events))
743 usbi_err(ctx, "failed to add pollable fd %d for transfer %p",
744 transfer_priv->pollable_fd.fd, transfer);
749 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
751 struct windows_context_priv *priv = usbi_get_context_priv(ITRANSFER_CTX(itransfer));
752 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
754 // Try CancelIoEx() on the transfer
755 // If that fails, fall back to the backend's cancel_transfer()
756 // function if it is available
757 if (CancelIoEx(transfer_priv->handle, transfer_priv->pollable_fd.overlapped))
758 return LIBUSB_SUCCESS;
759 else if (GetLastError() == ERROR_NOT_FOUND)
760 return LIBUSB_ERROR_NOT_FOUND;
762 if (priv->backend->cancel_transfer)
763 return priv->backend->cancel_transfer(itransfer);
765 usbi_warn(ITRANSFER_CTX(itransfer), "cancellation not supported for this transfer's driver");
766 return LIBUSB_ERROR_NOT_SUPPORTED;
769 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, usbi_nfds_t nfds, int num_ready)
771 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
772 struct usbi_transfer *itransfer;
773 struct windows_transfer_priv *transfer_priv;
774 DWORD result, bytes_transferred;
776 int r = LIBUSB_SUCCESS;
778 usbi_mutex_lock(&ctx->open_devs_lock);
779 for (i = 0; i < nfds && num_ready > 0; i++) {
780 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
787 transfer_priv = NULL;
788 usbi_mutex_lock(&ctx->flying_transfers_lock);
789 list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
790 transfer_priv = usbi_get_transfer_priv(itransfer);
791 if (transfer_priv->pollable_fd.fd == fds[i].fd)
793 transfer_priv = NULL;
795 usbi_mutex_unlock(&ctx->flying_transfers_lock);
797 if (transfer_priv == NULL) {
798 usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd);
799 r = LIBUSB_ERROR_NOT_FOUND;
803 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
805 if (GetOverlappedResult(transfer_priv->handle, transfer_priv->pollable_fd.overlapped, &bytes_transferred, FALSE))
808 result = GetLastError();
810 windows_transfer_callback(priv->backend, itransfer, result, bytes_transferred);
812 usbi_mutex_unlock(&ctx->open_devs_lock);
817 #if !defined(HAVE_CLOCK_GETTIME)
818 int usbi_clock_gettime(int clk_id, struct timespec *tp)
820 LARGE_INTEGER hires_counter;
821 #if !defined(_MSC_VER) || (_MSC_VER < 1900)
823 ULARGE_INTEGER rtime;
827 case USBI_CLOCK_MONOTONIC:
828 if (hires_frequency) {
829 QueryPerformanceCounter(&hires_counter);
830 tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
831 tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) * hires_ticks_to_ps) / UINT64_C(1000));
832 return LIBUSB_SUCCESS;
834 // Fall through and return real-time if monotonic was not detected @ timer init
835 case USBI_CLOCK_REALTIME:
836 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
837 if (!timespec_get(tp, TIME_UTC))
838 return LIBUSB_ERROR_OTHER;
840 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
841 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
842 // Note however that our resolution is bounded by the Windows system time
843 // functions and is at best of the order of 1 ms (or, usually, worse)
844 GetSystemTimeAsFileTime(&filetime);
845 rtime.LowPart = filetime.dwLowDateTime;
846 rtime.HighPart = filetime.dwHighDateTime;
847 rtime.QuadPart -= EPOCH_TIME;
848 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
849 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
851 return LIBUSB_SUCCESS;
853 return LIBUSB_ERROR_INVALID_PARAM;
858 // NB: MSVC6 does not support named initializers.
859 const struct usbi_os_backend usbi_backend = {
861 USBI_CAP_HAS_HID_ACCESS,
865 windows_get_device_list,
866 NULL, /* hotplug_poll */
867 NULL, /* wrap_sys_device */
870 windows_get_device_descriptor,
871 windows_get_active_config_descriptor,
872 windows_get_config_descriptor,
873 windows_get_config_descriptor_by_value,
874 windows_get_configuration,
875 windows_set_configuration,
876 windows_claim_interface,
877 windows_release_interface,
878 windows_set_interface_altsetting,
880 windows_reset_device,
881 NULL, /* alloc_streams */
882 NULL, /* free_streams */
883 NULL, /* dev_mem_alloc */
884 NULL, /* dev_mem_free */
885 NULL, /* kernel_driver_active */
886 NULL, /* detach_kernel_driver */
887 NULL, /* attach_kernel_driver */
888 windows_destroy_device,
889 windows_submit_transfer,
890 windows_cancel_transfer,
891 NULL, /* clear_transfer_priv */
892 windows_handle_events,
893 NULL, /* handle_transfer_completion */
894 sizeof(struct windows_context_priv),
895 sizeof(union windows_device_priv),
896 sizeof(union windows_device_handle_priv),
897 sizeof(struct windows_transfer_priv),