core: Miscellaneous internal logging cleanup
[platform/upstream/libusb.git] / libusb / os / windows_common.c
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 <errno.h>
28 #include <process.h>
29 #include <stdio.h>
30
31 #include "libusbi.h"
32 #include "windows_common.h"
33
34 #define EPOCH_TIME      UINT64_C(116444736000000000)    // 1970.01.01 00:00:000 in MS Filetime
35
36 #define STATUS_SUCCESS  ((ULONG_PTR)0UL)
37
38 // Public
39 enum windows_version windows_version = WINDOWS_UNDEFINED;
40
41 // Global variables for init/exit
42 static unsigned int init_count;
43 static bool usbdk_available;
44
45 #if !defined(HAVE_CLOCK_GETTIME)
46 // Global variables for clock_gettime mechanism
47 static uint64_t hires_ticks_to_ps;
48 static uint64_t hires_frequency;
49 #endif
50
51 /*
52 * Converts a windows error to human readable string
53 * uses retval as errorcode, or, if 0, use GetLastError()
54 */
55 #if defined(ENABLE_LOGGING)
56 const char *windows_error_str(DWORD error_code)
57 {
58         static char err_string[256];
59
60         DWORD size;
61         int len;
62
63         if (error_code == 0)
64                 error_code = GetLastError();
65
66         len = sprintf(err_string, "[%lu] ", ULONG_CAST(error_code));
67
68         // Translate codes returned by SetupAPI. The ones we are dealing with are either
69         // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
70         // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
71         switch (error_code & 0xE0000000) {
72         case 0:
73                 error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
74                 break;
75         case 0xE0000000:
76                 error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
77                 break;
78         default:
79                 break;
80         }
81
82         size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
83                         NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
84                         &err_string[len], sizeof(err_string) - len, NULL);
85         if (size == 0) {
86                 DWORD format_error = GetLastError();
87                 if (format_error)
88                         snprintf(err_string, sizeof(err_string),
89                                 "Windows error code %lu (FormatMessage error code %lu)",
90                                 ULONG_CAST(error_code), ULONG_CAST(format_error));
91                 else
92                         snprintf(err_string, sizeof(err_string), "Unknown error code %lu",
93                                 ULONG_CAST(error_code));
94         } else {
95                 // Remove CRLF from end of message, if present
96                 size_t pos = len + size - 2;
97                 if (err_string[pos] == '\r')
98                         err_string[pos] = '\0';
99         }
100
101         return err_string;
102 }
103 #endif
104
105 /* Hash table functions - modified From glibc 2.3.2:
106    [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
107    [Knuth]            The Art of Computer Programming, part 3 (6.4)  */
108
109 #define HTAB_SIZE 1021UL        // *MUST* be a prime number!!
110
111 typedef struct htab_entry {
112         unsigned long used;
113         char *str;
114 } htab_entry;
115
116 static htab_entry *htab_table;
117 static usbi_mutex_t htab_mutex;
118 static unsigned long htab_filled;
119
120 /* Before using the hash table we must allocate memory for it.
121    We allocate one element more as the found prime number says.
122    This is done for more effective indexing as explained in the
123    comment for the hash function.  */
124 static bool htab_create(struct libusb_context *ctx)
125 {
126         if (htab_table != NULL) {
127                 usbi_err(ctx, "program assertion failed - hash table already allocated");
128                 return true;
129         }
130
131         // Create a mutex
132         usbi_mutex_init(&htab_mutex);
133
134         usbi_dbg("using %lu entries hash table", HTAB_SIZE);
135         htab_filled = 0;
136
137         // allocate memory and zero out.
138         htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry));
139         if (htab_table == NULL) {
140                 usbi_err(ctx, "could not allocate space for hash table");
141                 return false;
142         }
143
144         return true;
145 }
146
147 /* After using the hash table it has to be destroyed.  */
148 static void htab_destroy(void)
149 {
150         unsigned long i;
151
152         if (htab_table == NULL)
153                 return;
154
155         for (i = 0; i < HTAB_SIZE; i++)
156                 free(htab_table[i].str);
157
158         safe_free(htab_table);
159
160         usbi_mutex_destroy(&htab_mutex);
161 }
162
163 /* This is the search function. It uses double hashing with open addressing.
164    We use a trick to speed up the lookup. The table is created with one
165    more element available. This enables us to use the index zero special.
166    This index will never be used because we store the first hash index in
167    the field used where zero means not used. Every other value means used.
168    The used field can be used as a first fast comparison for equality of
169    the stored and the parameter value. This helps to prevent unnecessary
170    expensive calls of strcmp.  */
171 unsigned long htab_hash(const char *str)
172 {
173         unsigned long hval, hval2;
174         unsigned long idx;
175         unsigned long r = 5381UL;
176         int c;
177         const char *sz = str;
178
179         if (str == NULL)
180                 return 0;
181
182         // Compute main hash value (algorithm suggested by Nokia)
183         while ((c = *sz++) != 0)
184                 r = ((r << 5) + r) + c;
185         if (r == 0)
186                 ++r;
187
188         // compute table hash: simply take the modulus
189         hval = r % HTAB_SIZE;
190         if (hval == 0)
191                 ++hval;
192
193         // Try the first index
194         idx = hval;
195
196         // Mutually exclusive access (R/W lock would be better)
197         usbi_mutex_lock(&htab_mutex);
198
199         if (htab_table[idx].used) {
200                 if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
201                         goto out_unlock; // existing hash
202
203                 usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
204
205                 // Second hash function, as suggested in [Knuth]
206                 hval2 = 1UL + hval % (HTAB_SIZE - 2);
207
208                 do {
209                         // Because size is prime this guarantees to step through all available indexes
210                         if (idx <= hval2)
211                                 idx = HTAB_SIZE + idx - hval2;
212                         else
213                                 idx -= hval2;
214
215                         // If we visited all entries leave the loop unsuccessfully
216                         if (idx == hval)
217                                 break;
218
219                         // If entry is found use it.
220                         if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
221                                 goto out_unlock;
222                 } while (htab_table[idx].used);
223         }
224
225         // Not found => New entry
226
227         // If the table is full return an error
228         if (htab_filled >= HTAB_SIZE) {
229                 usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE);
230                 idx = 0UL;
231                 goto out_unlock;
232         }
233
234         htab_table[idx].str = _strdup(str);
235         if (htab_table[idx].str == NULL) {
236                 usbi_err(NULL, "could not duplicate string for hash table");
237                 idx = 0UL;
238                 goto out_unlock;
239         }
240
241         htab_table[idx].used = hval;
242         ++htab_filled;
243
244 out_unlock:
245         usbi_mutex_unlock(&htab_mutex);
246
247         return idx;
248 }
249
250 enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS status)
251 {
252         if (USBD_SUCCESS(status))
253                 return LIBUSB_TRANSFER_COMPLETED;
254
255         switch (status) {
256         case USBD_STATUS_TIMEOUT:
257                 return LIBUSB_TRANSFER_TIMED_OUT;
258         case USBD_STATUS_CANCELED:
259                 return LIBUSB_TRANSFER_CANCELLED;
260         case USBD_STATUS_ENDPOINT_HALTED:
261                 return LIBUSB_TRANSFER_STALL;
262         case USBD_STATUS_DEVICE_GONE:
263                 return LIBUSB_TRANSFER_NO_DEVICE;
264         default:
265                 usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", ULONG_CAST(status));
266                 return LIBUSB_TRANSFER_ERROR;
267         }
268 }
269
270 /*
271  * Make a transfer complete synchronously
272  */
273 void windows_force_sync_completion(struct usbi_transfer *itransfer, ULONG size)
274 {
275         struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
276         OVERLAPPED *overlapped = &transfer_priv->overlapped;
277
278         usbi_dbg("transfer %p, length %lu", USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), size);
279
280         overlapped->Internal = (ULONG_PTR)STATUS_SUCCESS;
281         overlapped->InternalHigh = (ULONG_PTR)size;
282
283         usbi_signal_transfer_completion(itransfer);
284 }
285
286 static void windows_init_clock(void)
287 {
288 #if !defined(HAVE_CLOCK_GETTIME)
289         LARGE_INTEGER li_frequency;
290
291         // Microsoft says that the QueryPerformanceFrequency() and
292         // QueryPerformanceCounter() functions always succeed on XP and later
293         QueryPerformanceFrequency(&li_frequency);
294
295         // The hires frequency can go as high as 4 GHz, so we'll use a conversion
296         // to picoseconds to compute the tv_nsecs part in clock_gettime
297         hires_frequency = li_frequency.QuadPart;
298         hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
299         usbi_dbg("hires timer frequency: %"PRIu64" Hz", hires_frequency);
300 #endif
301 }
302
303 /* Windows version detection */
304 static BOOL is_x64(void)
305 {
306         BOOL ret = FALSE;
307
308         // Detect if we're running a 32 or 64 bit system
309         if (sizeof(uintptr_t) < 8) {
310                 IsWow64Process(GetCurrentProcess(), &ret);
311         } else {
312                 ret = TRUE;
313         }
314
315         return ret;
316 }
317
318 static enum windows_version get_windows_version(void)
319 {
320         enum windows_version winver;
321         OSVERSIONINFOEXA vi, vi2;
322         unsigned major, minor, version;
323         ULONGLONG major_equal, minor_equal;
324         const char *w, *arch;
325         bool ws;
326
327         memset(&vi, 0, sizeof(vi));
328         vi.dwOSVersionInfoSize = sizeof(vi);
329         if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
330                 memset(&vi, 0, sizeof(vi));
331                 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
332                 if (!GetVersionExA((OSVERSIONINFOA *)&vi))
333                         return WINDOWS_UNDEFINED;
334         }
335
336         if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
337                 return WINDOWS_UNDEFINED;
338
339         if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
340                 // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
341                 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
342
343                 major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
344                 for (major = vi.dwMajorVersion; major <= 9; major++) {
345                         memset(&vi2, 0, sizeof(vi2));
346                         vi2.dwOSVersionInfoSize = sizeof(vi2);
347                         vi2.dwMajorVersion = major;
348                         if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
349                                 continue;
350
351                         if (vi.dwMajorVersion < major) {
352                                 vi.dwMajorVersion = major;
353                                 vi.dwMinorVersion = 0;
354                         }
355
356                         minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
357                         for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
358                                 memset(&vi2, 0, sizeof(vi2));
359                                 vi2.dwOSVersionInfoSize = sizeof(vi2);
360                                 vi2.dwMinorVersion = minor;
361                                 if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
362                                         continue;
363
364                                 vi.dwMinorVersion = minor;
365                                 break;
366                         }
367
368                         break;
369                 }
370         }
371
372         if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
373                 return WINDOWS_UNDEFINED;
374
375         ws = (vi.wProductType <= VER_NT_WORKSTATION);
376         version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
377         switch (version) {
378         case 0x50: winver = WINDOWS_2000;  w = "2000"; break;
379         case 0x51: winver = WINDOWS_XP;    w = "XP";   break;
380         case 0x52: winver = WINDOWS_2003;  w = "2003"; break;
381         case 0x60: winver = WINDOWS_VISTA; w = (ws ? "Vista" : "2008");  break;
382         case 0x61: winver = WINDOWS_7;     w = (ws ? "7" : "2008_R2");   break;
383         case 0x62: winver = WINDOWS_8;     w = (ws ? "8" : "2012");      break;
384         case 0x63: winver = WINDOWS_8_1;   w = (ws ? "8.1" : "2012_R2"); break;
385         case 0x64: // Early Windows 10 Insider Previews and Windows Server 2017 Technical Preview 1 used version 6.4
386         case 0xA0: winver = WINDOWS_10;    w = (ws ? "10" : "2016");     break;
387         default:
388                 if (version < 0x50)
389                         return WINDOWS_UNDEFINED;
390                 winver = WINDOWS_11_OR_LATER;
391                 w = "11 or later";
392         }
393
394         arch = is_x64() ? "64-bit" : "32-bit";
395
396         if (vi.wServicePackMinor)
397                 usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
398         else if (vi.wServicePackMajor)
399                 usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
400         else
401                 usbi_dbg("Windows %s %s", w, arch);
402
403         return winver;
404 }
405
406 static unsigned __stdcall windows_iocp_thread(void *arg)
407 {
408         struct libusb_context *ctx = arg;
409         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
410         HANDLE iocp = priv->completion_port;
411         DWORD num_bytes;
412         ULONG_PTR completion_key;
413         OVERLAPPED *overlapped;
414         struct windows_transfer_priv *transfer_priv;
415         struct usbi_transfer *itransfer;
416
417         usbi_dbg("I/O completion thread started");
418
419         while (true) {
420                 overlapped = NULL;
421                 if (!GetQueuedCompletionStatus(iocp, &num_bytes, &completion_key, &overlapped, INFINITE) && (overlapped == NULL)) {
422                         usbi_err(ctx, "GetQueuedCompletionStatus failed: %s", windows_error_str(0));
423                         break;
424                 }
425
426                 if (overlapped == NULL) {
427                         // Signal to quit
428                         if (completion_key != (ULONG_PTR)ctx)
429                                 usbi_err(ctx, "program assertion failed - overlapped is NULL");
430                         break;
431                 }
432
433                 transfer_priv = container_of(overlapped, struct windows_transfer_priv, overlapped);
434                 itransfer = (struct usbi_transfer *)((unsigned char *)transfer_priv + PTR_ALIGN(sizeof(*transfer_priv)));
435                 usbi_dbg("transfer %p completed, length %lu",
436                          USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(num_bytes));
437                 usbi_signal_transfer_completion(itransfer);
438         }
439
440         usbi_dbg("I/O completion thread exiting");
441
442         return 0;
443 }
444
445 static int windows_init(struct libusb_context *ctx)
446 {
447         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
448         char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
449         HANDLE mutex;
450         bool winusb_backend_init = false;
451         int r;
452
453         sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
454         mutex = CreateMutexA(NULL, FALSE, mutex_name);
455         if (mutex == NULL) {
456                 usbi_err(ctx, "could not create mutex: %s", windows_error_str(0));
457                 return LIBUSB_ERROR_NO_MEM;
458         }
459
460         // A successful wait gives this thread ownership of the mutex
461         // => any concurrent wait stalls until the mutex is released
462         if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
463                 usbi_err(ctx, "failure to access mutex: %s", windows_error_str(0));
464                 CloseHandle(mutex);
465                 return LIBUSB_ERROR_NO_MEM;
466         }
467
468         // NB: concurrent usage supposes that init calls are equally balanced with
469         // exit calls. If init is called more than exit, we will not exit properly
470         if (++init_count == 1) { // First init?
471                 windows_version = get_windows_version();
472                 if (windows_version == WINDOWS_UNDEFINED) {
473                         usbi_err(ctx, "failed to detect Windows version");
474                         r = LIBUSB_ERROR_NOT_SUPPORTED;
475                         goto init_exit;
476                 } else if (windows_version < WINDOWS_VISTA) {
477                         usbi_err(ctx, "Windows version is too old");
478                         r = LIBUSB_ERROR_NOT_SUPPORTED;
479                         goto init_exit;
480                 }
481
482                 windows_init_clock();
483
484                 if (!htab_create(ctx)) {
485                         r = LIBUSB_ERROR_NO_MEM;
486                         goto init_exit;
487                 }
488
489                 r = winusb_backend.init(ctx);
490                 if (r != LIBUSB_SUCCESS)
491                         goto init_exit;
492                 winusb_backend_init = true;
493
494                 r = usbdk_backend.init(ctx);
495                 if (r == LIBUSB_SUCCESS) {
496                         usbi_dbg("UsbDk backend is available");
497                         usbdk_available = true;
498                 } else {
499                         usbi_info(ctx, "UsbDk backend is not available");
500                         // Do not report this as an error
501                 }
502         }
503
504         // By default, new contexts will use the WinUSB backend
505         priv->backend = &winusb_backend;
506
507         r = LIBUSB_ERROR_NO_MEM;
508
509         // Use an I/O completion port to manage all transfers for this context
510         priv->completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
511         if (priv->completion_port == NULL) {
512                 usbi_err(ctx, "failed to create I/O completion port: %s", windows_error_str(0));
513                 goto init_exit;
514         }
515
516         // And a dedicated thread to wait for I/O completions
517         priv->completion_port_thread = (HANDLE)_beginthreadex(NULL, 0, windows_iocp_thread, ctx, 0, NULL);
518         if (priv->completion_port_thread == NULL) {
519                 usbi_err(ctx, "failed to create I/O completion port thread");
520                 CloseHandle(priv->completion_port);
521                 goto init_exit;
522         }
523
524         r = LIBUSB_SUCCESS;
525
526 init_exit: // Holds semaphore here
527         if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
528                 if (usbdk_available) {
529                         usbdk_backend.exit(ctx);
530                         usbdk_available = false;
531                 }
532                 if (winusb_backend_init)
533                         winusb_backend.exit(ctx);
534                 htab_destroy();
535                 --init_count;
536         }
537
538         ReleaseMutex(mutex);
539         CloseHandle(mutex);
540         return r;
541 }
542
543 static void windows_exit(struct libusb_context *ctx)
544 {
545         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
546         char mutex_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
547         HANDLE mutex;
548
549         sprintf(mutex_name, "libusb_init%08lX", ULONG_CAST(GetCurrentProcessId() & 0xFFFFFFFFU));
550         mutex = CreateMutexA(NULL, FALSE, mutex_name);
551         if (mutex == NULL)
552                 return;
553
554         // A successful wait gives this thread ownership of the mutex
555         // => any concurrent wait stalls until the mutex is released
556         if (WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0) {
557                 usbi_err(ctx, "failed to access mutex: %s", windows_error_str(0));
558                 CloseHandle(mutex);
559                 return;
560         }
561
562         // A NULL completion status will indicate to the thread that it is time to exit
563         if (!PostQueuedCompletionStatus(priv->completion_port, 0, (ULONG_PTR)ctx, NULL))
564                 usbi_err(ctx, "failed to post I/O completion: %s", windows_error_str(0));
565
566         if (WaitForSingleObject(priv->completion_port_thread, INFINITE) == WAIT_FAILED)
567                 usbi_err(ctx, "failed to wait for I/O completion port thread: %s", windows_error_str(0));
568
569         CloseHandle(priv->completion_port_thread);
570         CloseHandle(priv->completion_port);
571
572         // Only works if exits and inits are balanced exactly
573         if (--init_count == 0) { // Last exit
574                 if (usbdk_available) {
575                         usbdk_backend.exit(ctx);
576                         usbdk_available = false;
577                 }
578                 winusb_backend.exit(ctx);
579                 htab_destroy();
580         }
581
582         ReleaseMutex(mutex);
583         CloseHandle(mutex);
584 }
585
586 static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
587 {
588         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
589
590         UNUSED(ap);
591
592         switch ((int)option) {
593         case LIBUSB_OPTION_USE_USBDK:
594                 if (usbdk_available) {
595                         usbi_dbg("switching context %p to use UsbDk backend", ctx);
596                         priv->backend = &usbdk_backend;
597                 } else {
598                         usbi_err(ctx, "UsbDk backend not available");
599                         return LIBUSB_ERROR_NOT_FOUND;
600                 }
601                 return LIBUSB_SUCCESS;
602         default:
603                 return LIBUSB_ERROR_NOT_SUPPORTED;
604         }
605 }
606
607 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
608 {
609         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
610         return priv->backend->get_device_list(ctx, discdevs);
611 }
612
613 static int windows_open(struct libusb_device_handle *dev_handle)
614 {
615         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
616         return priv->backend->open(dev_handle);
617 }
618
619 static void windows_close(struct libusb_device_handle *dev_handle)
620 {
621         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
622         priv->backend->close(dev_handle);
623 }
624
625 static int windows_get_active_config_descriptor(struct libusb_device *dev,
626         void *buffer, size_t len)
627 {
628         struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
629         return priv->backend->get_active_config_descriptor(dev, buffer, len);
630 }
631
632 static int windows_get_config_descriptor(struct libusb_device *dev,
633         uint8_t config_index, void *buffer, size_t len)
634 {
635         struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
636         return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
637 }
638
639 static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
640         uint8_t bConfigurationValue, void **buffer)
641 {
642         struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
643         return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
644 }
645
646 static int windows_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config)
647 {
648         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
649         return priv->backend->get_configuration(dev_handle, config);
650 }
651
652 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
653 {
654         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
655         if (config == -1)
656                 config = 0;
657         return priv->backend->set_configuration(dev_handle, (uint8_t)config);
658 }
659
660 static int windows_claim_interface(struct libusb_device_handle *dev_handle, uint8_t interface_number)
661 {
662         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
663         return priv->backend->claim_interface(dev_handle, interface_number);
664 }
665
666 static int windows_release_interface(struct libusb_device_handle *dev_handle, uint8_t interface_number)
667 {
668         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
669         return priv->backend->release_interface(dev_handle, interface_number);
670 }
671
672 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
673         uint8_t interface_number, uint8_t altsetting)
674 {
675         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
676         return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
677 }
678
679 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
680 {
681         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
682         return priv->backend->clear_halt(dev_handle, endpoint);
683 }
684
685 static int windows_reset_device(struct libusb_device_handle *dev_handle)
686 {
687         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
688         return priv->backend->reset_device(dev_handle);
689 }
690
691 static void windows_destroy_device(struct libusb_device *dev)
692 {
693         struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
694         priv->backend->destroy_device(dev);
695 }
696
697 static int windows_submit_transfer(struct usbi_transfer *itransfer)
698 {
699         struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
700         struct libusb_context *ctx = TRANSFER_CTX(transfer);
701         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
702         struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
703         int r;
704
705         switch (transfer->type) {
706         case LIBUSB_TRANSFER_TYPE_CONTROL:
707         case LIBUSB_TRANSFER_TYPE_BULK:
708         case LIBUSB_TRANSFER_TYPE_INTERRUPT:
709         case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
710                 break;
711         case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
712                 usbi_warn(ctx, "bulk stream transfers are not yet supported on this platform");
713                 return LIBUSB_ERROR_NOT_SUPPORTED;
714         default:
715                 usbi_err(ctx, "unknown endpoint type %d", transfer->type);
716                 return LIBUSB_ERROR_INVALID_PARAM;
717         }
718
719         if (transfer_priv->handle != NULL) {
720                 usbi_err(ctx, "program assertion failed - transfer HANDLE is not NULL");
721                 transfer_priv->handle = NULL;
722         }
723
724         r = priv->backend->submit_transfer(itransfer);
725         if (r != LIBUSB_SUCCESS) {
726                 // Always call the backend's clear_transfer_priv() function on failure
727                 priv->backend->clear_transfer_priv(itransfer);
728                 transfer_priv->handle = NULL;
729                 return r;
730         }
731
732         // The backend should set the HANDLE used for each submitted transfer
733         // by calling set_transfer_priv_handle()
734         if (transfer_priv->handle == NULL)
735                 usbi_err(ctx, "program assertion failed - transfer HANDLE is NULL after transfer was submitted");
736
737         return r;
738 }
739
740 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
741 {
742         struct windows_context_priv *priv = usbi_get_context_priv(ITRANSFER_CTX(itransfer));
743         struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
744
745         // Try CancelIoEx() on the transfer
746         // If that fails, fall back to the backend's cancel_transfer()
747         // function if it is available
748         if (CancelIoEx(transfer_priv->handle, &transfer_priv->overlapped))
749                 return LIBUSB_SUCCESS;
750         else if (GetLastError() == ERROR_NOT_FOUND)
751                 return LIBUSB_ERROR_NOT_FOUND;
752
753         if (priv->backend->cancel_transfer)
754                 return priv->backend->cancel_transfer(itransfer);
755
756         usbi_warn(ITRANSFER_CTX(itransfer), "cancellation not supported for this transfer's driver");
757         return LIBUSB_ERROR_NOT_SUPPORTED;
758 }
759
760 static int windows_handle_transfer_completion(struct usbi_transfer *itransfer)
761 {
762         struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
763         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
764         const struct windows_backend *backend = priv->backend;
765         struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
766         enum libusb_transfer_status status, istatus;
767         DWORD result, bytes_transferred;
768
769         if (GetOverlappedResult(transfer_priv->handle, &transfer_priv->overlapped, &bytes_transferred, FALSE))
770                 result = NO_ERROR;
771         else
772                 result = GetLastError();
773
774         usbi_dbg("handling transfer %p completion with errcode %lu, length %lu",
775                  USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(result), ULONG_CAST(bytes_transferred));
776
777         switch (result) {
778         case NO_ERROR:
779                 status = backend->copy_transfer_data(itransfer, bytes_transferred);
780                 break;
781         case ERROR_GEN_FAILURE:
782                 usbi_dbg("detected endpoint stall");
783                 status = LIBUSB_TRANSFER_STALL;
784                 break;
785         case ERROR_SEM_TIMEOUT:
786                 usbi_dbg("detected semaphore timeout");
787                 status = LIBUSB_TRANSFER_TIMED_OUT;
788                 break;
789         case ERROR_OPERATION_ABORTED:
790                 istatus = backend->copy_transfer_data(itransfer, bytes_transferred);
791                 if (istatus != LIBUSB_TRANSFER_COMPLETED)
792                         usbi_dbg("failed to copy partial data in aborted operation: %d", (int)istatus);
793
794                 usbi_dbg("detected operation aborted");
795                 status = LIBUSB_TRANSFER_CANCELLED;
796                 break;
797         case ERROR_FILE_NOT_FOUND:
798         case ERROR_DEVICE_NOT_CONNECTED:
799         case ERROR_NO_SUCH_DEVICE:
800                 usbi_dbg("detected device removed");
801                 status = LIBUSB_TRANSFER_NO_DEVICE;
802                 break;
803         default:
804                 usbi_err(ctx, "detected I/O error %lu: %s",
805                         ULONG_CAST(result), windows_error_str(result));
806                 status = LIBUSB_TRANSFER_ERROR;
807                 break;
808         }
809
810         transfer_priv->handle = NULL;
811
812         // Backend-specific cleanup
813         backend->clear_transfer_priv(itransfer);
814
815         if (status == LIBUSB_TRANSFER_CANCELLED)
816                 return usbi_handle_transfer_cancellation(itransfer);
817         else
818                 return usbi_handle_transfer_completion(itransfer, status);
819 }
820
821 #if !defined(HAVE_CLOCK_GETTIME)
822 int usbi_clock_gettime(int clk_id, struct timespec *tp)
823 {
824         LARGE_INTEGER hires_counter;
825 #if !defined(_MSC_VER) || (_MSC_VER < 1900)
826         FILETIME filetime;
827         ULARGE_INTEGER rtime;
828 #endif
829
830         switch (clk_id) {
831         case USBI_CLOCK_MONOTONIC:
832                 if (hires_frequency) {
833                         QueryPerformanceCounter(&hires_counter);
834                         tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
835                         tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) * hires_ticks_to_ps) / UINT64_C(1000));
836                         return 0;
837                 }
838                 // Return real-time if monotonic was not detected @ timer init
839                 // Fall through
840         case USBI_CLOCK_REALTIME:
841 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
842                 if (!timespec_get(tp, TIME_UTC)) {
843                         errno = EIO;
844                         return -1;
845                 }
846 #else
847                 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
848                 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
849                 // Note however that our resolution is bounded by the Windows system time
850                 // functions and is at best of the order of 1 ms (or, usually, worse)
851                 GetSystemTimeAsFileTime(&filetime);
852                 rtime.LowPart = filetime.dwLowDateTime;
853                 rtime.HighPart = filetime.dwHighDateTime;
854                 rtime.QuadPart -= EPOCH_TIME;
855                 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
856                 tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
857 #endif
858                 return 0;
859         default:
860                 errno = EINVAL;
861                 return -1;
862         }
863 }
864 #endif
865
866 // NB: MSVC6 does not support named initializers.
867 const struct usbi_os_backend usbi_backend = {
868         "Windows",
869         USBI_CAP_HAS_HID_ACCESS,
870         windows_init,
871         windows_exit,
872         windows_set_option,
873         windows_get_device_list,
874         NULL,   /* hotplug_poll */
875         NULL,   /* wrap_sys_device */
876         windows_open,
877         windows_close,
878         windows_get_active_config_descriptor,
879         windows_get_config_descriptor,
880         windows_get_config_descriptor_by_value,
881         windows_get_configuration,
882         windows_set_configuration,
883         windows_claim_interface,
884         windows_release_interface,
885         windows_set_interface_altsetting,
886         windows_clear_halt,
887         windows_reset_device,
888         NULL,   /* alloc_streams */
889         NULL,   /* free_streams */
890         NULL,   /* dev_mem_alloc */
891         NULL,   /* dev_mem_free */
892         NULL,   /* kernel_driver_active */
893         NULL,   /* detach_kernel_driver */
894         NULL,   /* attach_kernel_driver */
895         windows_destroy_device,
896         windows_submit_transfer,
897         windows_cancel_transfer,
898         NULL,   /* clear_transfer_priv */
899         NULL,   /* handle_events */
900         windows_handle_transfer_completion,
901         sizeof(struct windows_context_priv),
902         sizeof(union windows_device_priv),
903         sizeof(union windows_device_handle_priv),
904         sizeof(struct windows_transfer_priv),
905 };