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