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
37 enum windows_version windows_version = WINDOWS_UNDEFINED;
39 // Global variables for init/exit
40 static unsigned int init_count = 0;
41 static bool usbdk_available = false;
43 // Global variables for clock_gettime mechanism
44 static uint64_t hires_ticks_to_ps;
45 static uint64_t hires_frequency;
47 #define TIMER_REQUEST_RETRY_MS 100
48 #define WM_TIMER_REQUEST (WM_USER + 1)
49 #define WM_TIMER_EXIT (WM_USER + 2)
51 // used for monotonic clock_gettime()
52 struct timer_request {
58 static HANDLE timer_thread = NULL;
59 static DWORD timer_thread_id = 0;
61 /* User32 dependencies */
62 DLL_DECLARE_HANDLE(User32);
63 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
64 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
65 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM));
67 static unsigned __stdcall windows_clock_gettime_threaded(void *param);
70 * Converts a windows error to human readable string
71 * uses retval as errorcode, or, if 0, use GetLastError()
73 #if defined(ENABLE_LOGGING)
74 const char *windows_error_str(DWORD error_code)
76 static char err_string[256];
82 error_code = GetLastError();
84 len = sprintf(err_string, "[%lu] ", error_code);
86 // Translate codes returned by SetupAPI. The ones we are dealing with are either
87 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
88 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
89 switch (error_code & 0xE0000000) {
91 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
94 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
100 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
101 NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
102 &err_string[len], sizeof(err_string) - len, NULL);
104 DWORD format_error = GetLastError();
106 snprintf(err_string, sizeof(err_string),
107 "Windows error code %lu (FormatMessage error code %lu)",
108 error_code, format_error);
110 snprintf(err_string, sizeof(err_string), "Unknown error code %lu", error_code);
112 // Remove CRLF from end of message, if present
113 size_t pos = len + size - 2;
114 if (err_string[pos] == '\r')
115 err_string[pos] = '\0';
122 static inline struct windows_context_priv *_context_priv(struct libusb_context *ctx)
124 return (struct windows_context_priv *)ctx->os_priv;
127 /* Hash table functions - modified From glibc 2.3.2:
128 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
129 [Knuth] The Art of Computer Programming, part 3 (6.4) */
131 #define HTAB_SIZE 1021UL // *MUST* be a prime number!!
133 typedef struct htab_entry {
138 static htab_entry *htab_table = NULL;
139 static usbi_mutex_t htab_mutex;
140 static unsigned long htab_filled;
142 /* Before using the hash table we must allocate memory for it.
143 We allocate one element more as the found prime number says.
144 This is done for more effective indexing as explained in the
145 comment for the hash function. */
146 static bool htab_create(struct libusb_context *ctx)
148 if (htab_table != NULL) {
149 usbi_err(ctx, "hash table already allocated");
154 usbi_mutex_init(&htab_mutex);
156 usbi_dbg("using %lu entries hash table", HTAB_SIZE);
159 // allocate memory and zero out.
160 htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
161 if (htab_table == NULL) {
162 usbi_err(ctx, "could not allocate space for hash table");
169 /* After using the hash table it has to be destroyed. */
170 static void htab_destroy(void)
174 if (htab_table == NULL)
177 for (i = 0; i < HTAB_SIZE; i++)
178 free(htab_table[i].str);
180 safe_free(htab_table);
182 usbi_mutex_destroy(&htab_mutex);
185 /* This is the search function. It uses double hashing with open addressing.
186 We use a trick to speed up the lookup. The table is created with one
187 more element available. This enables us to use the index zero special.
188 This index will never be used because we store the first hash index in
189 the field used where zero means not used. Every other value means used.
190 The used field can be used as a first fast comparison for equality of
191 the stored and the parameter value. This helps to prevent unnecessary
192 expensive calls of strcmp. */
193 unsigned long htab_hash(const char *str)
195 unsigned long hval, hval2;
197 unsigned long r = 5381;
199 const char *sz = str;
204 // Compute main hash value (algorithm suggested by Nokia)
205 while ((c = *sz++) != 0)
206 r = ((r << 5) + r) + c;
210 // compute table hash: simply take the modulus
211 hval = r % HTAB_SIZE;
215 // Try the first index
218 // Mutually exclusive access (R/W lock would be better)
219 usbi_mutex_lock(&htab_mutex);
221 if (htab_table[idx].used) {
222 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
223 goto out_unlock; // existing hash
225 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
227 // Second hash function, as suggested in [Knuth]
228 hval2 = 1 + hval % (HTAB_SIZE - 2);
231 // Because size is prime this guarantees to step through all available indexes
233 idx = HTAB_SIZE + idx - hval2;
237 // If we visited all entries leave the loop unsuccessfully
241 // If entry is found use it.
242 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
244 } while (htab_table[idx].used);
247 // Not found => New entry
249 // If the table is full return an error
250 if (htab_filled >= HTAB_SIZE) {
251 usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
256 htab_table[idx].str = _strdup(str);
257 if (htab_table[idx].str == NULL) {
258 usbi_err(NULL, "could not duplicate string for hash table");
263 htab_table[idx].used = hval;
267 usbi_mutex_unlock(&htab_mutex);
273 * Make a transfer complete synchronously
275 void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
277 overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
278 overlapped->InternalHigh = size;
279 SetEvent(overlapped->hEvent);
282 static BOOL windows_init_dlls(void)
284 DLL_GET_HANDLE(User32);
285 DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE);
286 DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
287 DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
292 static void windows_exit_dlls(void)
294 DLL_FREE_HANDLE(User32);
297 static bool windows_init_clock(struct libusb_context *ctx)
299 DWORD_PTR affinity, dummy;
301 LARGE_INTEGER li_frequency;
304 if (QueryPerformanceFrequency(&li_frequency)) {
305 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
306 // to picoseconds to compute the tv_nsecs part in clock_gettime
307 hires_frequency = li_frequency.QuadPart;
308 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
309 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
311 // Because QueryPerformanceCounter might report different values when
312 // running on different cores, we create a separate thread for the timer
313 // calls, which we glue to the first available core always to prevent timing discrepancies.
314 if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) {
315 usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0));
319 // The process affinity mask is a bitmask where each set bit represents a core on
320 // which this process is allowed to run, so we find the first set bit
321 for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++);
322 affinity = (DWORD_PTR)(1 << i);
324 usbi_dbg("timer thread will run on core #%d", i);
326 event = CreateEvent(NULL, FALSE, FALSE, NULL);
328 usbi_err(ctx, "could not create event: %s", windows_error_str(0));
332 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event,
333 0, (unsigned int *)&timer_thread_id);
334 if (timer_thread == NULL) {
335 usbi_err(ctx, "unable to create timer thread - aborting");
340 if (!SetThreadAffinityMask(timer_thread, affinity))
341 usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise");
343 // Wait for timer thread to init before continuing.
344 if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
345 usbi_err(ctx, "failed to wait for timer thread to become ready - aborting");
352 usbi_dbg("no hires timer available on this platform");
354 hires_ticks_to_ps = UINT64_C(0);
360 static void windows_destroy_clock(void)
363 // actually the signal to quit the thread.
364 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0)
365 || (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
366 usbi_dbg("could not wait for timer thread to quit");
367 TerminateThread(timer_thread, 1);
368 // shouldn't happen, but we're destroying
369 // all objects it might have held anyway.
371 CloseHandle(timer_thread);
377 /* Windows version detection */
378 static BOOL is_x64(void)
382 // Detect if we're running a 32 or 64 bit system
383 if (sizeof(uintptr_t) < 8) {
384 IsWow64Process(GetCurrentProcess(), &ret);
392 static void get_windows_version(void)
394 OSVERSIONINFOEXA vi, vi2;
395 const char *arch, *w = NULL;
396 unsigned major, minor, version;
397 ULONGLONG major_equal, minor_equal;
400 windows_version = WINDOWS_UNDEFINED;
402 memset(&vi, 0, sizeof(vi));
403 vi.dwOSVersionInfoSize = sizeof(vi);
404 if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
405 memset(&vi, 0, sizeof(vi));
406 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
407 if (!GetVersionExA((OSVERSIONINFOA *)&vi))
411 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
414 if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
415 // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
416 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
418 major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
419 for (major = vi.dwMajorVersion; major <= 9; major++) {
420 memset(&vi2, 0, sizeof(vi2));
421 vi2.dwOSVersionInfoSize = sizeof(vi2);
422 vi2.dwMajorVersion = major;
423 if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
426 if (vi.dwMajorVersion < major) {
427 vi.dwMajorVersion = major;
428 vi.dwMinorVersion = 0;
431 minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
432 for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
433 memset(&vi2, 0, sizeof(vi2));
434 vi2.dwOSVersionInfoSize = sizeof(vi2);
435 vi2.dwMinorVersion = minor;
436 if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
439 vi.dwMinorVersion = minor;
447 if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
450 ws = (vi.wProductType <= VER_NT_WORKSTATION);
451 version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
453 case 0x50: windows_version = WINDOWS_2000; w = "2000"; break;
454 case 0x51: windows_version = WINDOWS_XP; w = "XP"; break;
455 case 0x52: windows_version = WINDOWS_2003; w = "2003"; break;
456 case 0x60: windows_version = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break;
457 case 0x61: windows_version = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break;
458 case 0x62: windows_version = WINDOWS_8; w = (ws ? "8" : "2012"); break;
459 case 0x63: windows_version = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break;
460 case 0x64: // Early Windows 10 Insider Previews and Windows Server 2017 Technical Preview 1 used version 6.4
461 case 0xA0: windows_version = WINDOWS_10; w = (ws ? "10" : "2016"); break;
463 if (version < 0x50) {
466 windows_version = WINDOWS_11_OR_LATER;
471 arch = is_x64() ? "64-bit" : "32-bit";
473 if (vi.wServicePackMinor)
474 usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
475 else if (vi.wServicePackMajor)
476 usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
478 usbi_dbg("Windows %s %s", w, arch);
482 * Monotonic and real time functions
484 static unsigned __stdcall windows_clock_gettime_threaded(void *param)
486 struct timer_request *request;
487 LARGE_INTEGER hires_counter;
490 // The following call will create this thread's message queue
491 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx
492 pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
494 // Signal windows_init_clock() that we're ready to service requests
495 if (!SetEvent((HANDLE)param))
496 usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0));
499 // Main loop - wait for requests
501 if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) {
502 usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0));
506 switch (msg.message) {
507 case WM_TIMER_REQUEST:
508 // Requests to this thread are for hires always
509 // Microsoft says that this function always succeeds on XP and later
510 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx
511 request = (struct timer_request *)msg.lParam;
512 QueryPerformanceCounter(&hires_counter);
513 request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
514 request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
515 if (!SetEvent(request->event))
516 usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0));
519 usbi_dbg("timer thread quitting");
525 static void windows_transfer_callback(const struct windows_backend *backend,
526 struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
530 usbi_dbg("handling I/O completion with errcode %lu, size %lu", io_result, io_size);
534 status = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
536 case ERROR_GEN_FAILURE:
537 usbi_dbg("detected endpoint stall");
538 status = LIBUSB_TRANSFER_STALL;
540 case ERROR_SEM_TIMEOUT:
541 usbi_dbg("detected semaphore timeout");
542 status = LIBUSB_TRANSFER_TIMED_OUT;
544 case ERROR_OPERATION_ABORTED:
545 istatus = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
546 if (istatus != LIBUSB_TRANSFER_COMPLETED)
547 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
549 usbi_dbg("detected operation aborted");
550 status = LIBUSB_TRANSFER_CANCELLED;
552 case ERROR_FILE_NOT_FOUND:
553 case ERROR_DEVICE_NOT_CONNECTED:
554 usbi_dbg("detected device removed");
555 status = LIBUSB_TRANSFER_NO_DEVICE;
558 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %lu: %s", io_result, windows_error_str(io_result));
559 status = LIBUSB_TRANSFER_ERROR;
562 backend->clear_transfer_priv(itransfer); // Cancel polling
563 if (status == LIBUSB_TRANSFER_CANCELLED)
564 usbi_handle_transfer_cancellation(itransfer);
566 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
569 static void windows_handle_callback(const struct windows_backend *backend,
570 struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
572 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
574 switch (transfer->type) {
575 case LIBUSB_TRANSFER_TYPE_CONTROL:
576 case LIBUSB_TRANSFER_TYPE_BULK:
577 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
578 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
579 windows_transfer_callback(backend, itransfer, io_result, io_size);
581 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
582 usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
585 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
589 static int windows_init(struct libusb_context *ctx)
591 struct windows_context_priv *priv = _context_priv(ctx);
593 char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
594 int r = LIBUSB_ERROR_OTHER;
595 bool winusb_backend_init = false;
597 sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
598 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
599 if (semaphore == NULL) {
600 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
601 return LIBUSB_ERROR_NO_MEM;
604 // A successful wait brings our semaphore count to 0 (unsignaled)
605 // => any concurent wait stalls until the semaphore's release
606 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
607 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
608 CloseHandle(semaphore);
609 return LIBUSB_ERROR_NO_MEM;
612 // NB: concurrent usage supposes that init calls are equally balanced with
613 // exit calls. If init is called more than exit, we will not exit properly
614 if (++init_count == 1) { // First init?
616 if (!windows_init_dlls()) {
617 usbi_err(ctx, "could not resolve DLL functions");
621 get_windows_version();
623 if (windows_version == WINDOWS_UNDEFINED) {
624 usbi_err(ctx, "failed to detect Windows version");
625 r = LIBUSB_ERROR_NOT_SUPPORTED;
629 if (!windows_init_clock(ctx))
632 if (!htab_create(ctx))
635 r = winusb_backend.init(ctx);
636 if (r != LIBUSB_SUCCESS)
638 winusb_backend_init = true;
640 r = usbdk_backend.init(ctx);
641 if (r == LIBUSB_SUCCESS) {
642 usbi_dbg("UsbDk backend is available");
643 usbdk_available = true;
645 usbi_info(ctx, "UsbDk backend is not available");
646 // Do not report this as an error
651 // By default, new contexts will use the WinUSB backend
652 priv->backend = &winusb_backend;
656 init_exit: // Holds semaphore here
657 if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
658 if (winusb_backend_init)
659 winusb_backend.exit(ctx);
661 windows_destroy_clock();
666 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
667 CloseHandle(semaphore);
671 static void windows_exit(struct libusb_context *ctx)
674 char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
677 sprintf(sem_name, "libusb_init%08lX", (GetCurrentProcessId() & 0xFFFFFFFFUL));
678 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
679 if (semaphore == NULL)
682 // A successful wait brings our semaphore count to 0 (unsignaled)
683 // => any concurent wait stalls until the semaphore release
684 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
685 CloseHandle(semaphore);
689 // Only works if exits and inits are balanced exactly
690 if (--init_count == 0) { // Last exit
691 if (usbdk_available) {
692 usbdk_backend.exit(ctx);
693 usbdk_available = false;
695 winusb_backend.exit(ctx);
697 windows_destroy_clock();
701 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
702 CloseHandle(semaphore);
705 static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
707 struct windows_context_priv *priv = _context_priv(ctx);
712 case LIBUSB_OPTION_USE_USBDK:
713 if (usbdk_available) {
714 usbi_dbg("switching context %p to use UsbDk backend", ctx);
715 priv->backend = &usbdk_backend;
717 usbi_err(ctx, "UsbDk backend not available");
718 return LIBUSB_ERROR_NOT_FOUND;
720 return LIBUSB_SUCCESS;
722 return LIBUSB_ERROR_NOT_SUPPORTED;
727 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
729 struct windows_context_priv *priv = _context_priv(ctx);
730 return priv->backend->get_device_list(ctx, discdevs);
733 static int windows_open(struct libusb_device_handle *dev_handle)
735 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
736 return priv->backend->open(dev_handle);
739 static void windows_close(struct libusb_device_handle *dev_handle)
741 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
742 priv->backend->close(dev_handle);
745 static int windows_get_device_descriptor(struct libusb_device *dev,
746 unsigned char *buffer, int *host_endian)
748 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
750 return priv->backend->get_device_descriptor(dev, buffer);
753 static int windows_get_active_config_descriptor(struct libusb_device *dev,
754 unsigned char *buffer, size_t len, int *host_endian)
756 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
758 return priv->backend->get_active_config_descriptor(dev, buffer, len);
761 static int windows_get_config_descriptor(struct libusb_device *dev,
762 uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
764 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
766 return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
769 static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
770 uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian)
772 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
774 return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
777 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
779 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
780 return priv->backend->get_configuration(dev_handle, config);
783 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
785 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
786 return priv->backend->set_configuration(dev_handle, config);
789 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
791 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
792 return priv->backend->claim_interface(dev_handle, interface_number);
795 static int windows_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
797 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
798 return priv->backend->release_interface(dev_handle, interface_number);
801 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
802 int interface_number, int altsetting)
804 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
805 return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
808 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
810 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
811 return priv->backend->clear_halt(dev_handle, endpoint);
814 static int windows_reset_device(struct libusb_device_handle *dev_handle)
816 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
817 return priv->backend->reset_device(dev_handle);
820 static void windows_destroy_device(struct libusb_device *dev)
822 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
823 priv->backend->destroy_device(dev);
826 static int windows_submit_transfer(struct usbi_transfer *itransfer)
828 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
829 return priv->backend->submit_transfer(itransfer);
832 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
834 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
835 return priv->backend->cancel_transfer(itransfer);
838 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
840 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
841 priv->backend->clear_transfer_priv(itransfer);
844 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
846 struct windows_context_priv *priv = _context_priv(ctx);
847 struct usbi_transfer *itransfer;
848 DWORD io_size, io_result;
852 int r = LIBUSB_SUCCESS;
854 usbi_mutex_lock(&ctx->open_devs_lock);
855 for (i = 0; i < nfds && num_ready > 0; i++) {
857 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
864 // Because a Windows OVERLAPPED is used for poll emulation,
865 // a pollable fd is created and stored with each transfer
868 usbi_mutex_lock(&ctx->flying_transfers_lock);
869 list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
870 transfer_fd = priv->backend->get_transfer_fd(itransfer);
871 if (transfer_fd == fds[i].fd) {
876 usbi_mutex_unlock(&ctx->flying_transfers_lock);
879 priv->backend->get_overlapped_result(itransfer, &io_result, &io_size);
881 usbi_remove_pollfd(ctx, transfer_fd);
883 // let handle_callback free the event using the transfer wfd
884 // If you don't use the transfer wfd, you run a risk of trying to free a
885 // newly allocated wfd that took the place of the one from the transfer.
886 windows_handle_callback(priv->backend, itransfer, io_result, io_size);
888 usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd);
889 r = LIBUSB_ERROR_NOT_FOUND;
893 usbi_mutex_unlock(&ctx->open_devs_lock);
898 static int windows_clock_gettime(int clk_id, struct timespec *tp)
900 struct timer_request request;
901 #if !defined(_MSC_VER) || (_MSC_VER < 1900)
903 ULARGE_INTEGER rtime;
908 case USBI_CLOCK_MONOTONIC:
911 request.event = CreateEvent(NULL, FALSE, FALSE, NULL);
912 if (request.event == NULL)
913 return LIBUSB_ERROR_NO_MEM;
915 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) {
916 usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0));
917 CloseHandle(request.event);
918 return LIBUSB_ERROR_OTHER;
922 r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS);
923 if (r == WAIT_TIMEOUT)
924 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
925 else if (r == WAIT_FAILED)
926 usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0));
927 } while (r == WAIT_TIMEOUT);
928 CloseHandle(request.event);
930 if (r == WAIT_OBJECT_0)
931 return LIBUSB_SUCCESS;
933 return LIBUSB_ERROR_OTHER;
935 // Fall through and return real-time if monotonic was not detected @ timer init
936 case USBI_CLOCK_REALTIME:
937 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
938 timespec_get(tp, TIME_UTC);
940 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
941 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
942 // Note however that our resolution is bounded by the Windows system time
943 // functions and is at best of the order of 1 ms (or, usually, worse)
944 GetSystemTimeAsFileTime(&filetime);
945 rtime.LowPart = filetime.dwLowDateTime;
946 rtime.HighPart = filetime.dwHighDateTime;
947 rtime.QuadPart -= EPOCH_TIME;
948 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
949 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
951 return LIBUSB_SUCCESS;
953 return LIBUSB_ERROR_INVALID_PARAM;
957 // NB: MSVC6 does not support named initializers.
958 const struct usbi_os_backend usbi_backend = {
960 USBI_CAP_HAS_HID_ACCESS,
964 windows_get_device_list,
965 NULL, /* hotplug_poll */
966 NULL, /* wrap_sys_device */
969 windows_get_device_descriptor,
970 windows_get_active_config_descriptor,
971 windows_get_config_descriptor,
972 windows_get_config_descriptor_by_value,
973 windows_get_configuration,
974 windows_set_configuration,
975 windows_claim_interface,
976 windows_release_interface,
977 windows_set_interface_altsetting,
979 windows_reset_device,
980 NULL, /* alloc_streams */
981 NULL, /* free_streams */
982 NULL, /* dev_mem_alloc */
983 NULL, /* dev_mem_free */
984 NULL, /* kernel_driver_active */
985 NULL, /* detach_kernel_driver */
986 NULL, /* attach_kernel_driver */
987 windows_destroy_device,
988 windows_submit_transfer,
989 windows_cancel_transfer,
990 windows_clear_transfer_priv,
991 windows_handle_events,
992 NULL, /* handle_transfer_completion */
993 windows_clock_gettime,
994 sizeof(struct windows_context_priv),
995 sizeof(union windows_device_priv),
996 sizeof(union windows_device_handle_priv),
997 sizeof(union windows_transfer_priv),