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 // Global variables for clock_gettime mechanism
46 static uint64_t hires_ticks_to_ps;
47 static uint64_t hires_frequency;
50 * Converts a windows error to human readable string
51 * uses retval as errorcode, or, if 0, use GetLastError()
53 #if defined(ENABLE_LOGGING)
54 const char *windows_error_str(DWORD error_code)
56 static char err_string[256];
62 error_code = GetLastError();
64 len = sprintf(err_string, "[%lu] ", ULONG_CAST(error_code));
66 // Translate codes returned by SetupAPI. The ones we are dealing with are either
67 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
68 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
69 switch (error_code & 0xE0000000) {
71 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
74 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
80 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
81 NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
82 &err_string[len], sizeof(err_string) - len, NULL);
84 DWORD format_error = GetLastError();
86 snprintf(err_string, sizeof(err_string),
87 "Windows error code %lu (FormatMessage error code %lu)",
88 ULONG_CAST(error_code), ULONG_CAST(format_error));
90 snprintf(err_string, sizeof(err_string), "Unknown error code %lu",
91 ULONG_CAST(error_code));
93 // Remove CRLF from end of message, if present
94 size_t pos = len + size - 2;
95 if (err_string[pos] == '\r')
96 err_string[pos] = '\0';
103 /* Hash table functions - modified From glibc 2.3.2:
104 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
105 [Knuth] The Art of Computer Programming, part 3 (6.4) */
107 #define HTAB_SIZE 1021UL // *MUST* be a prime number!!
109 typedef struct htab_entry {
114 static htab_entry *htab_table;
115 static usbi_mutex_t htab_mutex;
116 static unsigned long htab_filled;
118 /* Before using the hash table we must allocate memory for it.
119 We allocate one element more as the found prime number says.
120 This is done for more effective indexing as explained in the
121 comment for the hash function. */
122 static bool htab_create(struct libusb_context *ctx)
124 if (htab_table != NULL) {
125 usbi_err(ctx, "program assertion falied - hash table already allocated");
130 usbi_mutex_init(&htab_mutex);
132 usbi_dbg("using %lu entries hash table", HTAB_SIZE);
135 // allocate memory and zero out.
136 htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
137 if (htab_table == NULL) {
138 usbi_err(ctx, "could not allocate space for hash table");
145 /* After using the hash table it has to be destroyed. */
146 static void htab_destroy(void)
150 if (htab_table == NULL)
153 for (i = 0; i < HTAB_SIZE; i++)
154 free(htab_table[i].str);
156 safe_free(htab_table);
158 usbi_mutex_destroy(&htab_mutex);
161 /* This is the search function. It uses double hashing with open addressing.
162 We use a trick to speed up the lookup. The table is created with one
163 more element available. This enables us to use the index zero special.
164 This index will never be used because we store the first hash index in
165 the field used where zero means not used. Every other value means used.
166 The used field can be used as a first fast comparison for equality of
167 the stored and the parameter value. This helps to prevent unnecessary
168 expensive calls of strcmp. */
169 unsigned long htab_hash(const char *str)
171 unsigned long hval, hval2;
173 unsigned long r = 5381UL;
175 const char *sz = str;
180 // Compute main hash value (algorithm suggested by Nokia)
181 while ((c = *sz++) != 0)
182 r = ((r << 5) + r) + c;
186 // compute table hash: simply take the modulus
187 hval = r % HTAB_SIZE;
191 // Try the first index
194 // Mutually exclusive access (R/W lock would be better)
195 usbi_mutex_lock(&htab_mutex);
197 if (htab_table[idx].used) {
198 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
199 goto out_unlock; // existing hash
201 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
203 // Second hash function, as suggested in [Knuth]
204 hval2 = 1UL + hval % (HTAB_SIZE - 2);
207 // Because size is prime this guarantees to step through all available indexes
209 idx = HTAB_SIZE + idx - hval2;
213 // If we visited all entries leave the loop unsuccessfully
217 // If entry is found use it.
218 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
220 } while (htab_table[idx].used);
223 // Not found => New entry
225 // If the table is full return an error
226 if (htab_filled >= HTAB_SIZE) {
227 usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
232 htab_table[idx].str = _strdup(str);
233 if (htab_table[idx].str == NULL) {
234 usbi_err(NULL, "could not duplicate string for hash table");
239 htab_table[idx].used = hval;
243 usbi_mutex_unlock(&htab_mutex);
248 enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS status)
250 if (USBD_SUCCESS(status))
251 return LIBUSB_TRANSFER_COMPLETED;
254 case USBD_STATUS_TIMEOUT:
255 return LIBUSB_TRANSFER_TIMED_OUT;
256 case USBD_STATUS_CANCELED:
257 return LIBUSB_TRANSFER_CANCELLED;
258 case USBD_STATUS_ENDPOINT_HALTED:
259 return LIBUSB_TRANSFER_STALL;
260 case USBD_STATUS_DEVICE_GONE:
261 return LIBUSB_TRANSFER_NO_DEVICE;
263 usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", ULONG_CAST(status));
264 return LIBUSB_TRANSFER_ERROR;
269 * Make a transfer complete synchronously
271 void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
273 overlapped->Internal = (ULONG_PTR)STATUS_SUCCESS;
274 overlapped->InternalHigh = (ULONG_PTR)size;
275 SetEvent(overlapped->hEvent);
278 static void windows_init_clock(void)
280 LARGE_INTEGER li_frequency;
282 // Microsoft says that the QueryPerformanceFrequency() and
283 // QueryPerformanceCounter() functions always succeed on XP and later
284 QueryPerformanceFrequency(&li_frequency);
286 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
287 // to picoseconds to compute the tv_nsecs part in clock_gettime
288 hires_frequency = li_frequency.QuadPart;
289 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
290 usbi_dbg("hires timer frequency: %"PRIu64" Hz", hires_frequency);
293 /* Windows version detection */
294 static BOOL is_x64(void)
298 // Detect if we're running a 32 or 64 bit system
299 if (sizeof(uintptr_t) < 8) {
300 IsWow64Process(GetCurrentProcess(), &ret);
308 static void get_windows_version(void)
310 OSVERSIONINFOEXA vi, vi2;
311 const char *arch, *w = NULL;
312 unsigned major, minor, version;
313 ULONGLONG major_equal, minor_equal;
316 windows_version = WINDOWS_UNDEFINED;
318 memset(&vi, 0, sizeof(vi));
319 vi.dwOSVersionInfoSize = sizeof(vi);
320 if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
321 memset(&vi, 0, sizeof(vi));
322 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
323 if (!GetVersionExA((OSVERSIONINFOA *)&vi))
327 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
330 if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
331 // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
332 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
334 major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
335 for (major = vi.dwMajorVersion; major <= 9; major++) {
336 memset(&vi2, 0, sizeof(vi2));
337 vi2.dwOSVersionInfoSize = sizeof(vi2);
338 vi2.dwMajorVersion = major;
339 if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
342 if (vi.dwMajorVersion < major) {
343 vi.dwMajorVersion = major;
344 vi.dwMinorVersion = 0;
347 minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
348 for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
349 memset(&vi2, 0, sizeof(vi2));
350 vi2.dwOSVersionInfoSize = sizeof(vi2);
351 vi2.dwMinorVersion = minor;
352 if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
355 vi.dwMinorVersion = minor;
363 if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
366 ws = (vi.wProductType <= VER_NT_WORKSTATION);
367 version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
369 case 0x50: windows_version = WINDOWS_2000; w = "2000"; break;
370 case 0x51: windows_version = WINDOWS_XP; w = "XP"; break;
371 case 0x52: windows_version = WINDOWS_2003; w = "2003"; break;
372 case 0x60: windows_version = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break;
373 case 0x61: windows_version = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break;
374 case 0x62: windows_version = WINDOWS_8; w = (ws ? "8" : "2012"); break;
375 case 0x63: windows_version = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break;
376 case 0x64: // Early Windows 10 Insider Previews and Windows Server 2017 Technical Preview 1 used version 6.4
377 case 0xA0: windows_version = WINDOWS_10; w = (ws ? "10" : "2016"); break;
379 if (version < 0x50) {
382 windows_version = WINDOWS_11_OR_LATER;
387 arch = is_x64() ? "64-bit" : "32-bit";
389 if (vi.wServicePackMinor)
390 usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
391 else if (vi.wServicePackMajor)
392 usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
394 usbi_dbg("Windows %s %s", w, arch);
397 static void windows_transfer_callback(const struct windows_backend *backend,
398 struct usbi_transfer *itransfer, DWORD error, DWORD bytes_transferred)
400 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
401 enum libusb_transfer_status status, istatus;
403 usbi_dbg("handling I/O completion with errcode %lu, length %lu",
404 ULONG_CAST(error), ULONG_CAST(bytes_transferred));
408 status = backend->copy_transfer_data(itransfer, bytes_transferred);
410 case ERROR_GEN_FAILURE:
411 usbi_dbg("detected endpoint stall");
412 status = LIBUSB_TRANSFER_STALL;
414 case ERROR_SEM_TIMEOUT:
415 usbi_dbg("detected semaphore timeout");
416 status = LIBUSB_TRANSFER_TIMED_OUT;
418 case ERROR_OPERATION_ABORTED:
419 istatus = backend->copy_transfer_data(itransfer, bytes_transferred);
420 if (istatus != LIBUSB_TRANSFER_COMPLETED)
421 usbi_dbg("failed to copy partial data in aborted operation: %d", (int)istatus);
423 usbi_dbg("detected operation aborted");
424 status = LIBUSB_TRANSFER_CANCELLED;
426 case ERROR_FILE_NOT_FOUND:
427 case ERROR_DEVICE_NOT_CONNECTED:
428 usbi_dbg("detected device removed");
429 status = LIBUSB_TRANSFER_NO_DEVICE;
432 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %lu: %s",
433 ULONG_CAST(error), windows_error_str(error));
434 status = LIBUSB_TRANSFER_ERROR;
439 usbi_close(transfer_priv->pollable_fd.fd);
440 transfer_priv->pollable_fd = INVALID_WINFD;
441 transfer_priv->handle = NULL;
443 // Backend-specific cleanup
444 backend->clear_transfer_priv(itransfer);
446 if (status == LIBUSB_TRANSFER_CANCELLED)
447 usbi_handle_transfer_cancellation(itransfer);
449 usbi_handle_transfer_completion(itransfer, status);
452 static int windows_init(struct libusb_context *ctx)
454 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
455 char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
457 int r = LIBUSB_ERROR_OTHER;
458 bool winusb_backend_init = false;
460 sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
461 mutex = CreateMutexA(NULL, FALSE, mutex_name);
463 usbi_err(ctx, "could not create mutex: %s", windows_error_str(0));
464 return LIBUSB_ERROR_NO_MEM;
467 // A successful wait gives this thread ownership of the mutex
468 // => any concurent wait stalls until the mutex is released
469 if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
470 usbi_err(ctx, "failure to access mutex: %s", windows_error_str(0));
472 return LIBUSB_ERROR_NO_MEM;
475 // NB: concurrent usage supposes that init calls are equally balanced with
476 // exit calls. If init is called more than exit, we will not exit properly
477 if (++init_count == 1) { // First init?
478 get_windows_version();
480 if (windows_version == WINDOWS_UNDEFINED) {
481 usbi_err(ctx, "failed to detect Windows version");
482 r = LIBUSB_ERROR_NOT_SUPPORTED;
486 windows_init_clock();
488 if (!htab_create(ctx))
491 r = winusb_backend.init(ctx);
492 if (r != LIBUSB_SUCCESS)
494 winusb_backend_init = true;
496 r = usbdk_backend.init(ctx);
497 if (r == LIBUSB_SUCCESS) {
498 usbi_dbg("UsbDk backend is available");
499 usbdk_available = true;
501 usbi_info(ctx, "UsbDk backend is not available");
502 // Do not report this as an error
507 // By default, new contexts will use the WinUSB backend
508 priv->backend = &winusb_backend;
512 init_exit: // Holds semaphore here
513 if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
514 if (winusb_backend_init)
515 winusb_backend.exit(ctx);
525 static void windows_exit(struct libusb_context *ctx)
527 char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
530 sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
531 mutex = CreateMutexA(NULL, FALSE, mutex_name);
535 // A successful wait gives this thread ownership of the mutex
536 // => any concurent wait stalls until the mutex is released
537 if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
538 usbi_err(ctx, "failed to access mutex: %s", windows_error_str(0));
543 // Only works if exits and inits are balanced exactly
544 if (--init_count == 0) { // Last exit
545 if (usbdk_available) {
546 usbdk_backend.exit(ctx);
547 usbdk_available = false;
549 winusb_backend.exit(ctx);
557 static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
559 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
564 case LIBUSB_OPTION_USE_USBDK:
565 if (usbdk_available) {
566 usbi_dbg("switching context %p to use UsbDk backend", ctx);
567 priv->backend = &usbdk_backend;
569 usbi_err(ctx, "UsbDk backend not available");
570 return LIBUSB_ERROR_NOT_FOUND;
572 return LIBUSB_SUCCESS;
574 return LIBUSB_ERROR_NOT_SUPPORTED;
578 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
580 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
581 return priv->backend->get_device_list(ctx, discdevs);
584 static int windows_open(struct libusb_device_handle *dev_handle)
586 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
587 return priv->backend->open(dev_handle);
590 static void windows_close(struct libusb_device_handle *dev_handle)
592 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
593 priv->backend->close(dev_handle);
596 static int windows_get_device_descriptor(struct libusb_device *dev,
597 unsigned char *buffer, int *host_endian)
599 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
601 return priv->backend->get_device_descriptor(dev, buffer);
604 static int windows_get_active_config_descriptor(struct libusb_device *dev,
605 unsigned char *buffer, size_t len, int *host_endian)
607 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
609 return priv->backend->get_active_config_descriptor(dev, buffer, len);
612 static int windows_get_config_descriptor(struct libusb_device *dev,
613 uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
615 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
617 return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
620 static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
621 uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian)
623 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
625 return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
628 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
630 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
631 return priv->backend->get_configuration(dev_handle, config);
634 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
636 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
637 return priv->backend->set_configuration(dev_handle, config);
640 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
642 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
643 return priv->backend->claim_interface(dev_handle, interface_number);
646 static int windows_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
648 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
649 return priv->backend->release_interface(dev_handle, interface_number);
652 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
653 int interface_number, int altsetting)
655 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
656 return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
659 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
661 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
662 return priv->backend->clear_halt(dev_handle, endpoint);
665 static int windows_reset_device(struct libusb_device_handle *dev_handle)
667 struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
668 return priv->backend->reset_device(dev_handle);
671 static void windows_destroy_device(struct libusb_device *dev)
673 struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
674 priv->backend->destroy_device(dev);
677 static int windows_submit_transfer(struct usbi_transfer *itransfer)
679 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
680 struct libusb_context *ctx = TRANSFER_CTX(transfer);
681 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
682 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
686 switch (transfer->type) {
687 case LIBUSB_TRANSFER_TYPE_CONTROL:
688 events = (transfer->buffer[0] & LIBUSB_ENDPOINT_IN) ? POLLIN : POLLOUT;
690 case LIBUSB_TRANSFER_TYPE_BULK:
691 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
692 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
693 events = IS_XFERIN(transfer) ? POLLIN : POLLOUT;
695 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
696 usbi_warn(ctx, "bulk stream transfers are not yet supported on this platform");
697 return LIBUSB_ERROR_NOT_SUPPORTED;
699 usbi_err(ctx, "unknown endpoint type %d", transfer->type);
700 return LIBUSB_ERROR_INVALID_PARAM;
703 // Because a Windows OVERLAPPED is used for poll emulation,
704 // a pollable fd is created and stored with each transfer
705 transfer_priv->pollable_fd = usbi_create_fd();
706 if (transfer_priv->pollable_fd.fd < 0) {
707 usbi_err(ctx, "failed to create pollable fd");
708 return LIBUSB_ERROR_NO_MEM;
711 if (transfer_priv->handle != NULL) {
712 usbi_err(ctx, "program assertion failed - transfer HANDLE is not NULL");
713 transfer_priv->handle = NULL;
716 r = priv->backend->submit_transfer(itransfer);
717 if (r != LIBUSB_SUCCESS) {
718 // Always call the backend's clear_transfer_priv() function on failure
719 priv->backend->clear_transfer_priv(itransfer);
720 // Release the pollable fd since it won't be used
721 usbi_close(transfer_priv->pollable_fd.fd);
722 transfer_priv->pollable_fd = INVALID_WINFD;
723 transfer_priv->handle = NULL;
727 // The backend should set the HANDLE used for each submitted transfer
728 // by calling set_transfer_priv_handle()
729 if (transfer_priv->handle == NULL)
730 usbi_err(ctx, "program assertion failed - transfer HANDLE is NULL after transfer was submitted");
732 // We don't want to start monitoring the pollable fd before the transfer
733 // has been submitted, so start monitoring it now. Note that if the
734 // usbi_add_pollfd() function fails, the user will never get notified
735 // that the transfer has completed. We don't attempt any cleanup if this
736 // happens because the transfer is already in progress and could even have
738 if (usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, events))
739 usbi_err(ctx, "failed to add pollable fd %d for transfer %p",
740 transfer_priv->pollable_fd.fd, transfer);
745 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
747 struct windows_context_priv *priv = usbi_get_context_priv(ITRANSFER_CTX(itransfer));
748 struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
750 // Try CancelIoEx() on the transfer
751 // If that fails, fall back to the backend's cancel_transfer()
752 // function if it is available
753 if (CancelIoEx(transfer_priv->handle, transfer_priv->pollable_fd.overlapped))
754 return LIBUSB_SUCCESS;
755 else if (GetLastError() == ERROR_NOT_FOUND)
756 return LIBUSB_ERROR_NOT_FOUND;
758 if (priv->backend->cancel_transfer)
759 return priv->backend->cancel_transfer(itransfer);
761 usbi_warn(ITRANSFER_CTX(itransfer), "cancellation not supported for this transfer's driver");
762 return LIBUSB_ERROR_NOT_SUPPORTED;
765 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, usbi_nfds_t nfds, int num_ready)
767 struct windows_context_priv *priv = usbi_get_context_priv(ctx);
768 struct usbi_transfer *itransfer;
769 struct windows_transfer_priv *transfer_priv;
770 DWORD result, bytes_transferred;
772 int r = LIBUSB_SUCCESS;
774 usbi_mutex_lock(&ctx->open_devs_lock);
775 for (i = 0; i < nfds && num_ready > 0; i++) {
776 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
783 transfer_priv = NULL;
784 usbi_mutex_lock(&ctx->flying_transfers_lock);
785 list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
786 transfer_priv = usbi_get_transfer_priv(itransfer);
787 if (transfer_priv->pollable_fd.fd == fds[i].fd)
789 transfer_priv = NULL;
791 usbi_mutex_unlock(&ctx->flying_transfers_lock);
793 if (transfer_priv == NULL) {
794 usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd);
795 r = LIBUSB_ERROR_NOT_FOUND;
799 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
801 if (GetOverlappedResult(transfer_priv->handle, transfer_priv->pollable_fd.overlapped, &bytes_transferred, FALSE))
804 result = GetLastError();
806 windows_transfer_callback(priv->backend, itransfer, result, bytes_transferred);
808 usbi_mutex_unlock(&ctx->open_devs_lock);
813 static int windows_clock_gettime(int clk_id, struct timespec *tp)
815 LARGE_INTEGER hires_counter;
816 #if !defined(_MSC_VER) || (_MSC_VER < 1900)
818 ULARGE_INTEGER rtime;
822 case USBI_CLOCK_MONOTONIC:
823 if (hires_frequency) {
824 QueryPerformanceCounter(&hires_counter);
825 tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
826 tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) * hires_ticks_to_ps) / UINT64_C(1000));
827 return LIBUSB_SUCCESS;
829 // Fall through and return real-time if monotonic was not detected @ timer init
830 case USBI_CLOCK_REALTIME:
831 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
832 if (!timespec_get(tp, TIME_UTC))
833 return LIBUSB_ERROR_OTHER;
835 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
836 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
837 // Note however that our resolution is bounded by the Windows system time
838 // functions and is at best of the order of 1 ms (or, usually, worse)
839 GetSystemTimeAsFileTime(&filetime);
840 rtime.LowPart = filetime.dwLowDateTime;
841 rtime.HighPart = filetime.dwHighDateTime;
842 rtime.QuadPart -= EPOCH_TIME;
843 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
844 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
846 return LIBUSB_SUCCESS;
848 return LIBUSB_ERROR_INVALID_PARAM;
852 // NB: MSVC6 does not support named initializers.
853 const struct usbi_os_backend usbi_backend = {
855 USBI_CAP_HAS_HID_ACCESS,
859 windows_get_device_list,
860 NULL, /* hotplug_poll */
861 NULL, /* wrap_sys_device */
864 windows_get_device_descriptor,
865 windows_get_active_config_descriptor,
866 windows_get_config_descriptor,
867 windows_get_config_descriptor_by_value,
868 windows_get_configuration,
869 windows_set_configuration,
870 windows_claim_interface,
871 windows_release_interface,
872 windows_set_interface_altsetting,
874 windows_reset_device,
875 NULL, /* alloc_streams */
876 NULL, /* free_streams */
877 NULL, /* dev_mem_alloc */
878 NULL, /* dev_mem_free */
879 NULL, /* kernel_driver_active */
880 NULL, /* detach_kernel_driver */
881 NULL, /* attach_kernel_driver */
882 windows_destroy_device,
883 windows_submit_transfer,
884 windows_cancel_transfer,
885 NULL, /* clear_transfer_priv */
886 windows_handle_events,
887 NULL, /* handle_transfer_completion */
888 windows_clock_gettime,
889 sizeof(struct windows_context_priv),
890 sizeof(union windows_device_priv),
891 sizeof(union windows_device_handle_priv),
892 sizeof(struct windows_transfer_priv),