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 BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED);
38 enum windows_version windows_version = WINDOWS_UNDEFINED;
40 // Global variables for init/exit
41 static unsigned int init_count = 0;
42 static bool usbdk_available = false;
44 // Global variables for clock_gettime mechanism
45 static uint64_t hires_ticks_to_ps;
46 static uint64_t hires_frequency;
48 #define TIMER_REQUEST_RETRY_MS 100
49 #define WM_TIMER_REQUEST (WM_USER + 1)
50 #define WM_TIMER_EXIT (WM_USER + 2)
52 // used for monotonic clock_gettime()
53 struct timer_request {
59 static HANDLE timer_thread = NULL;
60 static DWORD timer_thread_id = 0;
62 /* Kernel32 dependencies */
63 DLL_DECLARE_HANDLE(Kernel32);
64 /* This call is only available from XP SP2 */
65 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
67 /* User32 dependencies */
68 DLL_DECLARE_HANDLE(User32);
69 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
70 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
71 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM));
73 static unsigned __stdcall windows_clock_gettime_threaded(void *param);
76 * Converts a windows error to human readable string
77 * uses retval as errorcode, or, if 0, use GetLastError()
79 #if defined(ENABLE_LOGGING)
80 const char *windows_error_str(DWORD error_code)
82 static char err_string[256];
88 error_code = GetLastError();
90 len = sprintf(err_string, "[%u] ", (unsigned int)error_code);
92 // Translate codes returned by SetupAPI. The ones we are dealing with are either
93 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
94 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
95 switch (error_code & 0xE0000000) {
97 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
100 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
106 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
107 NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
108 &err_string[len], sizeof(err_string) - len, NULL);
110 DWORD format_error = GetLastError();
112 snprintf(err_string, sizeof(err_string),
113 "Windows error code %u (FormatMessage error code %u)",
114 (unsigned int)error_code, (unsigned int)format_error);
116 snprintf(err_string, sizeof(err_string), "Unknown error code %u", (unsigned int)error_code);
118 // Remove CRLF from end of message, if present
119 size_t pos = len + size - 2;
120 if (err_string[pos] == '\r')
121 err_string[pos] = '\0';
128 static inline struct windows_context_priv *_context_priv(struct libusb_context *ctx)
130 return (struct windows_context_priv *)ctx->os_priv;
133 /* Hash table functions - modified From glibc 2.3.2:
134 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
135 [Knuth] The Art of Computer Programming, part 3 (6.4) */
137 #define HTAB_SIZE 1021UL // *MUST* be a prime number!!
139 typedef struct htab_entry {
144 static htab_entry *htab_table = NULL;
145 static usbi_mutex_t htab_mutex;
146 static unsigned long htab_filled;
148 /* Before using the hash table we must allocate memory for it.
149 We allocate one element more as the found prime number says.
150 This is done for more effective indexing as explained in the
151 comment for the hash function. */
152 static bool htab_create(struct libusb_context *ctx)
154 if (htab_table != NULL) {
155 usbi_err(ctx, "hash table already allocated");
160 usbi_mutex_init(&htab_mutex);
162 usbi_dbg("using %lu entries hash table", HTAB_SIZE);
165 // allocate memory and zero out.
166 htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
167 if (htab_table == NULL) {
168 usbi_err(ctx, "could not allocate space for hash table");
175 /* After using the hash table it has to be destroyed. */
176 static void htab_destroy(void)
180 if (htab_table == NULL)
183 for (i = 0; i < HTAB_SIZE; i++)
184 free(htab_table[i].str);
186 safe_free(htab_table);
188 usbi_mutex_destroy(&htab_mutex);
191 /* This is the search function. It uses double hashing with open addressing.
192 We use a trick to speed up the lookup. The table is created with one
193 more element available. This enables us to use the index zero special.
194 This index will never be used because we store the first hash index in
195 the field used where zero means not used. Every other value means used.
196 The used field can be used as a first fast comparison for equality of
197 the stored and the parameter value. This helps to prevent unnecessary
198 expensive calls of strcmp. */
199 unsigned long htab_hash(const char *str)
201 unsigned long hval, hval2;
203 unsigned long r = 5381;
205 const char *sz = str;
210 // Compute main hash value (algorithm suggested by Nokia)
211 while ((c = *sz++) != 0)
212 r = ((r << 5) + r) + c;
216 // compute table hash: simply take the modulus
217 hval = r % HTAB_SIZE;
221 // Try the first index
224 // Mutually exclusive access (R/W lock would be better)
225 usbi_mutex_lock(&htab_mutex);
227 if (htab_table[idx].used) {
228 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
229 goto out_unlock; // existing hash
231 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
233 // Second hash function, as suggested in [Knuth]
234 hval2 = 1 + hval % (HTAB_SIZE - 2);
237 // Because size is prime this guarantees to step through all available indexes
239 idx = HTAB_SIZE + idx - hval2;
243 // If we visited all entries leave the loop unsuccessfully
247 // If entry is found use it.
248 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
250 } while (htab_table[idx].used);
253 // Not found => New entry
255 // If the table is full return an error
256 if (htab_filled >= HTAB_SIZE) {
257 usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
262 htab_table[idx].str = _strdup(str);
263 if (htab_table[idx].str == NULL) {
264 usbi_err(NULL, "could not duplicate string for hash table");
269 htab_table[idx].used = hval;
273 usbi_mutex_unlock(&htab_mutex);
279 * Make a transfer complete synchronously
281 void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
283 overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
284 overlapped->InternalHigh = size;
285 SetEvent(overlapped->hEvent);
288 static BOOL windows_init_dlls(void)
290 DLL_GET_HANDLE(Kernel32);
291 DLL_LOAD_FUNC_PREFIXED(Kernel32, p, IsWow64Process, FALSE);
292 pCancelIoEx = (BOOL (WINAPI *)(HANDLE, LPOVERLAPPED))
293 GetProcAddress(DLL_HANDLE_NAME(Kernel32), "CancelIoEx");
294 usbi_dbg("Will use CancelIo%s for I/O cancellation", pCancelIoEx ? "Ex" : "");
296 DLL_GET_HANDLE(User32);
297 DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE);
298 DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
299 DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
304 static void windows_exit_dlls(void)
306 DLL_FREE_HANDLE(Kernel32);
307 DLL_FREE_HANDLE(User32);
310 static bool windows_init_clock(struct libusb_context *ctx)
312 DWORD_PTR affinity, dummy;
314 LARGE_INTEGER li_frequency;
317 if (QueryPerformanceFrequency(&li_frequency)) {
318 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
319 // to picoseconds to compute the tv_nsecs part in clock_gettime
320 hires_frequency = li_frequency.QuadPart;
321 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
322 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
324 // Because QueryPerformanceCounter might report different values when
325 // running on different cores, we create a separate thread for the timer
326 // calls, which we glue to the first available core always to prevent timing discrepancies.
327 if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) {
328 usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0));
332 // The process affinity mask is a bitmask where each set bit represents a core on
333 // which this process is allowed to run, so we find the first set bit
334 for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++);
335 affinity = (DWORD_PTR)(1 << i);
337 usbi_dbg("timer thread will run on core #%d", i);
339 event = CreateEvent(NULL, FALSE, FALSE, NULL);
341 usbi_err(ctx, "could not create event: %s", windows_error_str(0));
345 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event,
346 0, (unsigned int *)&timer_thread_id);
347 if (timer_thread == NULL) {
348 usbi_err(ctx, "unable to create timer thread - aborting");
353 if (!SetThreadAffinityMask(timer_thread, affinity))
354 usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise");
356 // Wait for timer thread to init before continuing.
357 if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
358 usbi_err(ctx, "failed to wait for timer thread to become ready - aborting");
365 usbi_dbg("no hires timer available on this platform");
367 hires_ticks_to_ps = UINT64_C(0);
373 static void windows_destroy_clock(void)
376 // actually the signal to quit the thread.
377 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0)
378 || (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
379 usbi_dbg("could not wait for timer thread to quit");
380 TerminateThread(timer_thread, 1);
381 // shouldn't happen, but we're destroying
382 // all objects it might have held anyway.
384 CloseHandle(timer_thread);
390 /* Windows version detection */
391 static BOOL is_x64(void)
395 // Detect if we're running a 32 or 64 bit system
396 if (sizeof(uintptr_t) < 8) {
397 if (pIsWow64Process != NULL)
398 pIsWow64Process(GetCurrentProcess(), &ret);
406 static void get_windows_version(void)
408 OSVERSIONINFOEXA vi, vi2;
409 const char *arch, *w = NULL;
410 unsigned major, minor, version;
411 ULONGLONG major_equal, minor_equal;
414 windows_version = WINDOWS_UNDEFINED;
416 memset(&vi, 0, sizeof(vi));
417 vi.dwOSVersionInfoSize = sizeof(vi);
418 if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
419 memset(&vi, 0, sizeof(vi));
420 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
421 if (!GetVersionExA((OSVERSIONINFOA *)&vi))
425 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
428 if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
429 // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
430 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
432 major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
433 for (major = vi.dwMajorVersion; major <= 9; major++) {
434 memset(&vi2, 0, sizeof(vi2));
435 vi2.dwOSVersionInfoSize = sizeof(vi2);
436 vi2.dwMajorVersion = major;
437 if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
440 if (vi.dwMajorVersion < major) {
441 vi.dwMajorVersion = major;
442 vi.dwMinorVersion = 0;
445 minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
446 for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
447 memset(&vi2, 0, sizeof(vi2));
448 vi2.dwOSVersionInfoSize = sizeof(vi2);
449 vi2.dwMinorVersion = minor;
450 if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
453 vi.dwMinorVersion = minor;
461 if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
464 ws = (vi.wProductType <= VER_NT_WORKSTATION);
465 version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
467 case 0x50: windows_version = WINDOWS_2000; w = "2000"; break;
468 case 0x51: windows_version = WINDOWS_XP; w = "XP"; break;
469 case 0x52: windows_version = WINDOWS_2003; w = "2003"; break;
470 case 0x60: windows_version = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break;
471 case 0x61: windows_version = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break;
472 case 0x62: windows_version = WINDOWS_8; w = (ws ? "8" : "2012"); break;
473 case 0x63: windows_version = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break;
474 case 0x64: // Early Windows 10 Insider Previews and Windows Server 2017 Technical Preview 1 used version 6.4
475 case 0xA0: windows_version = WINDOWS_10; w = (ws ? "10" : "2016"); break;
477 if (version < 0x50) {
480 windows_version = WINDOWS_11_OR_LATER;
485 arch = is_x64() ? "64-bit" : "32-bit";
487 if (vi.wServicePackMinor)
488 usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
489 else if (vi.wServicePackMajor)
490 usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
492 usbi_dbg("Windows %s %s", w, arch);
496 * Monotonic and real time functions
498 static unsigned __stdcall windows_clock_gettime_threaded(void *param)
500 struct timer_request *request;
501 LARGE_INTEGER hires_counter;
504 // The following call will create this thread's message queue
505 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx
506 pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
508 // Signal windows_init_clock() that we're ready to service requests
509 if (!SetEvent((HANDLE)param))
510 usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0));
513 // Main loop - wait for requests
515 if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) {
516 usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0));
520 switch (msg.message) {
521 case WM_TIMER_REQUEST:
522 // Requests to this thread are for hires always
523 // Microsoft says that this function always succeeds on XP and later
524 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx
525 request = (struct timer_request *)msg.lParam;
526 QueryPerformanceCounter(&hires_counter);
527 request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
528 request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
529 if (!SetEvent(request->event))
530 usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0));
533 usbi_dbg("timer thread quitting");
539 static void windows_transfer_callback(const struct windows_backend *backend,
540 struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
544 usbi_dbg("handling I/O completion with errcode %u, size %u", (unsigned int)io_result, (unsigned int)io_size);
548 status = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
550 case ERROR_GEN_FAILURE:
551 usbi_dbg("detected endpoint stall");
552 status = LIBUSB_TRANSFER_STALL;
554 case ERROR_SEM_TIMEOUT:
555 usbi_dbg("detected semaphore timeout");
556 status = LIBUSB_TRANSFER_TIMED_OUT;
558 case ERROR_OPERATION_ABORTED:
559 istatus = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
560 if (istatus != LIBUSB_TRANSFER_COMPLETED)
561 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
563 usbi_dbg("detected operation aborted");
564 status = LIBUSB_TRANSFER_CANCELLED;
566 case ERROR_FILE_NOT_FOUND:
567 case ERROR_DEVICE_NOT_CONNECTED:
568 usbi_dbg("detected device removed");
569 status = LIBUSB_TRANSFER_NO_DEVICE;
572 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", (unsigned int)io_result, windows_error_str(io_result));
573 status = LIBUSB_TRANSFER_ERROR;
576 backend->clear_transfer_priv(itransfer); // Cancel polling
577 if (status == LIBUSB_TRANSFER_CANCELLED)
578 usbi_handle_transfer_cancellation(itransfer);
580 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
583 static void windows_handle_callback(const struct windows_backend *backend,
584 struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
586 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
588 switch (transfer->type) {
589 case LIBUSB_TRANSFER_TYPE_CONTROL:
590 case LIBUSB_TRANSFER_TYPE_BULK:
591 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
592 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
593 windows_transfer_callback(backend, itransfer, io_result, io_size);
595 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
596 usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
599 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
603 static int windows_init(struct libusb_context *ctx)
605 struct windows_context_priv *priv = _context_priv(ctx);
607 char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
608 int r = LIBUSB_ERROR_OTHER;
609 bool winusb_backend_init = false;
611 sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
612 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
613 if (semaphore == NULL) {
614 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
615 return LIBUSB_ERROR_NO_MEM;
618 // A successful wait brings our semaphore count to 0 (unsignaled)
619 // => any concurent wait stalls until the semaphore's release
620 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
621 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
622 CloseHandle(semaphore);
623 return LIBUSB_ERROR_NO_MEM;
626 // NB: concurrent usage supposes that init calls are equally balanced with
627 // exit calls. If init is called more than exit, we will not exit properly
628 if (++init_count == 1) { // First init?
630 if (!windows_init_dlls()) {
631 usbi_err(ctx, "could not resolve DLL functions");
635 get_windows_version();
637 if (windows_version == WINDOWS_UNDEFINED) {
638 usbi_err(ctx, "failed to detect Windows version");
639 r = LIBUSB_ERROR_NOT_SUPPORTED;
643 if (!windows_init_clock(ctx))
646 if (!htab_create(ctx))
649 r = winusb_backend.init(ctx);
650 if (r != LIBUSB_SUCCESS)
652 winusb_backend_init = true;
654 r = usbdk_backend.init(ctx);
655 if (r == LIBUSB_SUCCESS) {
656 usbi_dbg("UsbDk backend is available");
657 usbdk_available = true;
659 usbi_info(ctx, "UsbDk backend is not available");
660 // Do not report this as an error
665 // By default, new contexts will use the WinUSB backend
666 priv->backend = &winusb_backend;
670 init_exit: // Holds semaphore here
671 if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
672 if (winusb_backend_init)
673 winusb_backend.exit(ctx);
675 windows_destroy_clock();
680 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
681 CloseHandle(semaphore);
685 static void windows_exit(struct libusb_context *ctx)
688 char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
691 sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
692 semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
693 if (semaphore == NULL)
696 // A successful wait brings our semaphore count to 0 (unsignaled)
697 // => any concurent wait stalls until the semaphore release
698 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
699 CloseHandle(semaphore);
703 // Only works if exits and inits are balanced exactly
704 if (--init_count == 0) { // Last exit
705 if (usbdk_available) {
706 usbdk_backend.exit(ctx);
707 usbdk_available = false;
709 winusb_backend.exit(ctx);
711 windows_destroy_clock();
715 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
716 CloseHandle(semaphore);
719 static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
721 struct windows_context_priv *priv = _context_priv(ctx);
726 case LIBUSB_OPTION_USE_USBDK:
727 if (usbdk_available) {
728 usbi_dbg("switching context %p to use UsbDk backend", ctx);
729 priv->backend = &usbdk_backend;
731 usbi_err(ctx, "UsbDk backend not available");
732 return LIBUSB_ERROR_NOT_FOUND;
734 return LIBUSB_SUCCESS;
736 return LIBUSB_ERROR_NOT_SUPPORTED;
741 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
743 struct windows_context_priv *priv = _context_priv(ctx);
744 return priv->backend->get_device_list(ctx, discdevs);
747 static int windows_open(struct libusb_device_handle *dev_handle)
749 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
750 return priv->backend->open(dev_handle);
753 static void windows_close(struct libusb_device_handle *dev_handle)
755 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
756 priv->backend->close(dev_handle);
759 static int windows_get_device_descriptor(struct libusb_device *dev,
760 unsigned char *buffer, int *host_endian)
762 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
764 return priv->backend->get_device_descriptor(dev, buffer);
767 static int windows_get_active_config_descriptor(struct libusb_device *dev,
768 unsigned char *buffer, size_t len, int *host_endian)
770 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
772 return priv->backend->get_active_config_descriptor(dev, buffer, len);
775 static int windows_get_config_descriptor(struct libusb_device *dev,
776 uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
778 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
780 return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
783 static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
784 uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian)
786 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
788 return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
791 static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
793 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
794 return priv->backend->get_configuration(dev_handle, config);
797 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
799 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
800 return priv->backend->set_configuration(dev_handle, config);
803 static int windows_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
805 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
806 return priv->backend->claim_interface(dev_handle, interface_number);
809 static int windows_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
811 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
812 return priv->backend->release_interface(dev_handle, interface_number);
815 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
816 int interface_number, int altsetting)
818 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
819 return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
822 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
824 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
825 return priv->backend->clear_halt(dev_handle, endpoint);
828 static int windows_reset_device(struct libusb_device_handle *dev_handle)
830 struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
831 return priv->backend->reset_device(dev_handle);
834 static void windows_destroy_device(struct libusb_device *dev)
836 struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
837 priv->backend->destroy_device(dev);
840 static int windows_submit_transfer(struct usbi_transfer *itransfer)
842 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
843 return priv->backend->submit_transfer(itransfer);
846 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
848 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
849 return priv->backend->cancel_transfer(itransfer);
852 static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
854 struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
855 priv->backend->clear_transfer_priv(itransfer);
858 static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
860 struct windows_context_priv *priv = _context_priv(ctx);
861 struct usbi_transfer *itransfer;
862 DWORD io_size, io_result;
866 int r = LIBUSB_SUCCESS;
868 usbi_mutex_lock(&ctx->open_devs_lock);
869 for (i = 0; i < nfds && num_ready > 0; i++) {
871 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
878 // Because a Windows OVERLAPPED is used for poll emulation,
879 // a pollable fd is created and stored with each transfer
882 usbi_mutex_lock(&ctx->flying_transfers_lock);
883 list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
884 transfer_fd = priv->backend->get_transfer_fd(itransfer);
885 if (transfer_fd == fds[i].fd) {
890 usbi_mutex_unlock(&ctx->flying_transfers_lock);
893 priv->backend->get_overlapped_result(itransfer, &io_result, &io_size);
895 usbi_remove_pollfd(ctx, transfer_fd);
897 // let handle_callback free the event using the transfer wfd
898 // If you don't use the transfer wfd, you run a risk of trying to free a
899 // newly allocated wfd that took the place of the one from the transfer.
900 windows_handle_callback(priv->backend, itransfer, io_result, io_size);
902 usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd);
903 r = LIBUSB_ERROR_NOT_FOUND;
907 usbi_mutex_unlock(&ctx->open_devs_lock);
912 static int windows_clock_gettime(int clk_id, struct timespec *tp)
914 struct timer_request request;
915 #if !defined(_MSC_VER) || (_MSC_VER < 1900)
917 ULARGE_INTEGER rtime;
922 case USBI_CLOCK_MONOTONIC:
925 request.event = CreateEvent(NULL, FALSE, FALSE, NULL);
926 if (request.event == NULL)
927 return LIBUSB_ERROR_NO_MEM;
929 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) {
930 usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0));
931 CloseHandle(request.event);
932 return LIBUSB_ERROR_OTHER;
936 r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS);
937 if (r == WAIT_TIMEOUT)
938 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
939 else if (r == WAIT_FAILED)
940 usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0));
941 } while (r == WAIT_TIMEOUT);
942 CloseHandle(request.event);
944 if (r == WAIT_OBJECT_0)
945 return LIBUSB_SUCCESS;
947 return LIBUSB_ERROR_OTHER;
949 // Fall through and return real-time if monotonic was not detected @ timer init
950 case USBI_CLOCK_REALTIME:
951 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
952 timespec_get(tp, TIME_UTC);
954 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
955 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
956 // Note however that our resolution is bounded by the Windows system time
957 // functions and is at best of the order of 1 ms (or, usually, worse)
958 GetSystemTimeAsFileTime(&filetime);
959 rtime.LowPart = filetime.dwLowDateTime;
960 rtime.HighPart = filetime.dwHighDateTime;
961 rtime.QuadPart -= EPOCH_TIME;
962 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
963 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
965 return LIBUSB_SUCCESS;
967 return LIBUSB_ERROR_INVALID_PARAM;
971 // NB: MSVC6 does not support named initializers.
972 const struct usbi_os_backend usbi_backend = {
974 USBI_CAP_HAS_HID_ACCESS,
978 windows_get_device_list,
979 NULL, /* hotplug_poll */
980 NULL, /* wrap_sys_device */
983 windows_get_device_descriptor,
984 windows_get_active_config_descriptor,
985 windows_get_config_descriptor,
986 windows_get_config_descriptor_by_value,
987 windows_get_configuration,
988 windows_set_configuration,
989 windows_claim_interface,
990 windows_release_interface,
991 windows_set_interface_altsetting,
993 windows_reset_device,
994 NULL, /* alloc_streams */
995 NULL, /* free_streams */
996 NULL, /* dev_mem_alloc */
997 NULL, /* dev_mem_free */
998 NULL, /* kernel_driver_active */
999 NULL, /* detach_kernel_driver */
1000 NULL, /* attach_kernel_driver */
1001 windows_destroy_device,
1002 windows_submit_transfer,
1003 windows_cancel_transfer,
1004 windows_clear_transfer_priv,
1005 windows_handle_events,
1006 NULL, /* handle_transfer_completion */
1007 windows_clock_gettime,
1008 sizeof(struct windows_context_priv),
1009 sizeof(union windows_device_priv),
1010 sizeof(union windows_device_handle_priv),
1011 sizeof(union windows_transfer_priv),