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"
33 #include "windows_nt_common.h"
36 BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED);
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 /* Kernel32 dependencies */
62 DLL_DECLARE_HANDLE(Kernel32);
63 /* This call is only available from XP SP2 */
64 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
66 /* User32 dependencies */
67 DLL_DECLARE_HANDLE(User32);
68 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
69 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
70 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM));
72 static unsigned __stdcall windows_clock_gettime_threaded(void *param);
75 * Converts a windows error to human readable string
76 * uses retval as errorcode, or, if 0, use GetLastError()
78 #if defined(ENABLE_LOGGING)
79 const char *windows_error_str(DWORD error_code)
81 static char err_string[ERR_BUFFER_SIZE];
87 error_code = GetLastError();
89 len = sprintf(err_string, "[%u] ", (unsigned int)error_code);
91 // Translate codes returned by SetupAPI. The ones we are dealing with are either
92 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
93 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
94 switch (error_code & 0xE0000000) {
96 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
99 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
105 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
106 NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
107 &err_string[len], ERR_BUFFER_SIZE - len, NULL);
109 DWORD format_error = GetLastError();
111 snprintf(err_string, ERR_BUFFER_SIZE,
112 "Windows error code %u (FormatMessage error code %u)",
113 (unsigned int)error_code, (unsigned int)format_error);
115 snprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code);
117 // Remove CRLF from end of message, if present
118 size_t pos = len + size - 2;
119 if (err_string[pos] == '\r')
120 err_string[pos] = '\0';
127 static inline struct windows_context_priv *_context_priv(struct libusb_context *ctx)
129 return (struct windows_context_priv *)ctx->os_priv;
132 /* Hash table functions - modified From glibc 2.3.2:
133 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
134 [Knuth] The Art of Computer Programming, part 3 (6.4) */
136 #define HTAB_SIZE 1021UL // *MUST* be a prime number!!
138 typedef struct htab_entry {
143 static htab_entry *htab_table = NULL;
144 static usbi_mutex_t htab_mutex;
145 static unsigned long htab_filled;
147 /* Before using the hash table we must allocate memory for it.
148 We allocate one element more as the found prime number says.
149 This is done for more effective indexing as explained in the
150 comment for the hash function. */
151 static bool htab_create(struct libusb_context *ctx)
153 if (htab_table != NULL) {
154 usbi_err(ctx, "hash table already allocated");
159 usbi_mutex_init(&htab_mutex);
161 usbi_dbg("using %lu entries hash table", HTAB_SIZE);
164 // allocate memory and zero out.
165 htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
166 if (htab_table == NULL) {
167 usbi_err(ctx, "could not allocate space for hash table");
174 /* After using the hash table it has to be destroyed. */
175 static void htab_destroy(void)
179 if (htab_table == NULL)
182 for (i = 0; i < HTAB_SIZE; i++)
183 free(htab_table[i].str);
185 safe_free(htab_table);
187 usbi_mutex_destroy(&htab_mutex);
190 /* This is the search function. It uses double hashing with open addressing.
191 We use a trick to speed up the lookup. The table is created with one
192 more element available. This enables us to use the index zero special.
193 This index will never be used because we store the first hash index in
194 the field used where zero means not used. Every other value means used.
195 The used field can be used as a first fast comparison for equality of
196 the stored and the parameter value. This helps to prevent unnecessary
197 expensive calls of strcmp. */
198 unsigned long htab_hash(const char *str)
200 unsigned long hval, hval2;
202 unsigned long r = 5381;
204 const char *sz = str;
209 // Compute main hash value (algorithm suggested by Nokia)
210 while ((c = *sz++) != 0)
211 r = ((r << 5) + r) + c;
215 // compute table hash: simply take the modulus
216 hval = r % HTAB_SIZE;
220 // Try the first index
223 // Mutually exclusive access (R/W lock would be better)
224 usbi_mutex_lock(&htab_mutex);
226 if (htab_table[idx].used) {
227 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
228 goto out_unlock; // existing hash
230 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
232 // Second hash function, as suggested in [Knuth]
233 hval2 = 1 + hval % (HTAB_SIZE - 2);
236 // Because size is prime this guarantees to step through all available indexes
238 idx = HTAB_SIZE + idx - hval2;
242 // If we visited all entries leave the loop unsuccessfully
246 // If entry is found use it.
247 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
249 } while (htab_table[idx].used);
252 // Not found => New entry
254 // If the table is full return an error
255 if (htab_filled >= HTAB_SIZE) {
256 usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
261 htab_table[idx].str = _strdup(str);
262 if (htab_table[idx].str == NULL) {
263 usbi_err(NULL, "could not duplicate string for hash table");
268 htab_table[idx].used = hval;
272 usbi_mutex_unlock(&htab_mutex);
278 * Make a transfer complete synchronously
280 void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
282 overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
283 overlapped->InternalHigh = size;
284 SetEvent(overlapped->hEvent);
287 static BOOL windows_init_dlls(void)
289 DLL_GET_HANDLE(Kernel32);
290 DLL_LOAD_FUNC_PREFIXED(Kernel32, p, IsWow64Process, FALSE);
291 pCancelIoEx = (BOOL (WINAPI *)(HANDLE, LPOVERLAPPED))
292 GetProcAddress(DLL_HANDLE_NAME(Kernel32), "CancelIoEx");
293 usbi_dbg("Will use CancelIo%s for I/O cancellation", pCancelIoEx ? "Ex" : "");
295 DLL_GET_HANDLE(User32);
296 DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE);
297 DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
298 DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
303 static void windows_exit_dlls(void)
305 DLL_FREE_HANDLE(Kernel32);
306 DLL_FREE_HANDLE(User32);
309 static bool windows_init_clock(struct libusb_context *ctx)
311 DWORD_PTR affinity, dummy;
313 LARGE_INTEGER li_frequency;
316 if (QueryPerformanceFrequency(&li_frequency)) {
317 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
318 // to picoseconds to compute the tv_nsecs part in clock_gettime
319 hires_frequency = li_frequency.QuadPart;
320 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
321 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
323 // Because QueryPerformanceCounter might report different values when
324 // running on different cores, we create a separate thread for the timer
325 // calls, which we glue to the first available core always to prevent timing discrepancies.
326 if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) {
327 usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0));
331 // The process affinity mask is a bitmask where each set bit represents a core on
332 // which this process is allowed to run, so we find the first set bit
333 for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++);
334 affinity = (DWORD_PTR)(1 << i);
336 usbi_dbg("timer thread will run on core #%d", i);
338 event = CreateEvent(NULL, FALSE, FALSE, NULL);
340 usbi_err(ctx, "could not create event: %s", windows_error_str(0));
344 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event,
345 0, (unsigned int *)&timer_thread_id);
346 if (timer_thread == NULL) {
347 usbi_err(ctx, "unable to create timer thread - aborting");
352 if (!SetThreadAffinityMask(timer_thread, affinity))
353 usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise");
355 // Wait for timer thread to init before continuing.
356 if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
357 usbi_err(ctx, "failed to wait for timer thread to become ready - aborting");
364 usbi_dbg("no hires timer available on this platform");
366 hires_ticks_to_ps = UINT64_C(0);
372 static void windows_destroy_clock(void)
375 // actually the signal to quit the thread.
376 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0)
377 || (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
378 usbi_dbg("could not wait for timer thread to quit");
379 TerminateThread(timer_thread, 1);
380 // shouldn't happen, but we're destroying
381 // all objects it might have held anyway.
383 CloseHandle(timer_thread);
389 /* Windows version detection */
390 static BOOL is_x64(void)
394 // Detect if we're running a 32 or 64 bit system
395 if (sizeof(uintptr_t) < 8) {
396 if (pIsWow64Process != NULL)
397 pIsWow64Process(GetCurrentProcess(), &ret);
405 static void get_windows_version(void)
407 OSVERSIONINFOEXA vi, vi2;
408 const char *arch, *w = NULL;
409 unsigned major, minor, version;
410 ULONGLONG major_equal, minor_equal;
413 windows_version = WINDOWS_UNDEFINED;
415 memset(&vi, 0, sizeof(vi));
416 vi.dwOSVersionInfoSize = sizeof(vi);
417 if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
418 memset(&vi, 0, sizeof(vi));
419 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
420 if (!GetVersionExA((OSVERSIONINFOA *)&vi))
424 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
427 if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
428 // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
429 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
431 major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
432 for (major = vi.dwMajorVersion; major <= 9; major++) {
433 memset(&vi2, 0, sizeof(vi2));
434 vi2.dwOSVersionInfoSize = sizeof(vi2);
435 vi2.dwMajorVersion = major;
436 if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
439 if (vi.dwMajorVersion < major) {
440 vi.dwMajorVersion = major;
441 vi.dwMinorVersion = 0;
444 minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
445 for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
446 memset(&vi2, 0, sizeof(vi2));
447 vi2.dwOSVersionInfoSize = sizeof(vi2);
448 vi2.dwMinorVersion = minor;
449 if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
452 vi.dwMinorVersion = minor;
460 if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
463 ws = (vi.wProductType <= VER_NT_WORKSTATION);
464 version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
466 case 0x50: windows_version = WINDOWS_2000; w = "2000"; break;
467 case 0x51: windows_version = WINDOWS_XP; w = "XP"; break;
468 case 0x52: windows_version = WINDOWS_2003; w = "2003"; break;
469 case 0x60: windows_version = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break;
470 case 0x61: windows_version = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break;
471 case 0x62: windows_version = WINDOWS_8; w = (ws ? "8" : "2012"); break;
472 case 0x63: windows_version = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break;
473 case 0x64: windows_version = WINDOWS_10; w = (ws ? "10" : "2016"); break;
475 if (version < 0x50) {
478 windows_version = WINDOWS_11_OR_LATER;
483 arch = is_x64() ? "64-bit" : "32-bit";
485 if (vi.wServicePackMinor)
486 usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
487 else if (vi.wServicePackMajor)
488 usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
490 usbi_dbg("Windows %s %s", w, arch);
494 * Monotonic and real time functions
496 static unsigned __stdcall windows_clock_gettime_threaded(void *param)
498 struct timer_request *request;
499 LARGE_INTEGER hires_counter;
502 // The following call will create this thread's message queue
503 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx
504 pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
506 // Signal windows_init_clock() that we're ready to service requests
507 if (!SetEvent((HANDLE)param))
508 usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0));
511 // Main loop - wait for requests
513 if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) {
514 usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0));
518 switch (msg.message) {
519 case WM_TIMER_REQUEST:
520 // Requests to this thread are for hires always
521 // Microsoft says that this function always succeeds on XP and later
522 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx
523 request = (struct timer_request *)msg.lParam;
524 QueryPerformanceCounter(&hires_counter);
525 request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
526 request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
527 if (!SetEvent(request->event))
528 usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0));
531 usbi_dbg("timer thread quitting");
537 static void windows_transfer_callback(const struct windows_backend *backend,
538 struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
542 usbi_dbg("handling I/O completion with errcode %u, size %u", (unsigned int)io_result, (unsigned int)io_size);
546 status = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
548 case ERROR_GEN_FAILURE:
549 usbi_dbg("detected endpoint stall");
550 status = LIBUSB_TRANSFER_STALL;
552 case ERROR_SEM_TIMEOUT:
553 usbi_dbg("detected semaphore timeout");
554 status = LIBUSB_TRANSFER_TIMED_OUT;
556 case ERROR_OPERATION_ABORTED:
557 istatus = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
558 if (istatus != LIBUSB_TRANSFER_COMPLETED)
559 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
561 usbi_dbg("detected operation aborted");
562 status = LIBUSB_TRANSFER_CANCELLED;
564 case ERROR_FILE_NOT_FOUND:
565 usbi_dbg("detected device removed");
566 status = LIBUSB_TRANSFER_NO_DEVICE;
569 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", (unsigned int)io_result, windows_error_str(io_result));
570 status = LIBUSB_TRANSFER_ERROR;
573 backend->clear_transfer_priv(itransfer); // Cancel polling
574 if (status == LIBUSB_TRANSFER_CANCELLED)
575 usbi_handle_transfer_cancellation(itransfer);
577 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
580 static void windows_handle_callback(const struct windows_backend *backend,
581 struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
583 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
585 switch (transfer->type) {
586 case LIBUSB_TRANSFER_TYPE_CONTROL:
587 case LIBUSB_TRANSFER_TYPE_BULK:
588 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
589 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
590 windows_transfer_callback(backend, itransfer, io_result, io_size);
592 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
593 usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
596 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
600 static int windows_init(struct libusb_context *ctx)
602 struct windows_context_priv *priv = _context_priv(ctx);
604 char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
605 int r = LIBUSB_ERROR_OTHER;
606 bool winusb_backend_init = false;
608 sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
609 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
610 if (semaphore == NULL) {
611 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
612 return LIBUSB_ERROR_NO_MEM;
615 // A successful wait brings our semaphore count to 0 (unsignaled)
616 // => any concurent wait stalls until the semaphore's release
617 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
618 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
619 CloseHandle(semaphore);
620 return LIBUSB_ERROR_NO_MEM;
623 // NB: concurrent usage supposes that init calls are equally balanced with
624 // exit calls. If init is called more than exit, we will not exit properly
625 if (++init_count == 1) { // First init?
627 if (!windows_init_dlls()) {
628 usbi_err(ctx, "could not resolve DLL functions");
632 get_windows_version();
634 if (windows_version == WINDOWS_UNDEFINED) {
635 usbi_err(ctx, "failed to detect Windows version");
636 r = LIBUSB_ERROR_NOT_SUPPORTED;
640 if (!windows_init_clock(ctx))
643 if (!htab_create(ctx))
646 r = winusb_backend.init(ctx);
647 if (r != LIBUSB_SUCCESS)
649 winusb_backend_init = true;
651 r = usbdk_backend.init(ctx);
652 if (r == LIBUSB_SUCCESS) {
653 usbi_dbg("UsbDk backend is available");
654 usbdk_available = true;
656 usbi_info(ctx, "UsbDk backend is not available");
657 // Do not report this as an error
662 // By default, new contexts will use the WinUSB backend
663 priv->backend = &winusb_backend;
667 init_exit: // Holds semaphore here
668 if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
669 if (winusb_backend_init)
670 winusb_backend.exit(ctx);
672 windows_destroy_clock();
677 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
678 CloseHandle(semaphore);
682 static void windows_exit(struct libusb_context *ctx)
685 char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
688 sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
689 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
690 if (semaphore == NULL)
693 // A successful wait brings our semaphore count to 0 (unsignaled)
694 // => any concurent wait stalls until the semaphore release
695 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
696 CloseHandle(semaphore);
700 // Only works if exits and inits are balanced exactly
701 if (--init_count == 0) { // Last exit
702 if (usbdk_available) {
703 usbdk_backend.exit(ctx);
704 usbdk_available = false;
706 winusb_backend.exit(ctx);
708 windows_destroy_clock();
712 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
713 CloseHandle(semaphore);
716 static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
718 struct windows_context_priv *priv = _context_priv(ctx);
723 case LIBUSB_OPTION_USE_USBDK:
724 if (usbdk_available) {
725 usbi_dbg("switching context %p to use UsbDk backend", ctx);
726 priv->backend = &usbdk_backend;
728 usbi_err(ctx, "UsbDk backend not available");
729 return LIBUSB_ERROR_NOT_FOUND;
731 return LIBUSB_SUCCESS;
733 return LIBUSB_ERROR_NOT_SUPPORTED;
738 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
740 struct windows_context_priv *priv = _context_priv(ctx);
741 return priv->backend->get_device_list(ctx, discdevs);
744 static int windows_open(struct libusb_device_handle *dev_handle)
746 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
747 return priv->backend->open(dev_handle);
750 static void windows_close(struct libusb_device_handle *dev_handle)
752 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
753 priv->backend->close(dev_handle);
756 static int windows_get_device_descriptor(struct libusb_device *dev,
757 unsigned char *buffer, int *host_endian)
759 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
761 return priv->backend->get_device_descriptor(dev, buffer);
764 static int windows_get_active_config_descriptor(struct libusb_device *dev,
765 unsigned char *buffer, size_t len, int *host_endian)
767 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
769 return priv->backend->get_active_config_descriptor(dev, buffer, len);
772 static int windows_get_config_descriptor(struct libusb_device *dev,
773 uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
775 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
777 return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
780 static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
781 uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian)
783 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
785 return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
788 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
790 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
791 return priv->backend->get_configuration(dev_handle, config);
794 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
796 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
797 return priv->backend->set_configuration(dev_handle, config);
800 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
802 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
803 return priv->backend->claim_interface(dev_handle, interface_number);
806 static int windows_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
808 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
809 return priv->backend->release_interface(dev_handle, interface_number);
812 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
813 int interface_number, int altsetting)
815 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
816 return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
819 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
821 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
822 return priv->backend->clear_halt(dev_handle, endpoint);
825 static int windows_reset_device(struct libusb_device_handle *dev_handle)
827 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
828 return priv->backend->reset_device(dev_handle);
831 static void windows_destroy_device(struct libusb_device *dev)
833 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
834 priv->backend->destroy_device(dev);
837 static int windows_submit_transfer(struct usbi_transfer *itransfer)
839 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
840 return priv->backend->submit_transfer(itransfer);
843 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
845 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
846 return priv->backend->cancel_transfer(itransfer);
849 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
851 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
852 priv->backend->clear_transfer_priv(itransfer);
855 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
857 struct windows_context_priv *priv = _context_priv(ctx);
858 struct usbi_transfer *itransfer;
859 DWORD io_size, io_result;
863 int r = LIBUSB_SUCCESS;
865 usbi_mutex_lock(&ctx->open_devs_lock);
866 for (i = 0; i < nfds && num_ready > 0; i++) {
868 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
875 // Because a Windows OVERLAPPED is used for poll emulation,
876 // a pollable fd is created and stored with each transfer
879 usbi_mutex_lock(&ctx->flying_transfers_lock);
880 list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
881 transfer_fd = priv->backend->get_transfer_fd(itransfer);
882 if (transfer_fd == fds[i].fd) {
887 usbi_mutex_unlock(&ctx->flying_transfers_lock);
890 priv->backend->get_overlapped_result(itransfer, &io_result, &io_size);
892 usbi_remove_pollfd(ctx, transfer_fd);
894 // let handle_callback free the event using the transfer wfd
895 // If you don't use the transfer wfd, you run a risk of trying to free a
896 // newly allocated wfd that took the place of the one from the transfer.
897 windows_handle_callback(priv->backend, itransfer, io_result, io_size);
899 usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd);
900 r = LIBUSB_ERROR_NOT_FOUND;
904 usbi_mutex_unlock(&ctx->open_devs_lock);
909 static int windows_clock_gettime(int clk_id, struct timespec *tp)
911 struct timer_request request;
912 #if !defined(_MSC_VER) || (_MSC_VER < 1900)
914 ULARGE_INTEGER rtime;
919 case USBI_CLOCK_MONOTONIC:
922 request.event = CreateEvent(NULL, FALSE, FALSE, NULL);
923 if (request.event == NULL)
924 return LIBUSB_ERROR_NO_MEM;
926 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) {
927 usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0));
928 CloseHandle(request.event);
929 return LIBUSB_ERROR_OTHER;
933 r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS);
934 if (r == WAIT_TIMEOUT)
935 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
936 else if (r == WAIT_FAILED)
937 usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0));
938 } while (r == WAIT_TIMEOUT);
939 CloseHandle(request.event);
941 if (r == WAIT_OBJECT_0)
942 return LIBUSB_SUCCESS;
944 return LIBUSB_ERROR_OTHER;
946 // Fall through and return real-time if monotonic was not detected @ timer init
947 case USBI_CLOCK_REALTIME:
948 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
949 timespec_get(tp, TIME_UTC);
951 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
952 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
953 // Note however that our resolution is bounded by the Windows system time
954 // functions and is at best of the order of 1 ms (or, usually, worse)
955 GetSystemTimeAsFileTime(&filetime);
956 rtime.LowPart = filetime.dwLowDateTime;
957 rtime.HighPart = filetime.dwHighDateTime;
958 rtime.QuadPart -= EPOCH_TIME;
959 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
960 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
962 return LIBUSB_SUCCESS;
964 return LIBUSB_ERROR_INVALID_PARAM;
968 // NB: MSVC6 does not support named initializers.
969 const struct usbi_os_backend usbi_backend = {
971 USBI_CAP_HAS_HID_ACCESS,
975 windows_get_device_list,
976 NULL, /* hotplug_poll */
979 windows_get_device_descriptor,
980 windows_get_active_config_descriptor,
981 windows_get_config_descriptor,
982 windows_get_config_descriptor_by_value,
983 windows_get_configuration,
984 windows_set_configuration,
985 windows_claim_interface,
986 windows_release_interface,
987 windows_set_interface_altsetting,
989 windows_reset_device,
990 NULL, /* alloc_streams */
991 NULL, /* free_streams */
992 NULL, /* dev_mem_alloc */
993 NULL, /* dev_mem_free */
994 NULL, /* kernel_driver_active */
995 NULL, /* detach_kernel_driver */
996 NULL, /* attach_kernel_driver */
997 windows_destroy_device,
998 windows_submit_transfer,
999 windows_cancel_transfer,
1000 windows_clear_transfer_priv,
1001 windows_handle_events,
1002 NULL, /* handle_transfer_completion */
1003 windows_clock_gettime,
1004 sizeof(struct windows_context_priv),
1005 sizeof(union windows_device_priv),
1006 sizeof(union windows_device_handle_priv),
1007 sizeof(union windows_transfer_priv),