core: Refactor initialization and how the default context is handled
[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 libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
297         struct windows_context_priv *priv = usbi_get_context_priv(TRANSFER_CTX(transfer));
298         struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
299         OVERLAPPED *overlapped = &transfer_priv->overlapped;
300
301         usbi_dbg("transfer %p, length %lu", transfer, ULONG_CAST(size));
302
303         overlapped->Internal = (ULONG_PTR)STATUS_SUCCESS;
304         overlapped->InternalHigh = (ULONG_PTR)size;
305
306         if (!PostQueuedCompletionStatus(priv->completion_port, (DWORD)size, (ULONG_PTR)transfer->dev_handle, overlapped))
307                 usbi_err(TRANSFER_CTX(transfer), "failed to post I/O completion: %s", windows_error_str(0));
308 }
309
310 /* Windows version detection */
311 static BOOL is_x64(void)
312 {
313         BOOL ret = FALSE;
314
315         // Detect if we're running a 32 or 64 bit system
316         if (sizeof(uintptr_t) < 8) {
317                 IsWow64Process(GetCurrentProcess(), &ret);
318         } else {
319                 ret = TRUE;
320         }
321
322         return ret;
323 }
324
325 static enum windows_version get_windows_version(void)
326 {
327         enum windows_version winver;
328         OSVERSIONINFOEXA vi, vi2;
329         unsigned major, minor, version;
330         ULONGLONG major_equal, minor_equal;
331         const char *w, *arch;
332         bool ws;
333
334         memset(&vi, 0, sizeof(vi));
335         vi.dwOSVersionInfoSize = sizeof(vi);
336         if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
337                 memset(&vi, 0, sizeof(vi));
338                 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
339                 if (!GetVersionExA((OSVERSIONINFOA *)&vi))
340                         return WINDOWS_UNDEFINED;
341         }
342
343         if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
344                 return WINDOWS_UNDEFINED;
345
346         if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
347                 // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
348                 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
349
350                 major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
351                 for (major = vi.dwMajorVersion; major <= 9; major++) {
352                         memset(&vi2, 0, sizeof(vi2));
353                         vi2.dwOSVersionInfoSize = sizeof(vi2);
354                         vi2.dwMajorVersion = major;
355                         if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
356                                 continue;
357
358                         if (vi.dwMajorVersion < major) {
359                                 vi.dwMajorVersion = major;
360                                 vi.dwMinorVersion = 0;
361                         }
362
363                         minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
364                         for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
365                                 memset(&vi2, 0, sizeof(vi2));
366                                 vi2.dwOSVersionInfoSize = sizeof(vi2);
367                                 vi2.dwMinorVersion = minor;
368                                 if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
369                                         continue;
370
371                                 vi.dwMinorVersion = minor;
372                                 break;
373                         }
374
375                         break;
376                 }
377         }
378
379         if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
380                 return WINDOWS_UNDEFINED;
381
382         ws = (vi.wProductType <= VER_NT_WORKSTATION);
383         version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
384         switch (version) {
385         case 0x50: winver = WINDOWS_2000;  w = "2000"; break;
386         case 0x51: winver = WINDOWS_XP;    w = "XP";   break;
387         case 0x52: winver = WINDOWS_2003;  w = "2003"; break;
388         case 0x60: winver = WINDOWS_VISTA; w = (ws ? "Vista" : "2008");  break;
389         case 0x61: winver = WINDOWS_7;     w = (ws ? "7" : "2008_R2");   break;
390         case 0x62: winver = WINDOWS_8;     w = (ws ? "8" : "2012");      break;
391         case 0x63: winver = WINDOWS_8_1;   w = (ws ? "8.1" : "2012_R2"); break;
392         case 0x64: // Early Windows 10 Insider Previews and Windows Server 2017 Technical Preview 1 used version 6.4
393         case 0xA0: winver = WINDOWS_10;    w = (ws ? "10" : "2016");     break;
394         default:
395                 if (version < 0x50)
396                         return WINDOWS_UNDEFINED;
397                 winver = WINDOWS_11_OR_LATER;
398                 w = "11 or later";
399         }
400
401         arch = is_x64() ? "64-bit" : "32-bit";
402
403         if (vi.wServicePackMinor)
404                 usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
405         else if (vi.wServicePackMajor)
406                 usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
407         else
408                 usbi_dbg("Windows %s %s", w, arch);
409
410         return winver;
411 }
412
413 static unsigned __stdcall windows_iocp_thread(void *arg)
414 {
415         struct libusb_context *ctx = arg;
416         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
417         HANDLE iocp = priv->completion_port;
418         DWORD num_bytes;
419         ULONG_PTR completion_key;
420         OVERLAPPED *overlapped;
421         struct libusb_device_handle *dev_handle;
422         struct windows_device_handle_priv *handle_priv;
423         struct windows_transfer_priv *transfer_priv;
424         struct usbi_transfer *itransfer;
425         bool found;
426
427         usbi_dbg("I/O completion thread started");
428
429         while (true) {
430                 overlapped = NULL;
431                 if (!GetQueuedCompletionStatus(iocp, &num_bytes, &completion_key, &overlapped, INFINITE) && (overlapped == NULL)) {
432                         usbi_err(ctx, "GetQueuedCompletionStatus failed: %s", windows_error_str(0));
433                         break;
434                 }
435
436                 if (overlapped == NULL) {
437                         // Signal to quit
438                         if (completion_key != (ULONG_PTR)ctx)
439                                 usbi_err(ctx, "program assertion failed - overlapped is NULL");
440                         break;
441                 }
442
443                 // Find the transfer associated with the OVERLAPPED that just completed.
444                 // If we cannot find a match, the I/O operation originated from outside of libusb
445                 // (e.g. within libusbK) and we need to ignore it.
446                 dev_handle = (struct libusb_device_handle *)completion_key;
447                 handle_priv = usbi_get_device_handle_priv(dev_handle);
448                 found = false;
449                 usbi_mutex_lock(&dev_handle->lock);
450                 list_for_each_entry(transfer_priv, &handle_priv->active_transfers, list, struct windows_transfer_priv) {
451                         if (overlapped == &transfer_priv->overlapped) {
452                                 // This OVERLAPPED belongs to us, remove the transfer from the device handle's list
453                                 list_del(&transfer_priv->list);
454                                 found = true;
455                                 break;
456                         }
457                 }
458                 usbi_mutex_unlock(&dev_handle->lock);
459
460                 if (!found) {
461                         usbi_dbg("ignoring overlapped %p for handle %p (device %u.%u)",
462                                 overlapped, dev_handle, dev_handle->dev->bus_number, dev_handle->dev->device_address);
463                         continue;
464                 }
465
466                 itransfer = (struct usbi_transfer *)((unsigned char *)transfer_priv + PTR_ALIGN(sizeof(*transfer_priv)));
467                 usbi_dbg("transfer %p completed, length %lu",
468                          USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(num_bytes));
469                 usbi_signal_transfer_completion(itransfer);
470         }
471
472         usbi_dbg("I/O completion thread exiting");
473
474         return 0;
475 }
476
477 static int windows_init(struct libusb_context *ctx)
478 {
479         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
480         bool winusb_backend_init = false;
481         int r;
482
483         // NB: concurrent usage supposes that init calls are equally balanced with
484         // exit calls. If init is called more than exit, we will not exit properly
485         if (++init_count == 1) { // First init?
486                 windows_version = get_windows_version();
487                 if (windows_version == WINDOWS_UNDEFINED) {
488                         usbi_err(ctx, "failed to detect Windows version");
489                         r = LIBUSB_ERROR_NOT_SUPPORTED;
490                         goto init_exit;
491                 } else if (windows_version < WINDOWS_VISTA) {
492                         usbi_err(ctx, "Windows version is too old");
493                         r = LIBUSB_ERROR_NOT_SUPPORTED;
494                         goto init_exit;
495                 }
496
497                 if (!htab_create(ctx)) {
498                         r = LIBUSB_ERROR_NO_MEM;
499                         goto init_exit;
500                 }
501
502                 r = winusb_backend.init(ctx);
503                 if (r != LIBUSB_SUCCESS)
504                         goto init_exit;
505                 winusb_backend_init = true;
506
507                 r = usbdk_backend.init(ctx);
508                 if (r == LIBUSB_SUCCESS) {
509                         usbi_dbg("UsbDk backend is available");
510                         usbdk_available = true;
511                 } else {
512                         usbi_info(ctx, "UsbDk backend is not available");
513                         // Do not report this as an error
514                 }
515         }
516
517         // By default, new contexts will use the WinUSB backend
518         priv->backend = &winusb_backend;
519
520         r = LIBUSB_ERROR_NO_MEM;
521
522         // Use an I/O completion port to manage all transfers for this context
523         priv->completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
524         if (priv->completion_port == NULL) {
525                 usbi_err(ctx, "failed to create I/O completion port: %s", windows_error_str(0));
526                 goto init_exit;
527         }
528
529         // And a dedicated thread to wait for I/O completions
530         priv->completion_port_thread = (HANDLE)_beginthreadex(NULL, 0, windows_iocp_thread, ctx, 0, NULL);
531         if (priv->completion_port_thread == NULL) {
532                 usbi_err(ctx, "failed to create I/O completion port thread");
533                 CloseHandle(priv->completion_port);
534                 goto init_exit;
535         }
536
537         r = LIBUSB_SUCCESS;
538
539 init_exit: // Holds semaphore here
540         if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
541                 if (usbdk_available) {
542                         usbdk_backend.exit(ctx);
543                         usbdk_available = false;
544                 }
545                 if (winusb_backend_init)
546                         winusb_backend.exit(ctx);
547                 htab_destroy();
548                 --init_count;
549         }
550
551         return r;
552 }
553
554 static void windows_exit(struct libusb_context *ctx)
555 {
556         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
557
558         // A NULL completion status will indicate to the thread that it is time to exit
559         if (!PostQueuedCompletionStatus(priv->completion_port, 0, (ULONG_PTR)ctx, NULL))
560                 usbi_err(ctx, "failed to post I/O completion: %s", windows_error_str(0));
561
562         if (WaitForSingleObject(priv->completion_port_thread, INFINITE) == WAIT_FAILED)
563                 usbi_err(ctx, "failed to wait for I/O completion port thread: %s", windows_error_str(0));
564
565         CloseHandle(priv->completion_port_thread);
566         CloseHandle(priv->completion_port);
567
568         // Only works if exits and inits are balanced exactly
569         if (--init_count == 0) { // Last exit
570                 if (usbdk_available) {
571                         usbdk_backend.exit(ctx);
572                         usbdk_available = false;
573                 }
574                 winusb_backend.exit(ctx);
575                 htab_destroy();
576         }
577 }
578
579 static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
580 {
581         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
582
583         UNUSED(ap);
584
585         if (option == LIBUSB_OPTION_USE_USBDK) {
586                 if (!usbdk_available) {
587                         usbi_err(ctx, "UsbDk backend not available");
588                         return LIBUSB_ERROR_NOT_FOUND;
589                 }
590                 usbi_dbg("switching context %p to use UsbDk backend", ctx);
591                 priv->backend = &usbdk_backend;
592                 return LIBUSB_SUCCESS;
593         }
594
595         return LIBUSB_ERROR_NOT_SUPPORTED;
596 }
597
598 static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
599 {
600         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
601         return priv->backend->get_device_list(ctx, discdevs);
602 }
603
604 static int windows_open(struct libusb_device_handle *dev_handle)
605 {
606         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
607         struct windows_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
608
609         list_init(&handle_priv->active_transfers);
610         return priv->backend->open(dev_handle);
611 }
612
613 static void windows_close(struct libusb_device_handle *dev_handle)
614 {
615         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
616         priv->backend->close(dev_handle);
617 }
618
619 static int windows_get_active_config_descriptor(struct libusb_device *dev,
620         void *buffer, size_t len)
621 {
622         struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
623         return priv->backend->get_active_config_descriptor(dev, buffer, len);
624 }
625
626 static int windows_get_config_descriptor(struct libusb_device *dev,
627         uint8_t config_index, void *buffer, size_t len)
628 {
629         struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
630         return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
631 }
632
633 static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
634         uint8_t bConfigurationValue, void **buffer)
635 {
636         struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
637         return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
638 }
639
640 static int windows_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config)
641 {
642         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
643         return priv->backend->get_configuration(dev_handle, config);
644 }
645
646 static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
647 {
648         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
649         if (config == -1)
650                 config = 0;
651         return priv->backend->set_configuration(dev_handle, (uint8_t)config);
652 }
653
654 static int windows_claim_interface(struct libusb_device_handle *dev_handle, uint8_t interface_number)
655 {
656         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
657         return priv->backend->claim_interface(dev_handle, interface_number);
658 }
659
660 static int windows_release_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->release_interface(dev_handle, interface_number);
664 }
665
666 static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
667         uint8_t interface_number, uint8_t altsetting)
668 {
669         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
670         return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
671 }
672
673 static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
674 {
675         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
676         return priv->backend->clear_halt(dev_handle, endpoint);
677 }
678
679 static int windows_reset_device(struct libusb_device_handle *dev_handle)
680 {
681         struct windows_context_priv *priv = usbi_get_context_priv(HANDLE_CTX(dev_handle));
682         return priv->backend->reset_device(dev_handle);
683 }
684
685 static void windows_destroy_device(struct libusb_device *dev)
686 {
687         struct windows_context_priv *priv = usbi_get_context_priv(DEVICE_CTX(dev));
688         priv->backend->destroy_device(dev);
689 }
690
691 static int windows_submit_transfer(struct usbi_transfer *itransfer)
692 {
693         struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
694         struct libusb_device_handle *dev_handle = transfer->dev_handle;
695         struct libusb_context *ctx = HANDLE_CTX(dev_handle);
696         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
697         struct windows_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
698         struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
699         int r;
700
701         switch (transfer->type) {
702         case LIBUSB_TRANSFER_TYPE_CONTROL:
703         case LIBUSB_TRANSFER_TYPE_BULK:
704         case LIBUSB_TRANSFER_TYPE_INTERRUPT:
705         case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
706                 break;
707         case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
708                 usbi_warn(ctx, "bulk stream transfers are not yet supported on this platform");
709                 return LIBUSB_ERROR_NOT_SUPPORTED;
710         default:
711                 usbi_err(ctx, "unknown endpoint type %d", transfer->type);
712                 return LIBUSB_ERROR_INVALID_PARAM;
713         }
714
715         if (transfer_priv->handle != NULL) {
716                 usbi_err(ctx, "program assertion failed - transfer HANDLE is not NULL");
717                 transfer_priv->handle = NULL;
718         }
719
720         // Add transfer to the device handle's list
721         usbi_mutex_lock(&dev_handle->lock);
722         list_add_tail(&transfer_priv->list, &handle_priv->active_transfers);
723         usbi_mutex_unlock(&dev_handle->lock);
724
725         r = priv->backend->submit_transfer(itransfer);
726         if (r != LIBUSB_SUCCESS) {
727                 // Remove the unsuccessful transfer from the device handle's list
728                 usbi_mutex_lock(&dev_handle->lock);
729                 list_del(&transfer_priv->list);
730                 usbi_mutex_unlock(&dev_handle->lock);
731
732                 // Always call the backend's clear_transfer_priv() function on failure
733                 priv->backend->clear_transfer_priv(itransfer);
734                 transfer_priv->handle = NULL;
735                 return r;
736         }
737
738         // The backend should set the HANDLE used for each submitted transfer
739         // by calling set_transfer_priv_handle()
740         if (transfer_priv->handle == NULL)
741                 usbi_err(ctx, "program assertion failed - transfer HANDLE is NULL after transfer was submitted");
742
743         return r;
744 }
745
746 static int windows_cancel_transfer(struct usbi_transfer *itransfer)
747 {
748         struct windows_context_priv *priv = usbi_get_context_priv(ITRANSFER_CTX(itransfer));
749         struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
750
751         // Try CancelIoEx() on the transfer
752         // If that fails, fall back to the backend's cancel_transfer()
753         // function if it is available
754         if (CancelIoEx(transfer_priv->handle, &transfer_priv->overlapped))
755                 return LIBUSB_SUCCESS;
756         else if (GetLastError() == ERROR_NOT_FOUND)
757                 return LIBUSB_ERROR_NOT_FOUND;
758
759         if (priv->backend->cancel_transfer)
760                 return priv->backend->cancel_transfer(itransfer);
761
762         usbi_warn(ITRANSFER_CTX(itransfer), "cancellation not supported for this transfer's driver");
763         return LIBUSB_ERROR_NOT_SUPPORTED;
764 }
765
766 static int windows_handle_transfer_completion(struct usbi_transfer *itransfer)
767 {
768         struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
769         struct windows_context_priv *priv = usbi_get_context_priv(ctx);
770         const struct windows_backend *backend = priv->backend;
771         struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
772         enum libusb_transfer_status status, istatus;
773         DWORD result, bytes_transferred;
774
775         if (GetOverlappedResult(transfer_priv->handle, &transfer_priv->overlapped, &bytes_transferred, FALSE))
776                 result = NO_ERROR;
777         else
778                 result = GetLastError();
779
780         usbi_dbg("handling transfer %p completion with errcode %lu, length %lu",
781                  USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(result), ULONG_CAST(bytes_transferred));
782
783         switch (result) {
784         case NO_ERROR:
785                 status = backend->copy_transfer_data(itransfer, bytes_transferred);
786                 break;
787         case ERROR_GEN_FAILURE:
788                 usbi_dbg("detected endpoint stall");
789                 status = LIBUSB_TRANSFER_STALL;
790                 break;
791         case ERROR_SEM_TIMEOUT:
792                 usbi_dbg("detected semaphore timeout");
793                 status = LIBUSB_TRANSFER_TIMED_OUT;
794                 break;
795         case ERROR_OPERATION_ABORTED:
796                 istatus = backend->copy_transfer_data(itransfer, bytes_transferred);
797                 if (istatus != LIBUSB_TRANSFER_COMPLETED)
798                         usbi_dbg("failed to copy partial data in aborted operation: %d", (int)istatus);
799
800                 usbi_dbg("detected operation aborted");
801                 status = LIBUSB_TRANSFER_CANCELLED;
802                 break;
803         case ERROR_FILE_NOT_FOUND:
804         case ERROR_DEVICE_NOT_CONNECTED:
805         case ERROR_NO_SUCH_DEVICE:
806                 usbi_dbg("detected device removed");
807                 status = LIBUSB_TRANSFER_NO_DEVICE;
808                 break;
809         default:
810                 usbi_err(ctx, "detected I/O error %lu: %s",
811                         ULONG_CAST(result), windows_error_str(result));
812                 status = LIBUSB_TRANSFER_ERROR;
813                 break;
814         }
815
816         transfer_priv->handle = NULL;
817
818         // Backend-specific cleanup
819         backend->clear_transfer_priv(itransfer);
820
821         if (status == LIBUSB_TRANSFER_CANCELLED)
822                 return usbi_handle_transfer_cancellation(itransfer);
823         else
824                 return usbi_handle_transfer_completion(itransfer, status);
825 }
826
827 void usbi_get_monotonic_time(struct timespec *tp)
828 {
829         static LONG hires_counter_init;
830         static uint64_t hires_ticks_to_ps;
831         static uint64_t hires_frequency;
832         LARGE_INTEGER hires_counter;
833
834         if (InterlockedExchange(&hires_counter_init, 1L) == 0L) {
835                 LARGE_INTEGER li_frequency;
836
837                 // Microsoft says that the QueryPerformanceFrequency() and
838                 // QueryPerformanceCounter() functions always succeed on XP and later
839                 QueryPerformanceFrequency(&li_frequency);
840
841                 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
842                 // to picoseconds to compute the tv_nsecs part
843                 hires_frequency = li_frequency.QuadPart;
844                 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
845         }
846
847         QueryPerformanceCounter(&hires_counter);
848         tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
849         tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) * hires_ticks_to_ps) / UINT64_C(1000));
850 }
851
852 // NB: MSVC6 does not support named initializers.
853 const struct usbi_os_backend usbi_backend = {
854         "Windows",
855         USBI_CAP_HAS_HID_ACCESS,
856         windows_init,
857         windows_exit,
858         windows_set_option,
859         windows_get_device_list,
860         NULL,   /* hotplug_poll */
861         NULL,   /* wrap_sys_device */
862         windows_open,
863         windows_close,
864         windows_get_active_config_descriptor,
865         windows_get_config_descriptor,
866         windows_get_config_descriptor_by_value,
867         windows_get_configuration,
868         windows_set_configuration,
869         windows_claim_interface,
870         windows_release_interface,
871         windows_set_interface_altsetting,
872         windows_clear_halt,
873         windows_reset_device,
874         NULL,   /* alloc_streams */
875         NULL,   /* free_streams */
876         NULL,   /* dev_mem_alloc */
877         NULL,   /* dev_mem_free */
878         NULL,   /* kernel_driver_active */
879         NULL,   /* detach_kernel_driver */
880         NULL,   /* attach_kernel_driver */
881         windows_destroy_device,
882         windows_submit_transfer,
883         windows_cancel_transfer,
884         NULL,   /* clear_transfer_priv */
885         NULL,   /* handle_events */
886         windows_handle_transfer_completion,
887         sizeof(struct windows_context_priv),
888         sizeof(union windows_device_priv),
889         sizeof(struct windows_device_handle_priv),
890         sizeof(struct windows_transfer_priv),
891 };