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"
35 // Global variables for clock_gettime mechanism
36 static uint64_t hires_ticks_to_ps;
37 static uint64_t hires_frequency;
39 #define TIMER_REQUEST_RETRY_MS 100
40 #define WM_TIMER_REQUEST (WM_USER + 1)
41 #define WM_TIMER_EXIT (WM_USER + 2)
43 // used for monotonic clock_gettime()
44 struct timer_request {
50 static HANDLE timer_thread = NULL;
51 static DWORD timer_thread_id = 0;
53 /* User32 dependencies */
54 DLL_DECLARE_HANDLE(User32);
55 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
56 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
57 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM));
59 static unsigned __stdcall windows_clock_gettime_threaded(void *param);
62 * Converts a windows error to human readable string
63 * uses retval as errorcode, or, if 0, use GetLastError()
65 #if defined(ENABLE_LOGGING)
66 const char *windows_error_str(DWORD error_code)
68 static char err_string[ERR_BUFFER_SIZE];
74 error_code = GetLastError();
76 len = sprintf(err_string, "[%u] ", (unsigned int)error_code);
78 // Translate codes returned by SetupAPI. The ones we are dealing with are either
79 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
80 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
81 switch (error_code & 0xE0000000) {
83 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
86 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
92 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
93 NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
94 &err_string[len], ERR_BUFFER_SIZE - len, NULL);
96 DWORD format_error = GetLastError();
98 snprintf(err_string, ERR_BUFFER_SIZE,
99 "Windows error code %u (FormatMessage error code %u)",
100 (unsigned int)error_code, (unsigned int)format_error);
102 snprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code);
104 // Remove CRLF from end of message, if present
105 size_t pos = len + size - 2;
106 if (err_string[pos] == '\r')
107 err_string[pos] = '\0';
114 /* Hash table functions - modified From glibc 2.3.2:
115 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
116 [Knuth] The Art of Computer Programming, part 3 (6.4) */
118 #define HTAB_SIZE 1021UL // *MUST* be a prime number!!
120 typedef struct htab_entry {
125 static htab_entry *htab_table = NULL;
126 static usbi_mutex_t htab_mutex;
127 static unsigned long htab_filled;
129 /* Before using the hash table we must allocate memory for it.
130 We allocate one element more as the found prime number says.
131 This is done for more effective indexing as explained in the
132 comment for the hash function. */
133 static bool htab_create(struct libusb_context *ctx)
135 if (htab_table != NULL) {
136 usbi_err(ctx, "hash table already allocated");
141 usbi_mutex_init(&htab_mutex);
143 usbi_dbg("using %lu entries hash table", HTAB_SIZE);
146 // allocate memory and zero out.
147 htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
148 if (htab_table == NULL) {
149 usbi_err(ctx, "could not allocate space for hash table");
156 /* After using the hash table it has to be destroyed. */
157 static void htab_destroy(void)
161 if (htab_table == NULL)
164 for (i = 0; i < HTAB_SIZE; i++)
165 free(htab_table[i].str);
167 safe_free(htab_table);
169 usbi_mutex_destroy(&htab_mutex);
172 /* This is the search function. It uses double hashing with open addressing.
173 We use a trick to speed up the lookup. The table is created with one
174 more element available. This enables us to use the index zero special.
175 This index will never be used because we store the first hash index in
176 the field used where zero means not used. Every other value means used.
177 The used field can be used as a first fast comparison for equality of
178 the stored and the parameter value. This helps to prevent unnecessary
179 expensive calls of strcmp. */
180 unsigned long htab_hash(const char *str)
182 unsigned long hval, hval2;
184 unsigned long r = 5381;
186 const char *sz = str;
191 // Compute main hash value (algorithm suggested by Nokia)
192 while ((c = *sz++) != 0)
193 r = ((r << 5) + r) + c;
197 // compute table hash: simply take the modulus
198 hval = r % HTAB_SIZE;
202 // Try the first index
205 // Mutually exclusive access (R/W lock would be better)
206 usbi_mutex_lock(&htab_mutex);
208 if (htab_table[idx].used) {
209 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
210 goto out_unlock; // existing hash
212 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
214 // Second hash function, as suggested in [Knuth]
215 hval2 = 1 + hval % (HTAB_SIZE - 2);
218 // Because size is prime this guarantees to step through all available indexes
220 idx = HTAB_SIZE + idx - hval2;
224 // If we visited all entries leave the loop unsuccessfully
228 // If entry is found use it.
229 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
231 } while (htab_table[idx].used);
234 // Not found => New entry
236 // If the table is full return an error
237 if (htab_filled >= HTAB_SIZE) {
238 usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
243 htab_table[idx].str = _strdup(str);
244 if (htab_table[idx].str == NULL) {
245 usbi_err(NULL, "could not duplicate string for hash table");
250 htab_table[idx].used = hval;
254 usbi_mutex_unlock(&htab_mutex);
259 static int windows_init_dlls(void)
261 DLL_GET_HANDLE(User32);
262 DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE);
263 DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
264 DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
266 return LIBUSB_SUCCESS;
269 static void windows_exit_dlls(void)
271 DLL_FREE_HANDLE(User32);
274 static bool windows_init_clock(struct libusb_context *ctx)
276 DWORD_PTR affinity, dummy;
278 LARGE_INTEGER li_frequency;
281 if (QueryPerformanceFrequency(&li_frequency)) {
283 if (windows_init_dlls() != LIBUSB_SUCCESS) {
284 usbi_err(ctx, "could not resolve DLL functions");
288 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
289 // to picoseconds to compute the tv_nsecs part in clock_gettime
290 hires_frequency = li_frequency.QuadPart;
291 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
292 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
294 // Because QueryPerformanceCounter might report different values when
295 // running on different cores, we create a separate thread for the timer
296 // calls, which we glue to the first available core always to prevent timing discrepancies.
297 if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) {
298 usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0));
302 // The process affinity mask is a bitmask where each set bit represents a core on
303 // which this process is allowed to run, so we find the first set bit
304 for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++);
305 affinity = (DWORD_PTR)(1 << i);
307 usbi_dbg("timer thread will run on core #%d", i);
309 event = CreateEvent(NULL, FALSE, FALSE, NULL);
311 usbi_err(ctx, "could not create event: %s", windows_error_str(0));
315 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event,
316 0, (unsigned int *)&timer_thread_id);
317 if (timer_thread == NULL) {
318 usbi_err(ctx, "unable to create timer thread - aborting");
323 if (!SetThreadAffinityMask(timer_thread, affinity))
324 usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise");
326 // Wait for timer thread to init before continuing.
327 if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
328 usbi_err(ctx, "failed to wait for timer thread to become ready - aborting");
335 usbi_dbg("no hires timer available on this platform");
337 hires_ticks_to_ps = UINT64_C(0);
343 void windows_destroy_clock(void)
346 // actually the signal to quit the thread.
347 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0)
348 || (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
349 usbi_dbg("could not wait for timer thread to quit");
350 TerminateThread(timer_thread, 1);
351 // shouldn't happen, but we're destroying
352 // all objects it might have held anyway.
354 CloseHandle(timer_thread);
361 * Monotonic and real time functions
363 static unsigned __stdcall windows_clock_gettime_threaded(void *param)
365 struct timer_request *request;
366 LARGE_INTEGER hires_counter;
369 // The following call will create this thread's message queue
370 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx
371 pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
373 // Signal windows_init_clock() that we're ready to service requests
374 if (!SetEvent((HANDLE)param))
375 usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0));
378 // Main loop - wait for requests
380 if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) {
381 usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0));
385 switch (msg.message) {
386 case WM_TIMER_REQUEST:
387 // Requests to this thread are for hires always
388 // Microsoft says that this function always succeeds on XP and later
389 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx
390 request = (struct timer_request *)msg.lParam;
391 QueryPerformanceCounter(&hires_counter);
392 request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
393 request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
394 if (!SetEvent(request->event))
395 usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0));
398 usbi_dbg("timer thread quitting");
404 int windows_clock_gettime(int clk_id, struct timespec *tp)
406 struct timer_request request;
407 #if !defined(_MSC_VER) || (_MSC_VER < 1900)
409 ULARGE_INTEGER rtime;
414 case USBI_CLOCK_MONOTONIC:
417 request.event = CreateEvent(NULL, FALSE, FALSE, NULL);
418 if (request.event == NULL)
419 return LIBUSB_ERROR_NO_MEM;
421 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) {
422 usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0));
423 CloseHandle(request.event);
424 return LIBUSB_ERROR_OTHER;
428 r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS);
429 if (r == WAIT_TIMEOUT)
430 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
431 else if (r == WAIT_FAILED)
432 usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0));
433 } while (r == WAIT_TIMEOUT);
434 CloseHandle(request.event);
436 if (r == WAIT_OBJECT_0)
437 return LIBUSB_SUCCESS;
439 return LIBUSB_ERROR_OTHER;
441 // Fall through and return real-time if monotonic was not detected @ timer init
442 case USBI_CLOCK_REALTIME:
443 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
444 timespec_get(tp, TIME_UTC);
446 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
447 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
448 // Note however that our resolution is bounded by the Windows system time
449 // functions and is at best of the order of 1 ms (or, usually, worse)
450 GetSystemTimeAsFileTime(&filetime);
451 rtime.LowPart = filetime.dwLowDateTime;
452 rtime.HighPart = filetime.dwHighDateTime;
453 rtime.QuadPart -= EPOCH_TIME;
454 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
455 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
457 return LIBUSB_SUCCESS;
459 return LIBUSB_ERROR_INVALID_PARAM;
463 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
467 usbi_dbg("handling I/O completion with errcode %u, size %u", io_result, io_size);
471 status = windows_copy_transfer_data(itransfer, io_size);
473 case ERROR_GEN_FAILURE:
474 usbi_dbg("detected endpoint stall");
475 status = LIBUSB_TRANSFER_STALL;
477 case ERROR_SEM_TIMEOUT:
478 usbi_dbg("detected semaphore timeout");
479 status = LIBUSB_TRANSFER_TIMED_OUT;
481 case ERROR_OPERATION_ABORTED:
482 istatus = windows_copy_transfer_data(itransfer, io_size);
483 if (istatus != LIBUSB_TRANSFER_COMPLETED)
484 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
486 usbi_dbg("detected operation aborted");
487 status = LIBUSB_TRANSFER_CANCELLED;
490 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", io_result, windows_error_str(io_result));
491 status = LIBUSB_TRANSFER_ERROR;
494 windows_clear_transfer_priv(itransfer); // Cancel polling
495 if (status == LIBUSB_TRANSFER_CANCELLED)
496 usbi_handle_transfer_cancellation(itransfer);
498 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
501 void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
503 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
505 switch (transfer->type) {
506 case LIBUSB_TRANSFER_TYPE_CONTROL:
507 case LIBUSB_TRANSFER_TYPE_BULK:
508 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
509 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
510 windows_transfer_callback(itransfer, io_result, io_size);
512 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
513 usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
516 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
520 int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
524 struct usbi_transfer *transfer;
525 struct winfd *pollable_fd = NULL;
526 DWORD io_size, io_result;
527 int r = LIBUSB_SUCCESS;
529 usbi_mutex_lock(&ctx->open_devs_lock);
530 for (i = 0; i < nfds && num_ready > 0; i++) {
532 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
539 // Because a Windows OVERLAPPED is used for poll emulation,
540 // a pollable fd is created and stored with each transfer
541 usbi_mutex_lock(&ctx->flying_transfers_lock);
543 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
544 pollable_fd = windows_get_fd(transfer);
545 if (pollable_fd->fd == fds[i].fd) {
550 usbi_mutex_unlock(&ctx->flying_transfers_lock);
553 windows_get_overlapped_result(transfer, pollable_fd, &io_result, &io_size);
555 usbi_remove_pollfd(ctx, pollable_fd->fd);
556 // let handle_callback free the event using the transfer wfd
557 // If you don't use the transfer wfd, you run a risk of trying to free a
558 // newly allocated wfd that took the place of the one from the transfer.
559 windows_handle_callback(transfer, io_result, io_size);
561 usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
562 r = LIBUSB_ERROR_NOT_FOUND;
566 usbi_mutex_unlock(&ctx->open_devs_lock);
571 int windows_common_init(struct libusb_context *ctx)
573 if (!windows_init_clock(ctx))
574 goto error_roll_back;
576 if (!htab_create(ctx))
577 goto error_roll_back;
579 return LIBUSB_SUCCESS;
582 windows_common_exit();
583 return LIBUSB_ERROR_NO_MEM;
586 void windows_common_exit(void)
589 windows_destroy_clock();