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