1 /*
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
9 *
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.
14 *
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.
19 *
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
23 */
24
25 #include <config.h>
26
27 #include <inttypes.h>
28 #include <process.h>
29 #include <stdio.h>
30
31 #include "libusbi.h"
32 #include "windows_common.h"
33 #include "windows_nt_common.h"
34
35 // Global variables
36 const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
37
38 // Global variables for clock_gettime mechanism
39 static uint64_t hires_ticks_to_ps;
40 static uint64_t hires_frequency;
41
42 #define TIMER_REQUEST_RETRY_MS 100
43 #define WM_TIMER_REQUEST (WM_USER + 1)
44 #define WM_TIMER_EXIT (WM_USER + 2)
45
46 // used for monotonic clock_gettime()
47 struct timer_request {
48 struct timespec *tp;
49 HANDLE event;
50 };
51
52 // Timer thread
53 static HANDLE timer_thread = NULL;
54 static DWORD timer_thread_id = 0;
55
56 /* User32 dependencies */
57 DLL_DECLARE_HANDLE(User32);
58 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
59 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
60 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM));
61
62 static unsigned __stdcall windows_clock_gettime_threaded(void *param);
63
64 /*
65 * Converts a windows error to human readable string
66 * uses retval as errorcode, or, if 0, use GetLastError()
67 */
68 #if defined(ENABLE_LOGGING)
windows_error_str(DWORD retval)69 const char *windows_error_str(DWORD retval)
70 {
71 static char err_string[ERR_BUFFER_SIZE];
72
73 DWORD error_code, format_error;
74 DWORD size;
75 ssize_t i;
76
77 error_code = retval ? retval : GetLastError();
78
79 safe_sprintf(err_string, ERR_BUFFER_SIZE, "[%u] ", (unsigned int)error_code);
80
81 // Translate codes returned by SetupAPI. The ones we are dealing with are either
82 // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
83 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
84 switch (error_code & 0xE0000000) {
85 case 0:
86 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
87 break;
88 case 0xE0000000:
89 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
90 break;
91 default:
92 break;
93 }
94
95 size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
96 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
97 ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
98 if (size == 0) {
99 format_error = GetLastError();
100 if (format_error)
101 safe_sprintf(err_string, ERR_BUFFER_SIZE,
102 "Windows error code %u (FormatMessage error code %u)",
103 (unsigned int)error_code, (unsigned int)format_error);
104 else
105 safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code);
106 }
107 else {
108 // Remove CR/LF terminators
109 for (i = safe_strlen(err_string) - 1; (i >= 0) && ((err_string[i] == 0x0A) || (err_string[i] == 0x0D)); i--)
110 err_string[i] = 0;
111 }
112
113 return err_string;
114 }
115 #endif
116
117 /* Hash table functions - modified From glibc 2.3.2:
118 [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
119 [Knuth] The Art of Computer Programming, part 3 (6.4) */
120
121 #define HTAB_SIZE 1021
122
123 typedef struct htab_entry {
124 unsigned long used;
125 char *str;
126 } htab_entry;
127
128 static htab_entry *htab_table = NULL;
129 static usbi_mutex_t htab_write_mutex = NULL;
130 static unsigned long htab_size, htab_filled;
131
132 /* For the used double hash method the table size has to be a prime. To
133 correct the user given table size we need a prime test. This trivial
134 algorithm is adequate because the code is called only during init and
135 the number is likely to be small */
isprime(unsigned long number)136 static int isprime(unsigned long number)
137 {
138 // no even number will be passed
139 unsigned int divider = 3;
140
141 while((divider * divider < number) && (number % divider != 0))
142 divider += 2;
143
144 return (number % divider != 0);
145 }
146
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. */
htab_create(struct libusb_context * ctx,unsigned long nel)151 static bool htab_create(struct libusb_context *ctx, unsigned long nel)
152 {
153 if (htab_table != NULL) {
154 usbi_err(ctx, "hash table already allocated");
155 return true;
156 }
157
158 // Create a mutex
159 usbi_mutex_init(&htab_write_mutex);
160
161 // Change nel to the first prime number not smaller as nel.
162 nel |= 1;
163 while (!isprime(nel))
164 nel += 2;
165
166 htab_size = nel;
167 usbi_dbg("using %lu entries hash table", nel);
168 htab_filled = 0;
169
170 // allocate memory and zero out.
171 htab_table = calloc(htab_size + 1, sizeof(htab_entry));
172 if (htab_table == NULL) {
173 usbi_err(ctx, "could not allocate space for hash table");
174 return false;
175 }
176
177 return true;
178 }
179
180 /* After using the hash table it has to be destroyed. */
htab_destroy(void)181 static void htab_destroy(void)
182 {
183 unsigned long i;
184
185 if (htab_table == NULL)
186 return;
187
188 for (i = 0; i < htab_size; i++) {
189 if (htab_table[i].used)
190 safe_free(htab_table[i].str);
191 }
192
193 usbi_mutex_destroy(&htab_write_mutex);
194 safe_free(htab_table);
195 }
196
197 /* This is the search function. It uses double hashing with open addressing.
198 We use a trick to speed up the lookup. The table is created with one
199 more element available. This enables us to use the index zero special.
200 This index will never be used because we store the first hash index in
201 the field used where zero means not used. Every other value means used.
202 The used field can be used as a first fast comparison for equality of
203 the stored and the parameter value. This helps to prevent unnecessary
204 expensive calls of strcmp. */
htab_hash(const char * str)205 unsigned long htab_hash(const char *str)
206 {
207 unsigned long hval, hval2;
208 unsigned long idx;
209 unsigned long r = 5381;
210 int c;
211 const char *sz = str;
212
213 if (str == NULL)
214 return 0;
215
216 // Compute main hash value (algorithm suggested by Nokia)
217 while ((c = *sz++) != 0)
218 r = ((r << 5) + r) + c;
219 if (r == 0)
220 ++r;
221
222 // compute table hash: simply take the modulus
223 hval = r % htab_size;
224 if (hval == 0)
225 ++hval;
226
227 // Try the first index
228 idx = hval;
229
230 if (htab_table[idx].used) {
231 if ((htab_table[idx].used == hval) && (safe_strcmp(str, htab_table[idx].str) == 0))
232 return idx; // existing hash
233
234 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
235
236 // Second hash function, as suggested in [Knuth]
237 hval2 = 1 + hval % (htab_size - 2);
238
239 do {
240 // Because size is prime this guarantees to step through all available indexes
241 if (idx <= hval2)
242 idx = htab_size + idx - hval2;
243 else
244 idx -= hval2;
245
246 // If we visited all entries leave the loop unsuccessfully
247 if (idx == hval)
248 break;
249
250 // If entry is found use it.
251 if ((htab_table[idx].used == hval) && (safe_strcmp(str, htab_table[idx].str) == 0))
252 return idx;
253 } while (htab_table[idx].used);
254 }
255
256 // Not found => New entry
257
258 // If the table is full return an error
259 if (htab_filled >= htab_size) {
260 usbi_err(NULL, "hash table is full (%d entries)", htab_size);
261 return 0;
262 }
263
264 // Concurrent threads might be storing the same entry at the same time
265 // (eg. "simultaneous" enums from different threads) => use a mutex
266 usbi_mutex_lock(&htab_write_mutex);
267 // Just free any previously allocated string (which should be the same as
268 // new one). The possibility of concurrent threads storing a collision
269 // string (same hash, different string) at the same time is extremely low
270 safe_free(htab_table[idx].str);
271 htab_table[idx].used = hval;
272 htab_table[idx].str = _strdup(str);
273 if (htab_table[idx].str == NULL) {
274 usbi_err(NULL, "could not duplicate string for hash table");
275 usbi_mutex_unlock(&htab_write_mutex);
276 return 0;
277 }
278 ++htab_filled;
279 usbi_mutex_unlock(&htab_write_mutex);
280
281 return idx;
282 }
283
windows_init_dlls(void)284 static int windows_init_dlls(void)
285 {
286 DLL_GET_HANDLE(User32);
287 DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE);
288 DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
289 DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
290
291 return LIBUSB_SUCCESS;
292 }
293
windows_exit_dlls(void)294 static void windows_exit_dlls(void)
295 {
296 DLL_FREE_HANDLE(User32);
297 }
298
windows_init_clock(struct libusb_context * ctx)299 static bool windows_init_clock(struct libusb_context *ctx)
300 {
301 DWORD_PTR affinity, dummy;
302 HANDLE event = NULL;
303 LARGE_INTEGER li_frequency;
304 int i;
305
306 if (QueryPerformanceFrequency(&li_frequency)) {
307 // Load DLL imports
308 if (windows_init_dlls() != LIBUSB_SUCCESS) {
309 usbi_err(ctx, "could not resolve DLL functions");
310 return false;
311 }
312
313 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
314 // to picoseconds to compute the tv_nsecs part in clock_gettime
315 hires_frequency = li_frequency.QuadPart;
316 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
317 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
318
319 // Because QueryPerformanceCounter might report different values when
320 // running on different cores, we create a separate thread for the timer
321 // calls, which we glue to the first available core always to prevent timing discrepancies.
322 if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) {
323 usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0));
324 return false;
325 }
326
327 // The process affinity mask is a bitmask where each set bit represents a core on
328 // which this process is allowed to run, so we find the first set bit
329 for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++);
330 affinity = (DWORD_PTR)(1 << i);
331
332 usbi_dbg("timer thread will run on core #%d", i);
333
334 event = CreateEvent(NULL, FALSE, FALSE, NULL);
335 if (event == NULL) {
336 usbi_err(ctx, "could not create event: %s", windows_error_str(0));
337 return false;
338 }
339
340 timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event,
341 0, (unsigned int *)&timer_thread_id);
342 if (timer_thread == NULL) {
343 usbi_err(ctx, "unable to create timer thread - aborting");
344 CloseHandle(event);
345 return false;
346 }
347
348 if (!SetThreadAffinityMask(timer_thread, affinity))
349 usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise");
350
351 // Wait for timer thread to init before continuing.
352 if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
353 usbi_err(ctx, "failed to wait for timer thread to become ready - aborting");
354 CloseHandle(event);
355 return false;
356 }
357
358 CloseHandle(event);
359 } else {
360 usbi_dbg("no hires timer available on this platform");
361 hires_frequency = 0;
362 hires_ticks_to_ps = UINT64_C(0);
363 }
364
365 return true;
366 }
367
windows_destroy_clock(void)368 void windows_destroy_clock(void)
369 {
370 if (timer_thread) {
371 // actually the signal to quit the thread.
372 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0)
373 || (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
374 usbi_dbg("could not wait for timer thread to quit");
375 TerminateThread(timer_thread, 1);
376 // shouldn't happen, but we're destroying
377 // all objects it might have held anyway.
378 }
379 CloseHandle(timer_thread);
380 timer_thread = NULL;
381 timer_thread_id = 0;
382 }
383 }
384
385 /*
386 * Monotonic and real time functions
387 */
windows_clock_gettime_threaded(void * param)388 static unsigned __stdcall windows_clock_gettime_threaded(void *param)
389 {
390 struct timer_request *request;
391 LARGE_INTEGER hires_counter;
392 MSG msg;
393
394 // The following call will create this thread's message queue
395 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx
396 pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
397
398 // Signal windows_init_clock() that we're ready to service requests
399 if (!SetEvent((HANDLE)param))
400 usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0));
401 param = NULL;
402
403 // Main loop - wait for requests
404 while (1) {
405 if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) {
406 usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0));
407 return 1;
408 }
409
410 switch (msg.message) {
411 case WM_TIMER_REQUEST:
412 // Requests to this thread are for hires always
413 // Microsoft says that this function always succeeds on XP and later
414 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx
415 request = (struct timer_request *)msg.lParam;
416 QueryPerformanceCounter(&hires_counter);
417 request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
418 request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
419 if (!SetEvent(request->event))
420 usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0));
421 break;
422 case WM_TIMER_EXIT:
423 usbi_dbg("timer thread quitting");
424 return 0;
425 }
426 }
427 }
428
windows_clock_gettime(int clk_id,struct timespec * tp)429 int windows_clock_gettime(int clk_id, struct timespec *tp)
430 {
431 struct timer_request request;
432 FILETIME filetime;
433 ULARGE_INTEGER rtime;
434 DWORD r;
435
436 switch (clk_id) {
437 case USBI_CLOCK_MONOTONIC:
438 if (timer_thread) {
439 request.tp = tp;
440 request.event = CreateEvent(NULL, FALSE, FALSE, NULL);
441 if (request.event == NULL)
442 return LIBUSB_ERROR_NO_MEM;
443
444 if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) {
445 usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0));
446 CloseHandle(request.event);
447 return LIBUSB_ERROR_OTHER;
448 }
449
450 do {
451 r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS);
452 if (r == WAIT_TIMEOUT)
453 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
454 else if (r == WAIT_FAILED)
455 usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0));
456 } while (r == WAIT_TIMEOUT);
457 CloseHandle(request.event);
458
459 if (r == WAIT_OBJECT_0)
460 return LIBUSB_SUCCESS;
461 else
462 return LIBUSB_ERROR_OTHER;
463 }
464 // Fall through and return real-time if monotonic was not detected @ timer init
465 case USBI_CLOCK_REALTIME:
466 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
467 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
468 // Note however that our resolution is bounded by the Windows system time
469 // functions and is at best of the order of 1 ms (or, usually, worse)
470 GetSystemTimeAsFileTime(&filetime);
471 rtime.LowPart = filetime.dwLowDateTime;
472 rtime.HighPart = filetime.dwHighDateTime;
473 rtime.QuadPart -= epoch_time;
474 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
475 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
476 return LIBUSB_SUCCESS;
477 default:
478 return LIBUSB_ERROR_INVALID_PARAM;
479 }
480 }
481
windows_transfer_callback(struct usbi_transfer * itransfer,uint32_t io_result,uint32_t io_size)482 static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
483 {
484 int status, istatus;
485
486 usbi_dbg("handling I/O completion with errcode %u, size %u", io_result, io_size);
487
488 switch (io_result) {
489 case NO_ERROR:
490 status = windows_copy_transfer_data(itransfer, io_size);
491 break;
492 case ERROR_GEN_FAILURE:
493 usbi_dbg("detected endpoint stall");
494 status = LIBUSB_TRANSFER_STALL;
495 break;
496 case ERROR_SEM_TIMEOUT:
497 usbi_dbg("detected semaphore timeout");
498 status = LIBUSB_TRANSFER_TIMED_OUT;
499 break;
500 case ERROR_OPERATION_ABORTED:
501 istatus = windows_copy_transfer_data(itransfer, io_size);
502 if (istatus != LIBUSB_TRANSFER_COMPLETED)
503 usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
504
505 usbi_dbg("detected operation aborted");
506 status = LIBUSB_TRANSFER_CANCELLED;
507 break;
508 default:
509 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", io_result, windows_error_str(io_result));
510 status = LIBUSB_TRANSFER_ERROR;
511 break;
512 }
513 windows_clear_transfer_priv(itransfer); // Cancel polling
514 if (status == LIBUSB_TRANSFER_CANCELLED)
515 usbi_handle_transfer_cancellation(itransfer);
516 else
517 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
518 }
519
windows_handle_callback(struct usbi_transfer * itransfer,uint32_t io_result,uint32_t io_size)520 void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
521 {
522 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
523
524 switch (transfer->type) {
525 case LIBUSB_TRANSFER_TYPE_CONTROL:
526 case LIBUSB_TRANSFER_TYPE_BULK:
527 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
528 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
529 windows_transfer_callback(itransfer, io_result, io_size);
530 break;
531 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
532 usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
533 break;
534 default:
535 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
536 }
537 }
538
windows_handle_events(struct libusb_context * ctx,struct pollfd * fds,POLL_NFDS_TYPE nfds,int num_ready)539 int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
540 {
541 POLL_NFDS_TYPE i = 0;
542 bool found = false;
543 struct usbi_transfer *transfer;
544 struct winfd *pollable_fd = NULL;
545 DWORD io_size, io_result;
546 int r = LIBUSB_SUCCESS;
547
548 usbi_mutex_lock(&ctx->open_devs_lock);
549 for (i = 0; i < nfds && num_ready > 0; i++) {
550
551 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
552
553 if (!fds[i].revents)
554 continue;
555
556 num_ready--;
557
558 // Because a Windows OVERLAPPED is used for poll emulation,
559 // a pollable fd is created and stored with each transfer
560 usbi_mutex_lock(&ctx->flying_transfers_lock);
561 found = false;
562 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
563 pollable_fd = windows_get_fd(transfer);
564 if (pollable_fd->fd == fds[i].fd) {
565 found = true;
566 break;
567 }
568 }
569 usbi_mutex_unlock(&ctx->flying_transfers_lock);
570
571 if (found) {
572 windows_get_overlapped_result(transfer, pollable_fd, &io_result, &io_size);
573
574 usbi_remove_pollfd(ctx, pollable_fd->fd);
575 // let handle_callback free the event using the transfer wfd
576 // If you don't use the transfer wfd, you run a risk of trying to free a
577 // newly allocated wfd that took the place of the one from the transfer.
578 windows_handle_callback(transfer, io_result, io_size);
579 } else {
580 usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
581 r = LIBUSB_ERROR_NOT_FOUND;
582 break;
583 }
584 }
585 usbi_mutex_unlock(&ctx->open_devs_lock);
586
587 return r;
588 }
589
windows_common_init(struct libusb_context * ctx)590 int windows_common_init(struct libusb_context *ctx)
591 {
592 if (!windows_init_clock(ctx))
593 goto error_roll_back;
594
595 if (!htab_create(ctx, HTAB_SIZE))
596 goto error_roll_back;
597
598 return LIBUSB_SUCCESS;
599
600 error_roll_back:
601 windows_common_exit();
602 return LIBUSB_ERROR_NO_MEM;
603 }
604
windows_common_exit(void)605 void windows_common_exit(void)
606 {
607 htab_destroy();
608 windows_destroy_clock();
609 windows_exit_dlls();
610 }
611