libusb 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -2
  3. data/Gemfile +2 -0
  4. data/History.md +12 -0
  5. data/README.md +25 -14
  6. data/Rakefile +64 -109
  7. data/appveyor.yml +23 -0
  8. data/ext/extconf.rb +10 -12
  9. data/ext/libusb_recipe.rb +29 -0
  10. data/lib/libusb/call.rb +14 -11
  11. data/lib/libusb/compat.rb +9 -9
  12. data/lib/libusb/context.rb +16 -1
  13. data/lib/libusb/dependencies.rb +7 -0
  14. data/lib/libusb/dev_handle.rb +13 -3
  15. data/lib/libusb/eventmachine.rb +4 -4
  16. data/lib/libusb/transfer.rb +71 -10
  17. data/lib/libusb/version_gem.rb +1 -1
  18. data/libusb.gemspec +7 -5
  19. data/ports/archives/libusb-1.0.21.tar.bz2 +0 -0
  20. data/test/test_libusb_bulk_stream_transfer.rb +1 -1
  21. data/test/test_libusb_descriptors.rb +4 -4
  22. data/test/test_libusb_event_machine.rb +7 -7
  23. data/test/test_libusb_hotplug.rb +15 -3
  24. data/test/test_libusb_iso_transfer.rb +1 -1
  25. data/test/test_libusb_mass_storage.rb +19 -19
  26. data/test/test_libusb_mass_storage2.rb +1 -1
  27. data/test/test_libusb_structs.rb +13 -0
  28. data/test/test_libusb_threads.rb +2 -2
  29. data/wireshark-usb-sniffer.png +0 -0
  30. metadata +32 -156
  31. checksums.yaml.gz.sig +0 -0
  32. data.tar.gz.sig +0 -0
  33. data/ext/libusb-1.0.20/AUTHORS +0 -89
  34. data/ext/libusb-1.0.20/COPYING +0 -504
  35. data/ext/libusb-1.0.20/ChangeLog +0 -227
  36. data/ext/libusb-1.0.20/INSTALL +0 -234
  37. data/ext/libusb-1.0.20/Makefile.am +0 -28
  38. data/ext/libusb-1.0.20/Makefile.in +0 -897
  39. data/ext/libusb-1.0.20/NEWS +0 -2
  40. data/ext/libusb-1.0.20/PORTING +0 -94
  41. data/ext/libusb-1.0.20/README +0 -29
  42. data/ext/libusb-1.0.20/TODO +0 -2
  43. data/ext/libusb-1.0.20/Xcode/common.xcconfig +0 -49
  44. data/ext/libusb-1.0.20/Xcode/config.h +0 -28
  45. data/ext/libusb-1.0.20/Xcode/debug.xcconfig +0 -29
  46. data/ext/libusb-1.0.20/Xcode/libusb.xcconfig +0 -21
  47. data/ext/libusb-1.0.20/Xcode/libusb.xcodeproj/project.pbxproj +0 -865
  48. data/ext/libusb-1.0.20/Xcode/libusb_debug.xcconfig +0 -21
  49. data/ext/libusb-1.0.20/Xcode/libusb_release.xcconfig +0 -21
  50. data/ext/libusb-1.0.20/Xcode/release.xcconfig +0 -30
  51. data/ext/libusb-1.0.20/aclocal.m4 +0 -1193
  52. data/ext/libusb-1.0.20/android/README +0 -114
  53. data/ext/libusb-1.0.20/android/config.h +0 -81
  54. data/ext/libusb-1.0.20/android/jni/Android.mk +0 -23
  55. data/ext/libusb-1.0.20/android/jni/Application.mk +0 -24
  56. data/ext/libusb-1.0.20/android/jni/examples.mk +0 -134
  57. data/ext/libusb-1.0.20/android/jni/libusb.mk +0 -54
  58. data/ext/libusb-1.0.20/android/jni/tests.mk +0 -56
  59. data/ext/libusb-1.0.20/compile +0 -347
  60. data/ext/libusb-1.0.20/config.guess +0 -1421
  61. data/ext/libusb-1.0.20/config.h.in +0 -155
  62. data/ext/libusb-1.0.20/config.sub +0 -1807
  63. data/ext/libusb-1.0.20/configure +0 -15466
  64. data/ext/libusb-1.0.20/configure.ac +0 -326
  65. data/ext/libusb-1.0.20/depcomp +0 -791
  66. data/ext/libusb-1.0.20/doc/Makefile.am +0 -9
  67. data/ext/libusb-1.0.20/doc/Makefile.in +0 -456
  68. data/ext/libusb-1.0.20/doc/doxygen.cfg.in +0 -2334
  69. data/ext/libusb-1.0.20/examples/Makefile.am +0 -19
  70. data/ext/libusb-1.0.20/examples/Makefile.in +0 -713
  71. data/ext/libusb-1.0.20/examples/dpfp.c +0 -506
  72. data/ext/libusb-1.0.20/examples/dpfp_threaded.c +0 -549
  73. data/ext/libusb-1.0.20/examples/ezusb.c +0 -831
  74. data/ext/libusb-1.0.20/examples/ezusb.h +0 -120
  75. data/ext/libusb-1.0.20/examples/fxload.c +0 -308
  76. data/ext/libusb-1.0.20/examples/getopt/getopt.c +0 -1060
  77. data/ext/libusb-1.0.20/examples/getopt/getopt.h +0 -180
  78. data/ext/libusb-1.0.20/examples/getopt/getopt1.c +0 -188
  79. data/ext/libusb-1.0.20/examples/hotplugtest.c +0 -122
  80. data/ext/libusb-1.0.20/examples/listdevs.c +0 -71
  81. data/ext/libusb-1.0.20/examples/sam3u_benchmark.c +0 -193
  82. data/ext/libusb-1.0.20/examples/xusb.c +0 -1130
  83. data/ext/libusb-1.0.20/install-sh +0 -501
  84. data/ext/libusb-1.0.20/libusb-1.0.pc.in +0 -11
  85. data/ext/libusb-1.0.20/libusb/Makefile.am +0 -90
  86. data/ext/libusb-1.0.20/libusb/Makefile.in +0 -1053
  87. data/ext/libusb-1.0.20/libusb/core.c +0 -2452
  88. data/ext/libusb-1.0.20/libusb/descriptor.c +0 -1201
  89. data/ext/libusb-1.0.20/libusb/hotplug.c +0 -344
  90. data/ext/libusb-1.0.20/libusb/hotplug.h +0 -90
  91. data/ext/libusb-1.0.20/libusb/io.c +0 -2760
  92. data/ext/libusb-1.0.20/libusb/libusb-1.0.def +0 -168
  93. data/ext/libusb-1.0.20/libusb/libusb-1.0.rc +0 -61
  94. data/ext/libusb-1.0.20/libusb/libusb.h +0 -1999
  95. data/ext/libusb-1.0.20/libusb/libusbi.h +0 -1102
  96. data/ext/libusb-1.0.20/libusb/os/darwin_usb.c +0 -1969
  97. data/ext/libusb-1.0.20/libusb/os/darwin_usb.h +0 -158
  98. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.am +0 -5
  99. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.in +0 -810
  100. data/ext/libusb-1.0.20/libusb/os/haiku/aclocal.m4 +0 -1193
  101. data/ext/libusb-1.0.20/libusb/os/haiku/compile +0 -347
  102. data/ext/libusb-1.0.20/libusb/os/haiku/config.guess +0 -1421
  103. data/ext/libusb-1.0.20/libusb/os/haiku/config.sub +0 -1807
  104. data/ext/libusb-1.0.20/libusb/os/haiku/configure +0 -17579
  105. data/ext/libusb-1.0.20/libusb/os/haiku/configure.ac +0 -8
  106. data/ext/libusb-1.0.20/libusb/os/haiku/depcomp +0 -791
  107. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_pollfs.cpp +0 -378
  108. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb.h +0 -112
  109. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_backend.cpp +0 -550
  110. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.cpp +0 -255
  111. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.h +0 -180
  112. data/ext/libusb-1.0.20/libusb/os/haiku/install-sh +0 -501
  113. data/ext/libusb-1.0.20/libusb/os/haiku/ltmain.sh +0 -9655
  114. data/ext/libusb-1.0.20/libusb/os/haiku/m4/libtool.m4 +0 -7992
  115. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltoptions.m4 +0 -384
  116. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltsugar.m4 +0 -123
  117. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltversion.m4 +0 -23
  118. data/ext/libusb-1.0.20/libusb/os/haiku/m4/lt~obsolete.m4 +0 -98
  119. data/ext/libusb-1.0.20/libusb/os/haiku/missing +0 -215
  120. data/ext/libusb-1.0.20/libusb/os/linux_netlink.c +0 -369
  121. data/ext/libusb-1.0.20/libusb/os/linux_udev.c +0 -306
  122. data/ext/libusb-1.0.20/libusb/os/linux_usbfs.c +0 -2692
  123. data/ext/libusb-1.0.20/libusb/os/linux_usbfs.h +0 -192
  124. data/ext/libusb-1.0.20/libusb/os/netbsd_usb.c +0 -674
  125. data/ext/libusb-1.0.20/libusb/os/openbsd_usb.c +0 -768
  126. data/ext/libusb-1.0.20/libusb/os/poll_posix.c +0 -53
  127. data/ext/libusb-1.0.20/libusb/os/poll_posix.h +0 -11
  128. data/ext/libusb-1.0.20/libusb/os/poll_windows.c +0 -728
  129. data/ext/libusb-1.0.20/libusb/os/poll_windows.h +0 -131
  130. data/ext/libusb-1.0.20/libusb/os/threads_posix.c +0 -82
  131. data/ext/libusb-1.0.20/libusb/os/threads_posix.h +0 -50
  132. data/ext/libusb-1.0.20/libusb/os/threads_windows.c +0 -214
  133. data/ext/libusb-1.0.20/libusb/os/threads_windows.h +0 -87
  134. data/ext/libusb-1.0.20/libusb/os/wince_usb.c +0 -869
  135. data/ext/libusb-1.0.20/libusb/os/wince_usb.h +0 -131
  136. data/ext/libusb-1.0.20/libusb/os/windows_common.h +0 -108
  137. data/ext/libusb-1.0.20/libusb/os/windows_usb.c +0 -4643
  138. data/ext/libusb-1.0.20/libusb/os/windows_usb.h +0 -973
  139. data/ext/libusb-1.0.20/libusb/strerror.c +0 -202
  140. data/ext/libusb-1.0.20/libusb/sync.c +0 -308
  141. data/ext/libusb-1.0.20/libusb/version.h +0 -18
  142. data/ext/libusb-1.0.20/libusb/version_nano.h +0 -1
  143. data/ext/libusb-1.0.20/ltmain.sh +0 -9655
  144. data/ext/libusb-1.0.20/m4/libtool.m4 +0 -7992
  145. data/ext/libusb-1.0.20/m4/ltoptions.m4 +0 -384
  146. data/ext/libusb-1.0.20/m4/ltsugar.m4 +0 -123
  147. data/ext/libusb-1.0.20/m4/ltversion.m4 +0 -23
  148. data/ext/libusb-1.0.20/m4/lt~obsolete.m4 +0 -98
  149. data/ext/libusb-1.0.20/missing +0 -215
  150. data/ext/libusb-1.0.20/tests/Makefile.am +0 -6
  151. data/ext/libusb-1.0.20/tests/Makefile.in +0 -596
  152. data/ext/libusb-1.0.20/tests/libusb_testlib.h +0 -107
  153. data/ext/libusb-1.0.20/tests/stress.c +0 -160
  154. data/ext/libusb-1.0.20/tests/testlib.c +0 -277
  155. metadata.gz.sig +0 -0
@@ -1,131 +0,0 @@
1
- /*
2
- * Windows CE backend for libusb 1.0
3
- * Copyright © 2011-2013 RealVNC Ltd.
4
- * Portions taken from Windows backend, which is
5
- * Copyright © 2009-2010 Pete Batard <pbatard@gmail.com>
6
- * With contributions from Michael Plante, Orin Eman et al.
7
- * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
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
- #pragma once
25
-
26
- #include "windows_common.h"
27
-
28
- #include <windows.h>
29
- #include "poll_windows.h"
30
-
31
- #define MAX_DEVICE_COUNT 256
32
-
33
- // This is a modified dump of the types in the ceusbkwrapper.h library header
34
- // with functions transformed into extern pointers.
35
- //
36
- // This backend dynamically loads ceusbkwrapper.dll and doesn't include
37
- // ceusbkwrapper.h directly to simplify the build process. The kernel
38
- // side wrapper driver is built using the platform image build tools,
39
- // which makes it difficult to reference directly from the libusb build
40
- // system.
41
- struct UKW_DEVICE_PRIV;
42
- typedef struct UKW_DEVICE_PRIV *UKW_DEVICE;
43
- typedef UKW_DEVICE *PUKW_DEVICE, *LPUKW_DEVICE;
44
-
45
- typedef struct {
46
- UINT8 bLength;
47
- UINT8 bDescriptorType;
48
- UINT16 bcdUSB;
49
- UINT8 bDeviceClass;
50
- UINT8 bDeviceSubClass;
51
- UINT8 bDeviceProtocol;
52
- UINT8 bMaxPacketSize0;
53
- UINT16 idVendor;
54
- UINT16 idProduct;
55
- UINT16 bcdDevice;
56
- UINT8 iManufacturer;
57
- UINT8 iProduct;
58
- UINT8 iSerialNumber;
59
- UINT8 bNumConfigurations;
60
- } UKW_DEVICE_DESCRIPTOR, *PUKW_DEVICE_DESCRIPTOR, *LPUKW_DEVICE_DESCRIPTOR;
61
-
62
- typedef struct {
63
- UINT8 bmRequestType;
64
- UINT8 bRequest;
65
- UINT16 wValue;
66
- UINT16 wIndex;
67
- UINT16 wLength;
68
- } UKW_CONTROL_HEADER, *PUKW_CONTROL_HEADER, *LPUKW_CONTROL_HEADER;
69
-
70
- // Collection of flags which can be used when issuing transfer requests
71
- /* Indicates that the transfer direction is 'in' */
72
- #define UKW_TF_IN_TRANSFER 0x00000001
73
- /* Indicates that the transfer direction is 'out' */
74
- #define UKW_TF_OUT_TRANSFER 0x00000000
75
- /* Specifies that the transfer should complete as soon as possible,
76
- * even if no OVERLAPPED structure has been provided. */
77
- #define UKW_TF_NO_WAIT 0x00000100
78
- /* Indicates that transfers shorter than the buffer are ok */
79
- #define UKW_TF_SHORT_TRANSFER_OK 0x00000200
80
- #define UKW_TF_SEND_TO_DEVICE 0x00010000
81
- #define UKW_TF_SEND_TO_INTERFACE 0x00020000
82
- #define UKW_TF_SEND_TO_ENDPOINT 0x00040000
83
- /* Don't block when waiting for memory allocations */
84
- #define UKW_TF_DONT_BLOCK_FOR_MEM 0x00080000
85
-
86
- /* Value to use when dealing with configuration values, such as UkwGetConfigDescriptor,
87
- * to specify the currently active configuration for the device. */
88
- #define UKW_ACTIVE_CONFIGURATION -1
89
-
90
- DLL_DECLARE(WINAPI, HANDLE, UkwOpenDriver, ());
91
- DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
92
- DLL_DECLARE(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
93
- DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
94
- DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
95
- DLL_DECLARE(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
96
- DLL_DECLARE(WINAPI, void, UkwCloseDriver, (HANDLE));
97
- DLL_DECLARE(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
98
- DLL_DECLARE(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
99
- DLL_DECLARE(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
100
- DLL_DECLARE(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
101
- DLL_DECLARE(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
102
- DLL_DECLARE(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
103
- DLL_DECLARE(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
104
- DLL_DECLARE(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
105
- DLL_DECLARE(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
106
- DLL_DECLARE(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
107
- DLL_DECLARE(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
108
- DLL_DECLARE(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
109
- DLL_DECLARE(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
110
- DLL_DECLARE(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
111
- DLL_DECLARE(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL));
112
-
113
- // Used to determine if an endpoint status really is halted on a failed transfer.
114
- #define STATUS_HALT_FLAG 0x1
115
-
116
- struct wince_device_priv {
117
- UKW_DEVICE dev;
118
- UKW_DEVICE_DESCRIPTOR desc;
119
- };
120
-
121
- struct wince_device_handle_priv {
122
- // This member isn't used, but only exists to avoid an empty structure
123
- // for private data for the device handle.
124
- int reserved;
125
- };
126
-
127
- struct wince_transfer_priv {
128
- struct winfd pollable_fd;
129
- uint8_t interface_number;
130
- };
131
-
@@ -1,108 +0,0 @@
1
- /*
2
- * Windows backend common header for libusb 1.0
3
- *
4
- * This file brings together header code common between
5
- * the desktop Windows and Windows CE backends.
6
- * Copyright © 2012-2013 RealVNC Ltd.
7
- * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
8
- * With contributions from Michael Plante, Orin Eman et al.
9
- * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
10
- * Major code testing contribution by Xiaofan Chen
11
- *
12
- * This library is free software; you can redistribute it and/or
13
- * modify it under the terms of the GNU Lesser General Public
14
- * License as published by the Free Software Foundation; either
15
- * version 2.1 of the License, or (at your option) any later version.
16
- *
17
- * This library is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
- * Lesser General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU Lesser General Public
23
- * License along with this library; if not, write to the Free Software
24
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25
- */
26
-
27
- #pragma once
28
-
29
- // Windows API default is uppercase - ugh!
30
- #if !defined(bool)
31
- #define bool BOOL
32
- #endif
33
- #if !defined(true)
34
- #define true TRUE
35
- #endif
36
- #if !defined(false)
37
- #define false FALSE
38
- #endif
39
-
40
- #define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
41
- #define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
42
- #define safe_min(a, b) MIN((size_t)(a), (size_t)(b))
43
- #define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
44
- ((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
45
- #define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
46
- #define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
47
- #define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
48
- #define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
49
- #define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
50
- #define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
51
- #define safe_strlen(str) ((str==NULL)?0:strlen(str))
52
- #define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0)
53
- #define safe_stprintf _sntprintf
54
- #define safe_tcslen(str) ((str==NULL)?0:_tcslen(str))
55
- #define safe_unref_device(dev) do {if (dev != NULL) {libusb_unref_device(dev); dev = NULL;}} while(0)
56
- #define wchar_to_utf8_ms(wstr, str, strlen) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, strlen, NULL, NULL)
57
- #ifndef ARRAYSIZE
58
- #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
59
- #endif
60
-
61
- #define ERR_BUFFER_SIZE 256
62
- #define TIMER_REQUEST_RETRY_MS 100
63
- #define MAX_TIMER_SEMAPHORES 128
64
-
65
-
66
- /*
67
- * API macros - from libusb-win32 1.x
68
- */
69
- #define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \
70
- typedef ret (api * __dll_##name##_t)args; \
71
- static __dll_##name##_t prefixname = NULL
72
-
73
- #ifndef _WIN32_WCE
74
- #define DLL_STRINGIFY(dll) #dll
75
- #define DLL_GET_MODULE_HANDLE(dll) GetModuleHandleA(DLL_STRINGIFY(dll))
76
- #define DLL_LOAD_LIBRARY(dll) LoadLibraryA(DLL_STRINGIFY(dll))
77
- #else
78
- #define DLL_STRINGIFY(dll) L#dll
79
- #define DLL_GET_MODULE_HANDLE(dll) GetModuleHandle(DLL_STRINGIFY(dll))
80
- #define DLL_LOAD_LIBRARY(dll) LoadLibrary(DLL_STRINGIFY(dll))
81
- #endif
82
-
83
- #define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
84
- do { \
85
- HMODULE h = DLL_GET_MODULE_HANDLE(dll); \
86
- if (!h) \
87
- h = DLL_LOAD_LIBRARY(dll); \
88
- if (!h) { \
89
- if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
90
- else { break; } \
91
- } \
92
- prefixname = (__dll_##name##_t)GetProcAddress(h, \
93
- DLL_STRINGIFY(name)); \
94
- if (prefixname) break; \
95
- prefixname = (__dll_##name##_t)GetProcAddress(h, \
96
- DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
97
- if (prefixname) break; \
98
- prefixname = (__dll_##name##_t)GetProcAddress(h, \
99
- DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
100
- if (prefixname) break; \
101
- if(ret_on_failure) \
102
- return LIBUSB_ERROR_NOT_FOUND; \
103
- } while(0)
104
-
105
- #define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args)
106
- #define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure)
107
- #define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args)
108
- #define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
@@ -1,4643 +0,0 @@
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 <windows.h>
28
- #include <setupapi.h>
29
- #include <ctype.h>
30
- #include <errno.h>
31
- #include <fcntl.h>
32
- #include <process.h>
33
- #include <stdio.h>
34
- #include <inttypes.h>
35
- #include <objbase.h>
36
- #include <winioctl.h>
37
-
38
- #include "libusbi.h"
39
- #include "poll_windows.h"
40
- #include "windows_usb.h"
41
-
42
- // The 2 macros below are used in conjunction with safe loops.
43
- #define LOOP_CHECK(fcall) { r=fcall; if (r != LIBUSB_SUCCESS) continue; }
44
- #define LOOP_BREAK(err) { r=err; continue; }
45
-
46
- // Helper prototypes
47
- static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian);
48
- static int windows_clock_gettime(int clk_id, struct timespec *tp);
49
- unsigned __stdcall windows_clock_gettime_threaded(void* param);
50
- // Common calls
51
- static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
52
-
53
- // WinUSB-like API prototypes
54
- static int winusbx_init(int sub_api, struct libusb_context *ctx);
55
- static int winusbx_exit(int sub_api);
56
- static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle);
57
- static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle);
58
- static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface);
59
- static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
60
- static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
61
- static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
62
- static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
63
- static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
64
- static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
65
- static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
66
- static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer);
67
- static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
68
- static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
69
- // HID API prototypes
70
- static int hid_init(int sub_api, struct libusb_context *ctx);
71
- static int hid_exit(int sub_api);
72
- static int hid_open(int sub_api, struct libusb_device_handle *dev_handle);
73
- static void hid_close(int sub_api, struct libusb_device_handle *dev_handle);
74
- static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
75
- static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
76
- static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
77
- static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
78
- static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
79
- static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
80
- static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
81
- static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
82
- static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
83
- // Composite API prototypes
84
- static int composite_init(int sub_api, struct libusb_context *ctx);
85
- static int composite_exit(int sub_api);
86
- static int composite_open(int sub_api, struct libusb_device_handle *dev_handle);
87
- static void composite_close(int sub_api, struct libusb_device_handle *dev_handle);
88
- static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
89
- static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
90
- static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
91
- static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
92
- static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
93
- static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
94
- static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
95
- static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
96
- static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer);
97
- static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
98
- static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
99
-
100
-
101
- // Global variables
102
- uint64_t hires_frequency, hires_ticks_to_ps;
103
- const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
104
- int windows_version = WINDOWS_UNDEFINED;
105
- static char windows_version_str[128] = "Windows Undefined";
106
- // Concurrency
107
- static int concurrent_usage = -1;
108
- usbi_mutex_t autoclaim_lock;
109
- // Timer thread
110
- HANDLE timer_thread = NULL;
111
- DWORD timer_thread_id = 0;
112
- // API globals
113
- #define CHECK_WINUSBX_AVAILABLE(sub_api) do { if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; \
114
- if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0)
115
- static struct winusb_interface WinUSBX[SUB_API_MAX];
116
- const char* sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES;
117
- bool api_hid_available = false;
118
- #define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0)
119
-
120
- static inline BOOLEAN guid_eq(const GUID *guid1, const GUID *guid2) {
121
- if ((guid1 != NULL) && (guid2 != NULL)) {
122
- return (memcmp(guid1, guid2, sizeof(GUID)) == 0);
123
- }
124
- return false;
125
- }
126
-
127
- #if defined(ENABLE_LOGGING)
128
- static char* guid_to_string(const GUID* guid)
129
- {
130
- static char guid_string[MAX_GUID_STRING_LENGTH];
131
-
132
- if (guid == NULL) return NULL;
133
- sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
134
- (unsigned int)guid->Data1, guid->Data2, guid->Data3,
135
- guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
136
- guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
137
- return guid_string;
138
- }
139
- #endif
140
-
141
- /*
142
- * Converts a windows error to human readable string
143
- * uses retval as errorcode, or, if 0, use GetLastError()
144
- */
145
- #if defined(ENABLE_LOGGING)
146
- static char *windows_error_str(uint32_t retval)
147
- {
148
- static char err_string[ERR_BUFFER_SIZE];
149
-
150
- DWORD size;
151
- ssize_t i;
152
- uint32_t error_code, format_error;
153
-
154
- error_code = retval?retval:GetLastError();
155
-
156
- safe_sprintf(err_string, ERR_BUFFER_SIZE, "[%u] ", error_code);
157
-
158
- // Translate codes returned by SetupAPI. The ones we are dealing with are either
159
- // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
160
- // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
161
- switch (error_code & 0xE0000000) {
162
- case 0:
163
- error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
164
- break;
165
- case 0xE0000000:
166
- error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
167
- break;
168
- default:
169
- break;
170
- }
171
-
172
- size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
173
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
174
- ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
175
- if (size == 0) {
176
- format_error = GetLastError();
177
- if (format_error)
178
- safe_sprintf(err_string, ERR_BUFFER_SIZE,
179
- "Windows error code %u (FormatMessage error code %u)", error_code, format_error);
180
- else
181
- safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
182
- } else {
183
- // Remove CR/LF terminators
184
- for (i=safe_strlen(err_string)-1; (i>=0) && ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
185
- err_string[i] = 0;
186
- }
187
- }
188
- return err_string;
189
- }
190
- #endif
191
-
192
- /*
193
- * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes.
194
- * Return an allocated sanitized string or NULL on error.
195
- */
196
- static char* sanitize_path(const char* path)
197
- {
198
- const char root_prefix[] = "\\\\.\\";
199
- size_t j, size, root_size;
200
- char* ret_path = NULL;
201
- size_t add_root = 0;
202
-
203
- if (path == NULL)
204
- return NULL;
205
-
206
- size = safe_strlen(path)+1;
207
- root_size = sizeof(root_prefix)-1;
208
-
209
- // Microsoft indiscriminately uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
210
- if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
211
- ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
212
- add_root = root_size;
213
- size += add_root;
214
- }
215
-
216
- if ((ret_path = (char*) calloc(size, 1)) == NULL)
217
- return NULL;
218
-
219
- safe_strcpy(&ret_path[add_root], size-add_root, path);
220
-
221
- // Ensure consistency with root prefix
222
- for (j=0; j<root_size; j++)
223
- ret_path[j] = root_prefix[j];
224
-
225
- // Same goes for '\' and '#' after the root prefix. Ensure '#' is used
226
- for(j=root_size; j<size; j++) {
227
- ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too
228
- if (ret_path[j] == '\\')
229
- ret_path[j] = '#';
230
- }
231
-
232
- return ret_path;
233
- }
234
-
235
- /*
236
- * Cfgmgr32, OLE32 and SetupAPI DLL functions
237
- */
238
- static int init_dlls(void)
239
- {
240
- DLL_LOAD(Cfgmgr32.dll, CM_Get_Parent, TRUE);
241
- DLL_LOAD(Cfgmgr32.dll, CM_Get_Child, TRUE);
242
- DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE);
243
- DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE);
244
- // Prefixed to avoid conflict with header files
245
- DLL_LOAD_PREFIXED(OLE32.dll, p, CLSIDFromString, TRUE);
246
- DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE);
247
- DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE);
248
- DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE);
249
- DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
250
- DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
251
- DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
252
- DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
253
- DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
254
- DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
255
- DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
256
- DLL_LOAD_PREFIXED(User32.dll, p, GetMessageA, TRUE);
257
- DLL_LOAD_PREFIXED(User32.dll, p, PeekMessageA, TRUE);
258
- DLL_LOAD_PREFIXED(User32.dll, p, PostThreadMessageA, TRUE);
259
- return LIBUSB_SUCCESS;
260
- }
261
-
262
- /*
263
- * enumerate interfaces for the whole USB class
264
- *
265
- * Parameters:
266
- * dev_info: a pointer to a dev_info list
267
- * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
268
- * usb_class: the generic USB class for which to retrieve interface details
269
- * index: zero based index of the interface in the device info list
270
- *
271
- * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
272
- * structure returned and call this function repeatedly using the same guid (with an
273
- * incremented index starting at zero) until all interfaces have been returned.
274
- */
275
- static bool get_devinfo_data(struct libusb_context *ctx,
276
- HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char* usb_class, unsigned _index)
277
- {
278
- if (_index <= 0) {
279
- *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
280
- if (*dev_info == INVALID_HANDLE_VALUE) {
281
- return false;
282
- }
283
- }
284
-
285
- dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
286
- if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
287
- if (GetLastError() != ERROR_NO_MORE_ITEMS) {
288
- usbi_err(ctx, "Could not obtain device info data for index %u: %s",
289
- _index, windows_error_str(0));
290
- }
291
- pSetupDiDestroyDeviceInfoList(*dev_info);
292
- *dev_info = INVALID_HANDLE_VALUE;
293
- return false;
294
- }
295
- return true;
296
- }
297
-
298
- /*
299
- * enumerate interfaces for a specific GUID
300
- *
301
- * Parameters:
302
- * dev_info: a pointer to a dev_info list
303
- * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
304
- * guid: the GUID for which to retrieve interface details
305
- * index: zero based index of the interface in the device info list
306
- *
307
- * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
308
- * structure returned and call this function repeatedly using the same guid (with an
309
- * incremented index starting at zero) until all interfaces have been returned.
310
- */
311
- static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details(struct libusb_context *ctx,
312
- HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index)
313
- {
314
- SP_DEVICE_INTERFACE_DATA dev_interface_data;
315
- SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
316
- DWORD size;
317
-
318
- if (_index <= 0) {
319
- *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
320
- }
321
-
322
- if (dev_info_data != NULL) {
323
- dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
324
- if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
325
- if (GetLastError() != ERROR_NO_MORE_ITEMS) {
326
- usbi_err(ctx, "Could not obtain device info data for index %u: %s",
327
- _index, windows_error_str(0));
328
- }
329
- pSetupDiDestroyDeviceInfoList(*dev_info);
330
- *dev_info = INVALID_HANDLE_VALUE;
331
- return NULL;
332
- }
333
- }
334
-
335
- dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
336
- if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
337
- if (GetLastError() != ERROR_NO_MORE_ITEMS) {
338
- usbi_err(ctx, "Could not obtain interface data for index %u: %s",
339
- _index, windows_error_str(0));
340
- }
341
- pSetupDiDestroyDeviceInfoList(*dev_info);
342
- *dev_info = INVALID_HANDLE_VALUE;
343
- return NULL;
344
- }
345
-
346
- // Read interface data (dummy + actual) to access the device path
347
- if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
348
- // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
349
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
350
- usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
351
- _index, windows_error_str(0));
352
- goto err_exit;
353
- }
354
- } else {
355
- usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
356
- goto err_exit;
357
- }
358
-
359
- if ((dev_interface_details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) calloc(size, 1)) == NULL) {
360
- usbi_err(ctx, "could not allocate interface data for index %u.", _index);
361
- goto err_exit;
362
- }
363
-
364
- dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
365
- if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
366
- dev_interface_details, size, &size, NULL)) {
367
- usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
368
- _index, windows_error_str(0));
369
- }
370
-
371
- return dev_interface_details;
372
-
373
- err_exit:
374
- pSetupDiDestroyDeviceInfoList(*dev_info);
375
- *dev_info = INVALID_HANDLE_VALUE;
376
- return NULL;
377
- }
378
-
379
- /* For libusb0 filter */
380
- static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
381
- HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index, char* filter_path){
382
- SP_DEVICE_INTERFACE_DATA dev_interface_data;
383
- SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
384
- DWORD size;
385
- if (_index <= 0) {
386
- *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
387
- }
388
- if (dev_info_data != NULL) {
389
- dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
390
- if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
391
- if (GetLastError() != ERROR_NO_MORE_ITEMS) {
392
- usbi_err(ctx, "Could not obtain device info data for index %u: %s",
393
- _index, windows_error_str(0));
394
- }
395
- pSetupDiDestroyDeviceInfoList(*dev_info);
396
- *dev_info = INVALID_HANDLE_VALUE;
397
- return NULL;
398
- }
399
- }
400
- dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
401
- if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) {
402
- if (GetLastError() != ERROR_NO_MORE_ITEMS) {
403
- usbi_err(ctx, "Could not obtain interface data for index %u: %s",
404
- _index, windows_error_str(0));
405
- }
406
- pSetupDiDestroyDeviceInfoList(*dev_info);
407
- *dev_info = INVALID_HANDLE_VALUE;
408
- return NULL;
409
- }
410
- // Read interface data (dummy + actual) to access the device path
411
- if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
412
- // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
413
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
414
- usbi_err(ctx, "could not access interface data (dummy) for index %u: %s",
415
- _index, windows_error_str(0));
416
- goto err_exit;
417
- }
418
- } else {
419
- usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong.");
420
- goto err_exit;
421
- }
422
- if ((dev_interface_details = malloc(size)) == NULL) {
423
- usbi_err(ctx, "could not allocate interface data for index %u.", _index);
424
- goto err_exit;
425
- }
426
- dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
427
- if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data,
428
- dev_interface_details, size, &size, NULL)) {
429
- usbi_err(ctx, "could not access interface data (actual) for index %u: %s",
430
- _index, windows_error_str(0));
431
- }
432
- // [trobinso] lookup the libusb0 symbolic index.
433
- if (dev_interface_details) {
434
- HKEY hkey_device_interface=pSetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ);
435
- if (hkey_device_interface != INVALID_HANDLE_VALUE) {
436
- DWORD libusb0_symboliclink_index=0;
437
- DWORD value_length=sizeof(DWORD);
438
- DWORD value_type=0;
439
- LONG status;
440
- status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type,
441
- (LPBYTE) &libusb0_symboliclink_index, &value_length);
442
- if (status == ERROR_SUCCESS) {
443
- if (libusb0_symboliclink_index < 256) {
444
- // libusb0.sys is connected to this device instance.
445
- // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
446
- safe_sprintf(filter_path, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index);
447
- usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
448
- } else {
449
- // libusb0.sys was connected to this device instance at one time; but not anymore.
450
- }
451
- }
452
- pRegCloseKey(hkey_device_interface);
453
- }
454
- }
455
- return dev_interface_details;
456
- err_exit:
457
- pSetupDiDestroyDeviceInfoList(*dev_info);
458
- *dev_info = INVALID_HANDLE_VALUE;
459
- return NULL;}
460
-
461
- /* Hash table functions - modified From glibc 2.3.2:
462
- [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
463
- [Knuth] The Art of Computer Programming, part 3 (6.4) */
464
- typedef struct htab_entry {
465
- unsigned long used;
466
- char* str;
467
- } htab_entry;
468
- htab_entry* htab_table = NULL;
469
- usbi_mutex_t htab_write_mutex = NULL;
470
- unsigned long htab_size, htab_filled;
471
-
472
- /* For the used double hash method the table size has to be a prime. To
473
- correct the user given table size we need a prime test. This trivial
474
- algorithm is adequate because the code is called only during init and
475
- the number is likely to be small */
476
- static int isprime(unsigned long number)
477
- {
478
- // no even number will be passed
479
- unsigned int divider = 3;
480
-
481
- while((divider * divider < number) && (number % divider != 0))
482
- divider += 2;
483
-
484
- return (number % divider != 0);
485
- }
486
-
487
- /* Before using the hash table we must allocate memory for it.
488
- We allocate one element more as the found prime number says.
489
- This is done for more effective indexing as explained in the
490
- comment for the hash function. */
491
- static int htab_create(struct libusb_context *ctx, unsigned long nel)
492
- {
493
- if (htab_table != NULL) {
494
- usbi_err(ctx, "hash table already allocated");
495
- }
496
-
497
- // Create a mutex
498
- usbi_mutex_init(&htab_write_mutex, NULL);
499
-
500
- // Change nel to the first prime number not smaller as nel.
501
- nel |= 1;
502
- while(!isprime(nel))
503
- nel += 2;
504
-
505
- htab_size = nel;
506
- usbi_dbg("using %d entries hash table", nel);
507
- htab_filled = 0;
508
-
509
- // allocate memory and zero out.
510
- htab_table = (htab_entry*) calloc(htab_size + 1, sizeof(htab_entry));
511
- if (htab_table == NULL) {
512
- usbi_err(ctx, "could not allocate space for hash table");
513
- return 0;
514
- }
515
-
516
- return 1;
517
- }
518
-
519
- /* After using the hash table it has to be destroyed. */
520
- static void htab_destroy(void)
521
- {
522
- size_t i;
523
- if (htab_table == NULL) {
524
- return;
525
- }
526
-
527
- for (i=0; i<htab_size; i++) {
528
- if (htab_table[i].used) {
529
- safe_free(htab_table[i].str);
530
- }
531
- }
532
- usbi_mutex_destroy(&htab_write_mutex);
533
- safe_free(htab_table);
534
- }
535
-
536
- /* This is the search function. It uses double hashing with open addressing.
537
- We use an trick to speed up the lookup. The table is created with one
538
- more element available. This enables us to use the index zero special.
539
- This index will never be used because we store the first hash index in
540
- the field used where zero means not used. Every other value means used.
541
- The used field can be used as a first fast comparison for equality of
542
- the stored and the parameter value. This helps to prevent unnecessary
543
- expensive calls of strcmp. */
544
- static unsigned long htab_hash(char* str)
545
- {
546
- unsigned long hval, hval2;
547
- unsigned long idx;
548
- unsigned long r = 5381;
549
- int c;
550
- char* sz = str;
551
-
552
- if (str == NULL)
553
- return 0;
554
-
555
- // Compute main hash value (algorithm suggested by Nokia)
556
- while ((c = *sz++) != 0)
557
- r = ((r << 5) + r) + c;
558
- if (r == 0)
559
- ++r;
560
-
561
- // compute table hash: simply take the modulus
562
- hval = r % htab_size;
563
- if (hval == 0)
564
- ++hval;
565
-
566
- // Try the first index
567
- idx = hval;
568
-
569
- if (htab_table[idx].used) {
570
- if ( (htab_table[idx].used == hval)
571
- && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
572
- // existing hash
573
- return idx;
574
- }
575
- usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
576
-
577
- // Second hash function, as suggested in [Knuth]
578
- hval2 = 1 + hval % (htab_size - 2);
579
-
580
- do {
581
- // Because size is prime this guarantees to step through all available indexes
582
- if (idx <= hval2) {
583
- idx = htab_size + idx - hval2;
584
- } else {
585
- idx -= hval2;
586
- }
587
-
588
- // If we visited all entries leave the loop unsuccessfully
589
- if (idx == hval) {
590
- break;
591
- }
592
-
593
- // If entry is found use it.
594
- if ( (htab_table[idx].used == hval)
595
- && (safe_strcmp(str, htab_table[idx].str) == 0) ) {
596
- return idx;
597
- }
598
- }
599
- while (htab_table[idx].used);
600
- }
601
-
602
- // Not found => New entry
603
-
604
- // If the table is full return an error
605
- if (htab_filled >= htab_size) {
606
- usbi_err(NULL, "hash table is full (%d entries)", htab_size);
607
- return 0;
608
- }
609
-
610
- // Concurrent threads might be storing the same entry at the same time
611
- // (eg. "simultaneous" enums from different threads) => use a mutex
612
- usbi_mutex_lock(&htab_write_mutex);
613
- // Just free any previously allocated string (which should be the same as
614
- // new one). The possibility of concurrent threads storing a collision
615
- // string (same hash, different string) at the same time is extremely low
616
- safe_free(htab_table[idx].str);
617
- htab_table[idx].used = hval;
618
- htab_table[idx].str = (char*) malloc(safe_strlen(str)+1);
619
- if (htab_table[idx].str == NULL) {
620
- usbi_err(NULL, "could not duplicate string for hash table");
621
- usbi_mutex_unlock(&htab_write_mutex);
622
- return 0;
623
- }
624
- memcpy(htab_table[idx].str, str, safe_strlen(str)+1);
625
- ++htab_filled;
626
- usbi_mutex_unlock(&htab_write_mutex);
627
-
628
- return idx;
629
- }
630
-
631
- /*
632
- * Returns the session ID of a device's nth level ancestor
633
- * If there's no device at the nth level, return 0
634
- */
635
- static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
636
- {
637
- DWORD parent_devinst;
638
- unsigned long session_id = 0;
639
- char* sanitized_path = NULL;
640
- char path[MAX_PATH_LENGTH];
641
- unsigned i;
642
-
643
- if (level < 1) return 0;
644
- for (i = 0; i<level; i++) {
645
- if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) {
646
- return 0;
647
- }
648
- devinst = parent_devinst;
649
- }
650
- if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
651
- return 0;
652
- }
653
- // TODO: (post hotplug): try without sanitizing
654
- sanitized_path = sanitize_path(path);
655
- if (sanitized_path == NULL) {
656
- return 0;
657
- }
658
- session_id = htab_hash(sanitized_path);
659
- safe_free(sanitized_path);
660
- return session_id;
661
- }
662
-
663
- /*
664
- * Determine which interface the given endpoint address belongs to
665
- */
666
- static int get_interface_by_endpoint(struct libusb_config_descriptor *conf_desc, uint8_t ep)
667
- {
668
- const struct libusb_interface *intf;
669
- const struct libusb_interface_descriptor *intf_desc;
670
- int i, j, k;
671
-
672
- for (i = 0; i < conf_desc->bNumInterfaces; i++) {
673
- intf = &conf_desc->interface[i];
674
- for (j = 0; j < intf->num_altsetting; j++) {
675
- intf_desc = &intf->altsetting[j];
676
- for (k = 0; k < intf_desc->bNumEndpoints; k++) {
677
- if (intf_desc->endpoint[k].bEndpointAddress == ep) {
678
- usbi_dbg("found endpoint %02X on interface %d", intf_desc->bInterfaceNumber);
679
- return intf_desc->bInterfaceNumber;
680
- }
681
- }
682
- }
683
- }
684
-
685
- usbi_dbg("endpoint %02X not found on any interface", ep);
686
- return LIBUSB_ERROR_NOT_FOUND;
687
- }
688
-
689
- /*
690
- * Populate the endpoints addresses of the device_priv interface helper structs
691
- */
692
- static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting)
693
- {
694
- int i, r;
695
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
696
- struct libusb_config_descriptor *conf_desc;
697
- const struct libusb_interface_descriptor *if_desc;
698
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
699
-
700
- r = libusb_get_config_descriptor(dev_handle->dev, (uint8_t)(priv->active_config-1), &conf_desc);
701
- if (r != LIBUSB_SUCCESS) {
702
- usbi_warn(ctx, "could not read config descriptor: error %d", r);
703
- return r;
704
- }
705
-
706
- if_desc = &conf_desc->interface[iface].altsetting[altsetting];
707
- safe_free(priv->usb_interface[iface].endpoint);
708
-
709
- if (if_desc->bNumEndpoints == 0) {
710
- usbi_dbg("no endpoints found for interface %d", iface);
711
- return LIBUSB_SUCCESS;
712
- }
713
-
714
- priv->usb_interface[iface].endpoint = (uint8_t*) malloc(if_desc->bNumEndpoints);
715
- if (priv->usb_interface[iface].endpoint == NULL) {
716
- return LIBUSB_ERROR_NO_MEM;
717
- }
718
-
719
- priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
720
- for (i=0; i<if_desc->bNumEndpoints; i++) {
721
- priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
722
- usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface);
723
- }
724
- libusb_free_config_descriptor(conf_desc);
725
-
726
- // Extra init may be required to configure endpoints
727
- return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
728
- }
729
-
730
- // Lookup for a match in the list of API driver names
731
- // return -1 if not found, driver match number otherwise
732
- static int get_sub_api(char* driver, int api){
733
- int i;
734
- const char sep_str[2] = {LIST_SEPARATOR, 0};
735
- char *tok, *tmp_str;
736
- size_t len = safe_strlen(driver);
737
-
738
- if (len == 0) return SUB_API_NOTSET;
739
- tmp_str = (char*) calloc(len+1, 1);
740
- if (tmp_str == NULL) return SUB_API_NOTSET;
741
- memcpy(tmp_str, driver, len+1);
742
- tok = strtok(tmp_str, sep_str);
743
- while (tok != NULL) {
744
- for (i=0; i<usb_api_backend[api].nb_driver_names; i++) {
745
- if (safe_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
746
- free(tmp_str);
747
- return i;
748
- }
749
- }
750
- tok = strtok(NULL, sep_str);
751
- }
752
- free (tmp_str);
753
- return SUB_API_NOTSET;
754
- }
755
-
756
- /*
757
- * auto-claiming and auto-release helper functions
758
- */
759
- static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
760
- {
761
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
762
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(
763
- transfer->dev_handle);
764
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
765
- int current_interface = *interface_number;
766
- int r = LIBUSB_SUCCESS;
767
-
768
- switch(api_type) {
769
- case USB_API_WINUSBX:
770
- case USB_API_HID:
771
- break;
772
- default:
773
- return LIBUSB_ERROR_INVALID_PARAM;
774
- }
775
-
776
- usbi_mutex_lock(&autoclaim_lock);
777
- if (current_interface < 0) // No serviceable interface was found
778
- {
779
- for (current_interface=0; current_interface<USB_MAXINTERFACES; current_interface++) {
780
- // Must claim an interface of the same API type
781
- if ( (priv->usb_interface[current_interface].apib->id == api_type)
782
- && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS) ) {
783
- usbi_dbg("auto-claimed interface %d for control request", current_interface);
784
- if (handle_priv->autoclaim_count[current_interface] != 0) {
785
- usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero");
786
- }
787
- handle_priv->autoclaim_count[current_interface]++;
788
- break;
789
- }
790
- }
791
- if (current_interface == USB_MAXINTERFACES) {
792
- usbi_err(ctx, "could not auto-claim any interface");
793
- r = LIBUSB_ERROR_NOT_FOUND;
794
- }
795
- } else {
796
- // If we have a valid interface that was autoclaimed, we must increment
797
- // its autoclaim count so that we can prevent an early release.
798
- if (handle_priv->autoclaim_count[current_interface] != 0) {
799
- handle_priv->autoclaim_count[current_interface]++;
800
- }
801
- }
802
- usbi_mutex_unlock(&autoclaim_lock);
803
-
804
- *interface_number = current_interface;
805
- return r;
806
-
807
- }
808
-
809
- static void auto_release(struct usbi_transfer *itransfer)
810
- {
811
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
812
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
813
- libusb_device_handle *dev_handle = transfer->dev_handle;
814
- struct windows_device_handle_priv* handle_priv = _device_handle_priv(dev_handle);
815
- int r;
816
-
817
- usbi_mutex_lock(&autoclaim_lock);
818
- if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
819
- handle_priv->autoclaim_count[transfer_priv->interface_number]--;
820
- if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
821
- r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
822
- if (r == LIBUSB_SUCCESS) {
823
- usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
824
- } else {
825
- usbi_dbg("failed to auto-release interface %d (%s)",
826
- transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
827
- }
828
- }
829
- }
830
- usbi_mutex_unlock(&autoclaim_lock);
831
- }
832
-
833
- /* Windows version dtection */
834
- static BOOL is_x64(void)
835
- {
836
- BOOL ret = FALSE;
837
- // Detect if we're running a 32 or 64 bit system
838
- if (sizeof(uintptr_t) < 8) {
839
- DLL_LOAD_PREFIXED(Kernel32.dll, p, IsWow64Process, FALSE);
840
- if (pIsWow64Process != NULL) {
841
- (*pIsWow64Process)(GetCurrentProcess(), &ret);
842
- }
843
- } else {
844
- ret = TRUE;
845
- }
846
- return ret;
847
- }
848
-
849
- static void get_windows_version(void)
850
- {
851
- OSVERSIONINFOEXA vi, vi2;
852
- const char* w = 0;
853
- const char* w64 = "32 bit";
854
- char* vptr;
855
- size_t vlen;
856
- unsigned major, minor;
857
- ULONGLONG major_equal, minor_equal;
858
- BOOL ws;
859
-
860
- memset(&vi, 0, sizeof(vi));
861
- vi.dwOSVersionInfoSize = sizeof(vi);
862
- if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
863
- memset(&vi, 0, sizeof(vi));
864
- vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
865
- if (!GetVersionExA((OSVERSIONINFOA *)&vi))
866
- return;
867
- }
868
-
869
- if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
870
-
871
- if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) {
872
- // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
873
- // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
874
-
875
- major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
876
- for (major = vi.dwMajorVersion; major <= 9; major++) {
877
- memset(&vi2, 0, sizeof(vi2));
878
- vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMajorVersion = major;
879
- if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
880
- continue;
881
- if (vi.dwMajorVersion < major) {
882
- vi.dwMajorVersion = major; vi.dwMinorVersion = 0;
883
- }
884
-
885
- minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
886
- for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
887
- memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2);
888
- vi2.dwMinorVersion = minor;
889
- if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
890
- continue;
891
- vi.dwMinorVersion = minor;
892
- break;
893
- }
894
-
895
- break;
896
- }
897
- }
898
-
899
- if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
900
- ws = (vi.wProductType <= VER_NT_WORKSTATION);
901
- windows_version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
902
- switch (windows_version) {
903
- case 0x50: w = "2000";
904
- break;
905
- case 0x51: w = "XP";
906
- break;
907
- case 0x52: w = ("2003");
908
- break;
909
- case 0x60: w = (ws?"Vista":"2008");
910
- break;
911
- case 0x61: w = (ws?"7":"2008_R2");
912
- break;
913
- case 0x62: w = (ws?"8":"2012");
914
- break;
915
- case 0x63: w = (ws?"8.1":"2012_R2");
916
- break;
917
- case 0x64: w = (ws?"10":"2015");
918
- break;
919
- default:
920
- if (windows_version < 0x50)
921
- windows_version = WINDOWS_UNSUPPORTED;
922
- else
923
- w = "11 or later";
924
- break;
925
- }
926
- }
927
- }
928
-
929
- if (is_x64())
930
- w64 = "64-bit";
931
-
932
- vptr = &windows_version_str[sizeof("Windows ") - 1];
933
- vlen = sizeof(windows_version_str) - sizeof("Windows ") - 1;
934
- if (!w)
935
- safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId==VER_PLATFORM_WIN32_NT?"NT":"??"),
936
- (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);
937
- else if (vi.wServicePackMinor)
938
- safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, w64);
939
- else if (vi.wServicePackMajor)
940
- safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64);
941
- else
942
- safe_sprintf(vptr, vlen, "%s %s", w, w64);
943
- }
944
-
945
- /*
946
- * init: libusb backend init function
947
- *
948
- * This function enumerates the HCDs (Host Controller Drivers) and populates our private HCD list
949
- * In our implementation, we equate Windows' "HCD" to libusb's "bus". Note that bus is zero indexed.
950
- * HCDs are not expected to change after init (might not hold true for hot pluggable USB PCI card?)
951
- */
952
- static int windows_init(struct libusb_context *ctx)
953
- {
954
- int i, r = LIBUSB_ERROR_OTHER;
955
- DWORD_PTR affinity, dummy;
956
- HANDLE event = NULL;
957
- HANDLE semaphore;
958
- LARGE_INTEGER li_frequency;
959
- char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
960
-
961
- sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
962
- semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
963
- if (semaphore == NULL) {
964
- usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
965
- return LIBUSB_ERROR_NO_MEM;
966
- }
967
-
968
- // A successful wait brings our semaphore count to 0 (unsignaled)
969
- // => any concurent wait stalls until the semaphore's release
970
- if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
971
- usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
972
- CloseHandle(semaphore);
973
- return LIBUSB_ERROR_NO_MEM;
974
- }
975
-
976
- // NB: concurrent usage supposes that init calls are equally balanced with
977
- // exit calls. If init is called more than exit, we will not exit properly
978
- if ( ++concurrent_usage == 0 ) { // First init?
979
- get_windows_version();
980
- usbi_dbg(windows_version_str);
981
- if (windows_version == WINDOWS_UNSUPPORTED) {
982
- usbi_err(ctx, "This version of Windows is NOT supported");
983
- r = LIBUSB_ERROR_NOT_SUPPORTED;
984
- goto init_exit;
985
- }
986
-
987
- // We need a lock for proper auto-release
988
- usbi_mutex_init(&autoclaim_lock, NULL);
989
-
990
- // Initialize pollable file descriptors
991
- init_polling();
992
-
993
- // Load DLL imports
994
- if (init_dlls() != LIBUSB_SUCCESS) {
995
- usbi_err(ctx, "could not resolve DLL functions");
996
- goto init_exit;
997
- }
998
-
999
- // Initialize the low level APIs (we don't care about errors at this stage)
1000
- for (i=0; i<USB_API_MAX; i++) {
1001
- usb_api_backend[i].init(SUB_API_NOTSET, ctx);
1002
- }
1003
-
1004
- if (QueryPerformanceFrequency(&li_frequency)) {
1005
- // The hires frequency can go as high as 4 GHz, so we'll use a conversion
1006
- // to picoseconds to compute the tv_nsecs part in clock_gettime
1007
- hires_frequency = li_frequency.QuadPart;
1008
- hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
1009
- usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
1010
-
1011
- // Because QueryPerformanceCounter might report different values when
1012
- // running on different cores, we create a separate thread for the timer
1013
- // calls, which we glue to the first available core always to prevent timing discrepancies.
1014
- if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) {
1015
- usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0));
1016
- goto init_exit;
1017
- }
1018
- // The process affinity mask is a bitmask where each set bit represents a core on
1019
- // which this process is allowed to run, so we find the first set bit
1020
- for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++);
1021
- affinity = (DWORD_PTR)(1 << i);
1022
-
1023
- usbi_dbg("timer thread will run on core #%d", i);
1024
-
1025
- r = LIBUSB_ERROR_NO_MEM;
1026
- event = CreateEvent(NULL, FALSE, FALSE, NULL);
1027
- if (event == NULL) {
1028
- usbi_err(ctx, "could not create event: %s", windows_error_str(0));
1029
- goto init_exit;
1030
- }
1031
- timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event,
1032
- 0, (unsigned int *)&timer_thread_id);
1033
- if (timer_thread == NULL) {
1034
- usbi_err(ctx, "unable to create timer thread - aborting");
1035
- goto init_exit;
1036
- }
1037
- if (!SetThreadAffinityMask(timer_thread, affinity)) {
1038
- usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise");
1039
- }
1040
-
1041
- // Wait for timer thread to init before continuing.
1042
- if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
1043
- usbi_err(ctx, "failed to wait for timer thread to become ready - aborting");
1044
- goto init_exit;
1045
- }
1046
- }
1047
- else {
1048
- usbi_dbg("no hires timer available on this platform");
1049
- hires_frequency = 0;
1050
- hires_ticks_to_ps = UINT64_C(0);
1051
- }
1052
-
1053
- // Create a hash table to store session ids. Second parameter is better if prime
1054
- htab_create(ctx, HTAB_SIZE);
1055
- }
1056
- // At this stage, either we went through full init successfully, or didn't need to
1057
- r = LIBUSB_SUCCESS;
1058
-
1059
- init_exit: // Holds semaphore here.
1060
- if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
1061
- if (timer_thread) {
1062
- // actually the signal to quit the thread.
1063
- if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0) ||
1064
- (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
1065
- usbi_warn(ctx, "could not wait for timer thread to quit");
1066
- TerminateThread(timer_thread, 1);
1067
- // shouldn't happen, but we're destroying
1068
- // all objects it might have held anyway.
1069
- }
1070
- CloseHandle(timer_thread);
1071
- timer_thread = NULL;
1072
- timer_thread_id = 0;
1073
- }
1074
- htab_destroy();
1075
- usbi_mutex_destroy(&autoclaim_lock);
1076
- }
1077
-
1078
- if (r != LIBUSB_SUCCESS)
1079
- --concurrent_usage; // Not expected to call libusb_exit if we failed.
1080
-
1081
- if (event)
1082
- CloseHandle(event);
1083
- ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1084
- CloseHandle(semaphore);
1085
- return r;
1086
- }
1087
-
1088
- /*
1089
- * HCD (root) hubs need to have their device descriptor manually populated
1090
- *
1091
- * Note that, like Microsoft does in the device manager, we populate the
1092
- * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device.
1093
- */
1094
- static int force_hcd_device_descriptor(struct libusb_device *dev)
1095
- {
1096
- struct windows_device_priv *parent_priv, *priv = _device_priv(dev);
1097
- struct libusb_context *ctx = DEVICE_CTX(dev);
1098
- int vid, pid;
1099
-
1100
- dev->num_configurations = 1;
1101
- priv->dev_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
1102
- priv->dev_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
1103
- priv->dev_descriptor.bNumConfigurations = 1;
1104
- priv->active_config = 1;
1105
-
1106
- if (priv->parent_dev == NULL) {
1107
- usbi_err(ctx, "program assertion failed - HCD hub has no parent");
1108
- return LIBUSB_ERROR_NO_DEVICE;
1109
- }
1110
- parent_priv = _device_priv(priv->parent_dev);
1111
- if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) {
1112
- priv->dev_descriptor.idVendor = (uint16_t)vid;
1113
- priv->dev_descriptor.idProduct = (uint16_t)pid;
1114
- } else {
1115
- usbi_warn(ctx, "could not infer VID/PID of HCD hub from '%s'", parent_priv->path);
1116
- priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub
1117
- priv->dev_descriptor.idProduct = 1;
1118
- }
1119
- return LIBUSB_SUCCESS;
1120
- }
1121
-
1122
- /*
1123
- * fetch and cache all the config descriptors through I/O
1124
- */
1125
- static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char* device_id)
1126
- {
1127
- DWORD size, ret_size;
1128
- struct libusb_context *ctx = DEVICE_CTX(dev);
1129
- struct windows_device_priv *priv = _device_priv(dev);
1130
- int r;
1131
- uint8_t i;
1132
-
1133
- USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
1134
- PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
1135
- PUSB_CONFIGURATION_DESCRIPTOR cd_data = NULL;
1136
-
1137
- if (dev->num_configurations == 0)
1138
- return LIBUSB_ERROR_INVALID_PARAM;
1139
-
1140
- priv->config_descriptor = (unsigned char**) calloc(dev->num_configurations, sizeof(unsigned char*));
1141
- if (priv->config_descriptor == NULL)
1142
- return LIBUSB_ERROR_NO_MEM;
1143
- for (i=0; i<dev->num_configurations; i++)
1144
- priv->config_descriptor[i] = NULL;
1145
-
1146
- for (i=0, r=LIBUSB_SUCCESS; ; i++)
1147
- {
1148
- // safe loop: release all dynamic resources
1149
- safe_free(cd_buf_actual);
1150
-
1151
- // safe loop: end of loop condition
1152
- if ((i >= dev->num_configurations) || (r != LIBUSB_SUCCESS))
1153
- break;
1154
-
1155
- size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT);
1156
- memset(&cd_buf_short, 0, size);
1157
-
1158
- cd_buf_short.req.ConnectionIndex = (ULONG)priv->port;
1159
- cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1160
- cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1161
- cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1162
- cd_buf_short.req.SetupPacket.wIndex = 0;
1163
- cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1164
-
1165
- // Dummy call to get the required data size. Initial failures are reported as info rather
1166
- // than error as they can occur for non-penalizing situations, such as with some hubs.
1167
- // coverity[tainted_data_argument]
1168
- if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
1169
- &cd_buf_short, size, &ret_size, NULL)) {
1170
- usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
1171
- LOOP_BREAK(LIBUSB_ERROR_IO);
1172
- }
1173
-
1174
- if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
1175
- usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
1176
- LOOP_BREAK(LIBUSB_ERROR_IO);
1177
- }
1178
-
1179
- size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
1180
- if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST) calloc(1, size)) == NULL) {
1181
- usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
1182
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1183
- }
1184
- memset(cd_buf_actual, 0, size);
1185
-
1186
- // Actual call
1187
- cd_buf_actual->ConnectionIndex = (ULONG)priv->port;
1188
- cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
1189
- cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1190
- cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
1191
- cd_buf_actual->SetupPacket.wIndex = 0;
1192
- cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
1193
-
1194
- if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
1195
- cd_buf_actual, size, &ret_size, NULL)) {
1196
- usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
1197
- LOOP_BREAK(LIBUSB_ERROR_IO);
1198
- }
1199
-
1200
- cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
1201
-
1202
- if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
1203
- usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
1204
- LOOP_BREAK(LIBUSB_ERROR_IO);
1205
- }
1206
-
1207
- if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
1208
- usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
1209
- LOOP_BREAK(LIBUSB_ERROR_IO);
1210
- }
1211
-
1212
- usbi_dbg("cached config descriptor %d (bConfigurationValue=%d, %d bytes)",
1213
- i, cd_data->bConfigurationValue, cd_data->wTotalLength);
1214
-
1215
- // Cache the descriptor
1216
- priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
1217
- if (priv->config_descriptor[i] == NULL)
1218
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1219
- memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
1220
- }
1221
- return LIBUSB_SUCCESS;
1222
- }
1223
-
1224
- /*
1225
- * Populate a libusb device structure
1226
- */
1227
- static int init_device(struct libusb_device* dev, struct libusb_device* parent_dev,
1228
- uint8_t port_number, char* device_id, DWORD devinst)
1229
- {
1230
- HANDLE handle;
1231
- DWORD size;
1232
- USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1233
- USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2;
1234
- struct windows_device_priv *priv, *parent_priv;
1235
- struct libusb_context *ctx;
1236
- struct libusb_device* tmp_dev;
1237
- unsigned long tmp_id;
1238
- unsigned i;
1239
-
1240
- if ((dev == NULL) || (parent_dev == NULL)) {
1241
- return LIBUSB_ERROR_NOT_FOUND;
1242
- }
1243
- ctx = DEVICE_CTX(dev);
1244
- priv = _device_priv(dev);
1245
- parent_priv = _device_priv(parent_dev);
1246
- if (parent_priv->apib->id != USB_API_HUB) {
1247
- usbi_warn(ctx, "parent for device '%s' is not a hub", device_id);
1248
- return LIBUSB_ERROR_NOT_FOUND;
1249
- }
1250
-
1251
- // It is possible for the parent hub not to have been initialized yet
1252
- // If that's the case, lookup the ancestors to set the bus number
1253
- if (parent_dev->bus_number == 0) {
1254
- for (i=2; ; i++) {
1255
- tmp_id = get_ancestor_session_id(devinst, i);
1256
- if (tmp_id == 0) break;
1257
- tmp_dev = usbi_get_device_by_session_id(ctx, tmp_id);
1258
- if (tmp_dev == NULL) continue;
1259
- if (tmp_dev->bus_number != 0) {
1260
- usbi_dbg("got bus number from ancestor #%d", i);
1261
- parent_dev->bus_number = tmp_dev->bus_number;
1262
- libusb_unref_device(tmp_dev);
1263
- break;
1264
- }
1265
- libusb_unref_device(tmp_dev);
1266
- }
1267
- }
1268
- if (parent_dev->bus_number == 0) {
1269
- usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id);
1270
- return LIBUSB_ERROR_NOT_FOUND;
1271
- }
1272
- dev->bus_number = parent_dev->bus_number;
1273
- priv->port = port_number;
1274
- dev->port_number = port_number;
1275
- priv->depth = parent_priv->depth + 1;
1276
- priv->parent_dev = parent_dev;
1277
- dev->parent_dev = parent_dev;
1278
-
1279
- // If the device address is already set, we can stop here
1280
- if (dev->device_address != 0) {
1281
- return LIBUSB_SUCCESS;
1282
- }
1283
- memset(&conn_info, 0, sizeof(conn_info));
1284
- if (priv->depth != 0) { // Not a HCD hub
1285
- handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1286
- FILE_FLAG_OVERLAPPED, NULL);
1287
- if (handle == INVALID_HANDLE_VALUE) {
1288
- usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1289
- return LIBUSB_ERROR_ACCESS;
1290
- }
1291
- size = sizeof(conn_info);
1292
- conn_info.ConnectionIndex = (ULONG)port_number;
1293
- // coverity[tainted_data_argument]
1294
- if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
1295
- &conn_info, size, &size, NULL)) {
1296
- usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1297
- device_id, windows_error_str(0));
1298
- safe_closehandle(handle);
1299
- return LIBUSB_ERROR_NO_DEVICE;
1300
- }
1301
- if (conn_info.ConnectionStatus == NoDeviceConnected) {
1302
- usbi_err(ctx, "device '%s' is no longer connected!", device_id);
1303
- safe_closehandle(handle);
1304
- return LIBUSB_ERROR_NO_DEVICE;
1305
- }
1306
- memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR));
1307
- dev->num_configurations = priv->dev_descriptor.bNumConfigurations;
1308
- priv->active_config = conn_info.CurrentConfigurationValue;
1309
- usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
1310
- // If we can't read the config descriptors, just set the number of confs to zero
1311
- if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
1312
- dev->num_configurations = 0;
1313
- priv->dev_descriptor.bNumConfigurations = 0;
1314
- }
1315
-
1316
- // In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8
1317
- if (windows_version >= WINDOWS_8) {
1318
- memset(&conn_info_v2, 0, sizeof(conn_info_v2));
1319
- size = sizeof(conn_info_v2);
1320
- conn_info_v2.ConnectionIndex = (ULONG)port_number;
1321
- conn_info_v2.Length = size;
1322
- conn_info_v2.SupportedUsbProtocols.Usb300 = 1;
1323
- if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2,
1324
- &conn_info_v2, size, &conn_info_v2, size, &size, NULL)) {
1325
- usbi_warn(ctx, "could not get node connection information (V2) for device '%s': %s",
1326
- device_id, windows_error_str(0));
1327
- } else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) {
1328
- conn_info.Speed = 3;
1329
- }
1330
- }
1331
-
1332
- safe_closehandle(handle);
1333
-
1334
- if (conn_info.DeviceAddress > UINT8_MAX) {
1335
- usbi_err(ctx, "program assertion failed: device address overflow");
1336
- }
1337
- dev->device_address = (uint8_t)conn_info.DeviceAddress + 1;
1338
- if (dev->device_address == 1) {
1339
- usbi_err(ctx, "program assertion failed: device address collision with root hub");
1340
- }
1341
- switch (conn_info.Speed) {
1342
- case 0: dev->speed = LIBUSB_SPEED_LOW; break;
1343
- case 1: dev->speed = LIBUSB_SPEED_FULL; break;
1344
- case 2: dev->speed = LIBUSB_SPEED_HIGH; break;
1345
- case 3: dev->speed = LIBUSB_SPEED_SUPER; break;
1346
- default:
1347
- usbi_warn(ctx, "Got unknown device speed %d", conn_info.Speed);
1348
- break;
1349
- }
1350
- } else {
1351
- dev->device_address = 1; // root hubs are set to use device number 1
1352
- force_hcd_device_descriptor(dev);
1353
- }
1354
-
1355
- usbi_sanitize_device(dev);
1356
-
1357
- usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
1358
- dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
1359
-
1360
- return LIBUSB_SUCCESS;
1361
- }
1362
-
1363
- // Returns the api type, or 0 if not found/unsupported
1364
- static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
1365
- SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
1366
- {
1367
- // Precedence for filter drivers vs driver is in the order of this array
1368
- struct driver_lookup lookup[3] = {
1369
- {"\0\0", SPDRP_SERVICE, "driver"},
1370
- {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1371
- {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1372
- };
1373
- DWORD size, reg_type;
1374
- unsigned k, l;
1375
- int i, j;
1376
-
1377
- *api = USB_API_UNSUPPORTED;
1378
- *sub_api = SUB_API_NOTSET;
1379
- // Check the service & filter names to know the API we should use
1380
- for (k=0; k<3; k++) {
1381
- if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1382
- &reg_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1383
- // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1384
- if (lookup[k].reg_prop == SPDRP_SERVICE) {
1385
- // our buffers are MAX_KEY_LENGTH+1 so we can overflow if needed
1386
- lookup[k].list[safe_strlen(lookup[k].list)+1] = 0;
1387
- }
1388
- // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1389
- // NB: none of the driver names we check against contain LIST_SEPARATOR,
1390
- // (currently ';'), so even if an unsuported one does, it's not an issue
1391
- for (l=0; (lookup[k].list[l] != 0) || (lookup[k].list[l+1] != 0); l++) {
1392
- if (lookup[k].list[l] == 0) {
1393
- lookup[k].list[l] = LIST_SEPARATOR;
1394
- }
1395
- }
1396
- usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
1397
- } else {
1398
- if (GetLastError() != ERROR_INVALID_DATA) {
1399
- usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
1400
- }
1401
- lookup[k].list[0] = 0;
1402
- }
1403
- }
1404
-
1405
- for (i=1; i<USB_API_MAX; i++) {
1406
- for (k=0; k<3; k++) {
1407
- j = get_sub_api(lookup[k].list, i);
1408
- if (j >= 0) {
1409
- usbi_dbg("matched %s name against %s",
1410
- lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
1411
- *api = i;
1412
- *sub_api = j;
1413
- return;
1414
- }
1415
- }
1416
- }
1417
- }
1418
-
1419
- static int set_composite_interface(struct libusb_context* ctx, struct libusb_device* dev,
1420
- char* dev_interface_path, char* device_id, int api, int sub_api)
1421
- {
1422
- unsigned i;
1423
- struct windows_device_priv *priv = _device_priv(dev);
1424
- int interface_number;
1425
-
1426
- if (priv->apib->id != USB_API_COMPOSITE) {
1427
- usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id);
1428
- return LIBUSB_ERROR_NO_DEVICE;
1429
- }
1430
-
1431
- // Because MI_## are not necessarily in sequential order (some composite
1432
- // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1433
- // interface number from the path's MI value
1434
- interface_number = 0;
1435
- for (i=0; device_id[i] != 0; ) {
1436
- if ( (device_id[i++] == 'M') && (device_id[i++] == 'I')
1437
- && (device_id[i++] == '_') ) {
1438
- interface_number = (device_id[i++] - '0')*10;
1439
- interface_number += device_id[i] - '0';
1440
- break;
1441
- }
1442
- }
1443
-
1444
- if (device_id[i] == 0) {
1445
- usbi_warn(ctx, "failure to read interface number for %s. Using default value %d",
1446
- device_id, interface_number);
1447
- }
1448
-
1449
- if (priv->usb_interface[interface_number].path != NULL) {
1450
- if (api == USB_API_HID) {
1451
- // HID devices can have multiple collections (COL##) for each MI_## interface
1452
- usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
1453
- interface_number, device_id);
1454
- return LIBUSB_ERROR_ACCESS;
1455
- }
1456
- // In other cases, just use the latest data
1457
- safe_free(priv->usb_interface[interface_number].path);
1458
- }
1459
-
1460
- usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
1461
- priv->usb_interface[interface_number].path = dev_interface_path;
1462
- priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1463
- priv->usb_interface[interface_number].sub_api = sub_api;
1464
- if ((api == USB_API_HID) && (priv->hid == NULL)) {
1465
- priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
1466
- if (priv->hid == NULL)
1467
- return LIBUSB_ERROR_NO_MEM;
1468
- }
1469
-
1470
- return LIBUSB_SUCCESS;
1471
- }
1472
-
1473
- static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
1474
- char* dev_interface_path)
1475
- {
1476
- int i;
1477
- struct windows_device_priv *priv = _device_priv(dev);
1478
-
1479
- if (priv->hid == NULL) {
1480
- usbi_err(ctx, "program assertion failed: parent is not HID");
1481
- return LIBUSB_ERROR_NO_DEVICE;
1482
- }
1483
- if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1484
- usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
1485
- return LIBUSB_ERROR_NO_DEVICE;
1486
- }
1487
- for (i=0; i<priv->hid->nb_interfaces; i++) {
1488
- if (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
1489
- usbi_dbg("interface[%d] already set to %s", i, dev_interface_path);
1490
- return LIBUSB_SUCCESS;
1491
- }
1492
- }
1493
-
1494
- priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1495
- priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1496
- usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
1497
- priv->hid->nb_interfaces++;
1498
- return LIBUSB_SUCCESS;
1499
- }
1500
-
1501
- /*
1502
- * get_device_list: libusb backend device enumeration function
1503
- */
1504
- static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1505
- {
1506
- struct discovered_devs *discdevs;
1507
- HDEVINFO dev_info = { 0 };
1508
- const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
1509
- SP_DEVINFO_DATA dev_info_data = { 0 };
1510
- SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
1511
- GUID hid_guid;
1512
- #define MAX_ENUM_GUIDS 64
1513
- const GUID* guid[MAX_ENUM_GUIDS];
1514
- #define HCD_PASS 0
1515
- #define HUB_PASS 1
1516
- #define GEN_PASS 2
1517
- #define DEV_PASS 3
1518
- #define HID_PASS 4
1519
- int r = LIBUSB_SUCCESS;
1520
- int api, sub_api;
1521
- size_t class_index = 0;
1522
- unsigned int nb_guids, pass, i, j, ancestor;
1523
- char path[MAX_PATH_LENGTH];
1524
- char strbuf[MAX_PATH_LENGTH];
1525
- struct libusb_device *dev, *parent_dev;
1526
- struct windows_device_priv *priv, *parent_priv;
1527
- char* dev_interface_path = NULL;
1528
- char* dev_id_path = NULL;
1529
- unsigned long session_id;
1530
- DWORD size, reg_type, port_nr, install_state;
1531
- HKEY key;
1532
- WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
1533
- GUID* if_guid;
1534
- LONG s;
1535
- // Keep a list of newly allocated devs to unref
1536
- libusb_device** unref_list;
1537
- unsigned int unref_size = 64;
1538
- unsigned int unref_cur = 0;
1539
-
1540
- // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug)
1541
- // PASS 2 : (re)enumerate HUBS
1542
- // PASS 3 : (re)enumerate generic USB devices (including driverless)
1543
- // and list additional USB device interface GUIDs to explore
1544
- // PASS 4 : (re)enumerate master USB devices that have a device interface
1545
- // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
1546
- // set the device interfaces.
1547
-
1548
- // Init the GUID table
1549
- guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1550
- guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1551
- guid[GEN_PASS] = NULL;
1552
- guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1553
- HidD_GetHidGuid(&hid_guid);
1554
- guid[HID_PASS] = &hid_guid;
1555
- nb_guids = HID_PASS+1;
1556
-
1557
- unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*));
1558
- if (unref_list == NULL) {
1559
- return LIBUSB_ERROR_NO_MEM;
1560
- }
1561
-
1562
- for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1563
- //#define ENUM_DEBUG
1564
- #ifdef ENUM_DEBUG
1565
- const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
1566
- usbi_dbg("#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
1567
- (pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
1568
- #endif
1569
- for (i = 0; ; i++) {
1570
- // safe loop: free up any (unprotected) dynamic resource
1571
- // NB: this is always executed before breaking the loop
1572
- safe_free(dev_interface_details);
1573
- safe_free(dev_interface_path);
1574
- safe_free(dev_id_path);
1575
- priv = parent_priv = NULL;
1576
- dev = parent_dev = NULL;
1577
-
1578
- // Safe loop: end of loop conditions
1579
- if (r != LIBUSB_SUCCESS) {
1580
- break;
1581
- }
1582
- if ((pass == HCD_PASS) && (i == UINT8_MAX)) {
1583
- usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX);
1584
- break;
1585
- }
1586
- if (pass != GEN_PASS) {
1587
- // Except for GEN, all passes deal with device interfaces
1588
- dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i);
1589
- if (dev_interface_details == NULL) {
1590
- break;
1591
- } else {
1592
- dev_interface_path = sanitize_path(dev_interface_details->DevicePath);
1593
- if (dev_interface_path == NULL) {
1594
- usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath);
1595
- continue;
1596
- }
1597
- }
1598
- } else {
1599
- // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1600
- // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1601
- // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1602
- for (; class_index < ARRAYSIZE(usb_class); class_index++) {
1603
- if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))
1604
- break;
1605
- i = 0;
1606
- }
1607
- if (class_index >= ARRAYSIZE(usb_class))
1608
- break;
1609
- }
1610
-
1611
- // Read the Device ID path. This is what we'll use as UID
1612
- // Note that if the device is plugged in a different port or hub, the Device ID changes
1613
- if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
1614
- usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
1615
- dev_info_data.DevInst);
1616
- continue;
1617
- }
1618
- dev_id_path = sanitize_path(path);
1619
- if (dev_id_path == NULL) {
1620
- usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
1621
- dev_info_data.DevInst);
1622
- continue;
1623
- }
1624
- #ifdef ENUM_DEBUG
1625
- usbi_dbg("PRO: %s", dev_id_path);
1626
- #endif
1627
-
1628
- // The SPDRP_ADDRESS for USB devices is the device port number on the hub
1629
- port_nr = 0;
1630
- if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) {
1631
- if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
1632
- &reg_type, (BYTE*)&port_nr, 4, &size))
1633
- || (size != 4) ) {
1634
- usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
1635
- dev_id_path, windows_error_str(0));
1636
- continue;
1637
- }
1638
- }
1639
-
1640
- // Set API to use or get additional data from generic pass
1641
- api = USB_API_UNSUPPORTED;
1642
- sub_api = SUB_API_NOTSET;
1643
- switch (pass) {
1644
- case HCD_PASS:
1645
- break;
1646
- case GEN_PASS:
1647
- // We use the GEN pass to detect driverless devices...
1648
- size = sizeof(strbuf);
1649
- if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER,
1650
- &reg_type, (BYTE*)strbuf, size, &size)) {
1651
- usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path);
1652
- usbi_info(ctx, "libusb will not be able to access it.");
1653
- }
1654
- // ...and to add the additional device interface GUIDs
1655
- key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1656
- if (key != INVALID_HANDLE_VALUE) {
1657
- size = sizeof(guid_string_w);
1658
- s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, &reg_type,
1659
- (BYTE*)guid_string_w, &size);
1660
- pRegCloseKey(key);
1661
- if (s == ERROR_SUCCESS) {
1662
- if (nb_guids >= MAX_ENUM_GUIDS) {
1663
- // If this assert is ever reported, grow a GUID table dynamically
1664
- usbi_err(ctx, "program assertion failed: too many GUIDs");
1665
- LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
1666
- }
1667
- if_guid = (GUID*) calloc(1, sizeof(GUID));
1668
- if (if_guid == NULL) {
1669
- usbi_err(ctx, "could not calloc for if_guid: not enough memory");
1670
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1671
- }
1672
- pCLSIDFromString(guid_string_w, if_guid);
1673
- guid[nb_guids++] = if_guid;
1674
- usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
1675
- }
1676
- }
1677
- break;
1678
- case HID_PASS:
1679
- api = USB_API_HID;
1680
- break;
1681
- default:
1682
- // Get the API type (after checking that the driver installation is OK)
1683
- if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1684
- &reg_type, (BYTE*)&install_state, 4, &size))
1685
- || (size != 4) ){
1686
- usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1687
- dev_id_path, windows_error_str(0));
1688
- } else if (install_state != 0) {
1689
- usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %d) - skipping",
1690
- dev_id_path, install_state);
1691
- continue;
1692
- }
1693
- get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api);
1694
- break;
1695
- }
1696
-
1697
- // Find parent device (for the passes that need it)
1698
- switch (pass) {
1699
- case HCD_PASS:
1700
- case DEV_PASS:
1701
- case HUB_PASS:
1702
- break;
1703
- default:
1704
- // Go through the ancestors until we see a face we recognize
1705
- parent_dev = NULL;
1706
- for (ancestor = 1; parent_dev == NULL; ancestor++) {
1707
- session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor);
1708
- if (session_id == 0) {
1709
- break;
1710
- }
1711
- parent_dev = usbi_get_device_by_session_id(ctx, session_id);
1712
- }
1713
- if (parent_dev == NULL) {
1714
- usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
1715
- continue;
1716
- }
1717
- parent_priv = _device_priv(parent_dev);
1718
- // virtual USB devices are also listed during GEN - don't process these yet
1719
- if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
1720
- libusb_unref_device(parent_dev);
1721
- continue;
1722
- }
1723
- break;
1724
- }
1725
-
1726
- // Create new or match existing device, using the (hashed) device_id as session id
1727
- if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
1728
- // These are the passes that create "new" devices
1729
- session_id = htab_hash(dev_id_path);
1730
- dev = usbi_get_device_by_session_id(ctx, session_id);
1731
- if (dev == NULL) {
1732
- if (pass == DEV_PASS) {
1733
- // This can occur if the OS only reports a newly plugged device after we started enum
1734
- usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)"
1735
- " - ignoring", dev_id_path);
1736
- continue;
1737
- }
1738
- usbi_dbg("allocating new device for session [%X]", session_id);
1739
- if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
1740
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1741
- }
1742
- windows_device_priv_init(dev);
1743
- } else {
1744
- usbi_dbg("found existing device for session [%X] (%d.%d)",
1745
- session_id, dev->bus_number, dev->device_address);
1746
- }
1747
- // Keep track of devices that need unref
1748
- unref_list[unref_cur++] = dev;
1749
- if (unref_cur >= unref_size) {
1750
- unref_size += 64;
1751
- unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1752
- if (unref_list == NULL) {
1753
- usbi_err(ctx, "could not realloc list for unref - aborting.");
1754
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1755
- }
1756
- }
1757
- priv = _device_priv(dev);
1758
- }
1759
-
1760
- // Setup device
1761
- switch (pass) {
1762
- case HCD_PASS:
1763
- dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected
1764
- dev->device_address = 0;
1765
- dev->num_configurations = 0;
1766
- priv->apib = &usb_api_backend[USB_API_HUB];
1767
- priv->sub_api = SUB_API_NOTSET;
1768
- priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs
1769
- priv->path = dev_interface_path; dev_interface_path = NULL;
1770
- break;
1771
- case HUB_PASS:
1772
- case DEV_PASS:
1773
- // If the device has already been setup, don't do it again
1774
- if (priv->path != NULL)
1775
- break;
1776
- // Take care of API initialization
1777
- priv->path = dev_interface_path; dev_interface_path = NULL;
1778
- priv->apib = &usb_api_backend[api];
1779
- priv->sub_api = sub_api;
1780
- switch(api) {
1781
- case USB_API_COMPOSITE:
1782
- case USB_API_HUB:
1783
- break;
1784
- case USB_API_HID:
1785
- priv->hid = calloc(1, sizeof(struct hid_device_priv));
1786
- if (priv->hid == NULL) {
1787
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1788
- }
1789
- priv->hid->nb_interfaces = 0;
1790
- break;
1791
- default:
1792
- // For other devices, the first interface is the same as the device
1793
- priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1);
1794
- if (priv->usb_interface[0].path != NULL) {
1795
- safe_strcpy(priv->usb_interface[0].path, safe_strlen(priv->path)+1, priv->path);
1796
- } else {
1797
- usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
1798
- }
1799
- // The following is needed if we want API calls to work for both simple
1800
- // and composite devices.
1801
- for(j=0; j<USB_MAXINTERFACES; j++) {
1802
- priv->usb_interface[j].apib = &usb_api_backend[api];
1803
- }
1804
- break;
1805
- }
1806
- break;
1807
- case GEN_PASS:
1808
- r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
1809
- if (r == LIBUSB_SUCCESS) {
1810
- // Append device to the list of discovered devices
1811
- discdevs = discovered_devs_append(*_discdevs, dev);
1812
- if (!discdevs) {
1813
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1814
- }
1815
- *_discdevs = discdevs;
1816
- } else if (r == LIBUSB_ERROR_NO_DEVICE) {
1817
- // This can occur if the device was disconnected but Windows hasn't
1818
- // refreshed its enumeration yet - in that case, we ignore the device
1819
- r = LIBUSB_SUCCESS;
1820
- }
1821
- break;
1822
- default: // HID_PASS and later
1823
- if (parent_priv->apib->id == USB_API_HID) {
1824
- usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
1825
- r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1826
- if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
1827
- dev_interface_path = NULL;
1828
- } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
1829
- usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
1830
- switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) {
1831
- case LIBUSB_SUCCESS:
1832
- dev_interface_path = NULL;
1833
- break;
1834
- case LIBUSB_ERROR_ACCESS:
1835
- // interface has already been set => make sure dev_interface_path is freed then
1836
- break;
1837
- default:
1838
- LOOP_BREAK(r);
1839
- break;
1840
- }
1841
- }
1842
- libusb_unref_device(parent_dev);
1843
- break;
1844
- }
1845
- }
1846
- }
1847
-
1848
- // Free any additional GUIDs
1849
- for (pass = HID_PASS+1; pass < nb_guids; pass++) {
1850
- safe_free(guid[pass]);
1851
- }
1852
-
1853
- // Unref newly allocated devs
1854
- if (unref_list != NULL) {
1855
- for (i=0; i<unref_cur; i++) {
1856
- safe_unref_device(unref_list[i]);
1857
- }
1858
- free(unref_list);
1859
- }
1860
-
1861
- return r;
1862
- }
1863
-
1864
- /*
1865
- * exit: libusb backend deinitialization function
1866
- */
1867
- static void windows_exit(void)
1868
- {
1869
- int i;
1870
- HANDLE semaphore;
1871
- char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
1872
-
1873
- sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
1874
- semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
1875
- if (semaphore == NULL) {
1876
- return;
1877
- }
1878
-
1879
- // A successful wait brings our semaphore count to 0 (unsignaled)
1880
- // => any concurent wait stalls until the semaphore release
1881
- if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
1882
- CloseHandle(semaphore);
1883
- return;
1884
- }
1885
-
1886
- // Only works if exits and inits are balanced exactly
1887
- if (--concurrent_usage < 0) { // Last exit
1888
- for (i=0; i<USB_API_MAX; i++) {
1889
- usb_api_backend[i].exit(SUB_API_NOTSET);
1890
- }
1891
- exit_polling();
1892
-
1893
- if (timer_thread) {
1894
- // actually the signal to quit the thread.
1895
- if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0) ||
1896
- (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
1897
- usbi_dbg("could not wait for timer thread to quit");
1898
- TerminateThread(timer_thread, 1);
1899
- }
1900
- CloseHandle(timer_thread);
1901
- timer_thread = NULL;
1902
- timer_thread_id = 0;
1903
- }
1904
- htab_destroy();
1905
- usbi_mutex_destroy(&autoclaim_lock);
1906
- }
1907
-
1908
- ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
1909
- CloseHandle(semaphore);
1910
- }
1911
-
1912
- static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
1913
- {
1914
- struct windows_device_priv *priv = _device_priv(dev);
1915
-
1916
- memcpy(buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
1917
- *host_endian = 0;
1918
-
1919
- return LIBUSB_SUCCESS;
1920
- }
1921
-
1922
- static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
1923
- {
1924
- struct windows_device_priv *priv = _device_priv(dev);
1925
- PUSB_CONFIGURATION_DESCRIPTOR config_header;
1926
- size_t size;
1927
-
1928
- // config index is zero based
1929
- if (config_index >= dev->num_configurations)
1930
- return LIBUSB_ERROR_INVALID_PARAM;
1931
-
1932
- if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
1933
- return LIBUSB_ERROR_NOT_FOUND;
1934
-
1935
- config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
1936
-
1937
- size = MIN(config_header->wTotalLength, len);
1938
- memcpy(buffer, priv->config_descriptor[config_index], size);
1939
- *host_endian = 0;
1940
-
1941
- return (int)size;
1942
- }
1943
-
1944
- /*
1945
- * return the cached copy of the active config descriptor
1946
- */
1947
- static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
1948
- {
1949
- struct windows_device_priv *priv = _device_priv(dev);
1950
-
1951
- if (priv->active_config == 0)
1952
- return LIBUSB_ERROR_NOT_FOUND;
1953
-
1954
- // config index is zero based
1955
- return windows_get_config_descriptor(dev, (uint8_t)(priv->active_config-1), buffer, len, host_endian);
1956
- }
1957
-
1958
- static int windows_open(struct libusb_device_handle *dev_handle)
1959
- {
1960
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1961
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
1962
-
1963
- if (priv->apib == NULL) {
1964
- usbi_err(ctx, "program assertion failed - device is not initialized");
1965
- return LIBUSB_ERROR_NO_DEVICE;
1966
- }
1967
-
1968
- return priv->apib->open(SUB_API_NOTSET, dev_handle);
1969
- }
1970
-
1971
- static void windows_close(struct libusb_device_handle *dev_handle)
1972
- {
1973
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1974
-
1975
- priv->apib->close(SUB_API_NOTSET, dev_handle);
1976
- }
1977
-
1978
- static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
1979
- {
1980
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1981
-
1982
- if (priv->active_config == 0) {
1983
- *config = 0;
1984
- return LIBUSB_ERROR_NOT_FOUND;
1985
- }
1986
-
1987
- *config = priv->active_config;
1988
- return LIBUSB_SUCCESS;
1989
- }
1990
-
1991
- /*
1992
- * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
1993
- * does not currently expose a service that allows higher-level drivers to set
1994
- * the configuration."
1995
- */
1996
- static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
1997
- {
1998
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
1999
- int r = LIBUSB_SUCCESS;
2000
-
2001
- if (config >= USB_MAXCONFIG)
2002
- return LIBUSB_ERROR_INVALID_PARAM;
2003
-
2004
- r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
2005
- LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
2006
- LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
2007
- 0, NULL, 0, 1000);
2008
-
2009
- if (r == LIBUSB_SUCCESS) {
2010
- priv->active_config = (uint8_t)config;
2011
- }
2012
- return r;
2013
- }
2014
-
2015
- static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface)
2016
- {
2017
- int r = LIBUSB_SUCCESS;
2018
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2019
-
2020
- safe_free(priv->usb_interface[iface].endpoint);
2021
- priv->usb_interface[iface].nb_endpoints= 0;
2022
-
2023
- r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
2024
-
2025
- if (r == LIBUSB_SUCCESS) {
2026
- r = windows_assign_endpoints(dev_handle, iface, 0);
2027
- }
2028
-
2029
- return r;
2030
- }
2031
-
2032
- static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
2033
- {
2034
- int r = LIBUSB_SUCCESS;
2035
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2036
-
2037
- safe_free(priv->usb_interface[iface].endpoint);
2038
- priv->usb_interface[iface].nb_endpoints= 0;
2039
-
2040
- r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
2041
-
2042
- if (r == LIBUSB_SUCCESS) {
2043
- r = windows_assign_endpoints(dev_handle, iface, altsetting);
2044
- }
2045
-
2046
- return r;
2047
- }
2048
-
2049
- static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface)
2050
- {
2051
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2052
-
2053
- return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
2054
- }
2055
-
2056
- static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
2057
- {
2058
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2059
- return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
2060
- }
2061
-
2062
- static int windows_reset_device(struct libusb_device_handle *dev_handle)
2063
- {
2064
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2065
- return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
2066
- }
2067
-
2068
- // The 3 functions below are unlikely to ever get supported on Windows
2069
- static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
2070
- {
2071
- return LIBUSB_ERROR_NOT_SUPPORTED;
2072
- }
2073
-
2074
- static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
2075
- {
2076
- return LIBUSB_ERROR_NOT_SUPPORTED;
2077
- }
2078
-
2079
- static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
2080
- {
2081
- return LIBUSB_ERROR_NOT_SUPPORTED;
2082
- }
2083
-
2084
- static void windows_destroy_device(struct libusb_device *dev)
2085
- {
2086
- windows_device_priv_release(dev);
2087
- }
2088
-
2089
- static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
2090
- {
2091
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2092
-
2093
- usbi_free_fd(&transfer_priv->pollable_fd);
2094
- safe_free(transfer_priv->hid_buffer);
2095
- // When auto claim is in use, attempt to release the auto-claimed interface
2096
- auto_release(itransfer);
2097
- }
2098
-
2099
- static int submit_bulk_transfer(struct usbi_transfer *itransfer)
2100
- {
2101
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2102
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2103
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2104
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2105
- int r;
2106
-
2107
- r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer);
2108
- if (r != LIBUSB_SUCCESS) {
2109
- return r;
2110
- }
2111
-
2112
- usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
2113
- (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
2114
-
2115
- return LIBUSB_SUCCESS;
2116
- }
2117
-
2118
- static int submit_iso_transfer(struct usbi_transfer *itransfer)
2119
- {
2120
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2121
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2122
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2123
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2124
- int r;
2125
-
2126
- r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer);
2127
- if (r != LIBUSB_SUCCESS) {
2128
- return r;
2129
- }
2130
-
2131
- usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
2132
- (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
2133
-
2134
- return LIBUSB_SUCCESS;
2135
- }
2136
-
2137
- static int submit_control_transfer(struct usbi_transfer *itransfer)
2138
- {
2139
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2140
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
2141
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
2142
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2143
- int r;
2144
-
2145
- r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer);
2146
- if (r != LIBUSB_SUCCESS) {
2147
- return r;
2148
- }
2149
-
2150
- usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
2151
-
2152
- return LIBUSB_SUCCESS;
2153
-
2154
- }
2155
-
2156
- static int windows_submit_transfer(struct usbi_transfer *itransfer)
2157
- {
2158
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2159
-
2160
- switch (transfer->type) {
2161
- case LIBUSB_TRANSFER_TYPE_CONTROL:
2162
- return submit_control_transfer(itransfer);
2163
- case LIBUSB_TRANSFER_TYPE_BULK:
2164
- case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2165
- if (IS_XFEROUT(transfer) &&
2166
- transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
2167
- return LIBUSB_ERROR_NOT_SUPPORTED;
2168
- return submit_bulk_transfer(itransfer);
2169
- case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2170
- return submit_iso_transfer(itransfer);
2171
- case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2172
- return LIBUSB_ERROR_NOT_SUPPORTED;
2173
- default:
2174
- usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2175
- return LIBUSB_ERROR_INVALID_PARAM;
2176
- }
2177
- }
2178
-
2179
- static int windows_abort_control(struct usbi_transfer *itransfer)
2180
- {
2181
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2182
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2183
-
2184
- return priv->apib->abort_control(SUB_API_NOTSET, itransfer);
2185
- }
2186
-
2187
- static int windows_abort_transfers(struct usbi_transfer *itransfer)
2188
- {
2189
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2190
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2191
-
2192
- return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer);
2193
- }
2194
-
2195
- static int windows_cancel_transfer(struct usbi_transfer *itransfer)
2196
- {
2197
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2198
-
2199
- switch (transfer->type) {
2200
- case LIBUSB_TRANSFER_TYPE_CONTROL:
2201
- return windows_abort_control(itransfer);
2202
- case LIBUSB_TRANSFER_TYPE_BULK:
2203
- case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2204
- case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2205
- return windows_abort_transfers(itransfer);
2206
- case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2207
- return LIBUSB_ERROR_NOT_SUPPORTED;
2208
- default:
2209
- usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2210
- return LIBUSB_ERROR_INVALID_PARAM;
2211
- }
2212
- }
2213
-
2214
- static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2215
- {
2216
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2217
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
2218
- int status, istatus;
2219
-
2220
- usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
2221
-
2222
- switch(io_result) {
2223
- case NO_ERROR:
2224
- status = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2225
- break;
2226
- case ERROR_GEN_FAILURE:
2227
- usbi_dbg("detected endpoint stall");
2228
- status = LIBUSB_TRANSFER_STALL;
2229
- break;
2230
- case ERROR_SEM_TIMEOUT:
2231
- usbi_dbg("detected semaphore timeout");
2232
- status = LIBUSB_TRANSFER_TIMED_OUT;
2233
- break;
2234
- case ERROR_OPERATION_ABORTED:
2235
- istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
2236
- if (istatus != LIBUSB_TRANSFER_COMPLETED) {
2237
- usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
2238
- }
2239
- if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
2240
- usbi_dbg("detected timeout");
2241
- status = LIBUSB_TRANSFER_TIMED_OUT;
2242
- } else {
2243
- usbi_dbg("detected operation aborted");
2244
- status = LIBUSB_TRANSFER_CANCELLED;
2245
- }
2246
- break;
2247
- default:
2248
- usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(io_result));
2249
- status = LIBUSB_TRANSFER_ERROR;
2250
- break;
2251
- }
2252
- windows_clear_transfer_priv(itransfer); // Cancel polling
2253
- usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
2254
- }
2255
-
2256
- static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
2257
- {
2258
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2259
-
2260
- switch (transfer->type) {
2261
- case LIBUSB_TRANSFER_TYPE_CONTROL:
2262
- case LIBUSB_TRANSFER_TYPE_BULK:
2263
- case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2264
- case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2265
- windows_transfer_callback (itransfer, io_result, io_size);
2266
- break;
2267
- case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2268
- usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
2269
- break;
2270
- default:
2271
- usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
2272
- }
2273
- }
2274
-
2275
- static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
2276
- {
2277
- struct windows_transfer_priv* transfer_priv = NULL;
2278
- POLL_NFDS_TYPE i = 0;
2279
- bool found;
2280
- struct usbi_transfer *transfer;
2281
- DWORD io_size, io_result;
2282
-
2283
- usbi_mutex_lock(&ctx->open_devs_lock);
2284
- for (i = 0; i < nfds && num_ready > 0; i++) {
2285
-
2286
- usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
2287
-
2288
- if (!fds[i].revents) {
2289
- continue;
2290
- }
2291
-
2292
- num_ready--;
2293
-
2294
- // Because a Windows OVERLAPPED is used for poll emulation,
2295
- // a pollable fd is created and stored with each transfer
2296
- usbi_mutex_lock(&ctx->flying_transfers_lock);
2297
- found = false;
2298
- list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2299
- transfer_priv = usbi_transfer_get_os_priv(transfer);
2300
- if (transfer_priv->pollable_fd.fd == fds[i].fd) {
2301
- found = true;
2302
- break;
2303
- }
2304
- }
2305
- usbi_mutex_unlock(&ctx->flying_transfers_lock);
2306
-
2307
- if (found) {
2308
- // Handle async requests that completed synchronously first
2309
- if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
2310
- io_result = NO_ERROR;
2311
- io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
2312
- // Regular async overlapped
2313
- } else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
2314
- transfer_priv->pollable_fd.overlapped, &io_size, false)) {
2315
- io_result = NO_ERROR;
2316
- } else {
2317
- io_result = GetLastError();
2318
- }
2319
- usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
2320
- // let handle_callback free the event using the transfer wfd
2321
- // If you don't use the transfer wfd, you run a risk of trying to free a
2322
- // newly allocated wfd that took the place of the one from the transfer.
2323
- windows_handle_callback(transfer, io_result, io_size);
2324
- } else {
2325
- usbi_mutex_unlock(&ctx->open_devs_lock);
2326
- usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
2327
- return LIBUSB_ERROR_NOT_FOUND;
2328
- }
2329
- }
2330
-
2331
- usbi_mutex_unlock(&ctx->open_devs_lock);
2332
- return LIBUSB_SUCCESS;
2333
- }
2334
-
2335
- /*
2336
- * Monotonic and real time functions
2337
- */
2338
- unsigned __stdcall windows_clock_gettime_threaded(void* param)
2339
- {
2340
- struct timer_request *request;
2341
- LARGE_INTEGER hires_counter;
2342
- MSG msg;
2343
-
2344
- // The following call will create this thread's message queue
2345
- // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx
2346
- pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
2347
-
2348
- // Signal windows_init() that we're ready to service requests
2349
- if (!SetEvent((HANDLE)param)) {
2350
- usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0));
2351
- }
2352
- param = NULL;
2353
-
2354
- // Main loop - wait for requests
2355
- while (1) {
2356
- if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) {
2357
- usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0));
2358
- return 1;
2359
- }
2360
-
2361
- switch (msg.message) {
2362
- case WM_TIMER_REQUEST:
2363
- // Requests to this thread are for hires always
2364
- // Microsoft says that this function always succeeds on XP and later
2365
- // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx
2366
- request = (struct timer_request *)msg.lParam;
2367
- QueryPerformanceCounter(&hires_counter);
2368
- request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
2369
- request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
2370
- if (!SetEvent(request->event)) {
2371
- usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0));
2372
- }
2373
- break;
2374
-
2375
- case WM_TIMER_EXIT:
2376
- usbi_dbg("timer thread quitting");
2377
- return 0;
2378
- }
2379
- }
2380
- }
2381
-
2382
- static int windows_clock_gettime(int clk_id, struct timespec *tp)
2383
- {
2384
- struct timer_request request;
2385
- FILETIME filetime;
2386
- ULARGE_INTEGER rtime;
2387
- DWORD r;
2388
- switch(clk_id) {
2389
- case USBI_CLOCK_MONOTONIC:
2390
- if (timer_thread) {
2391
- request.tp = tp;
2392
- request.event = CreateEvent(NULL, FALSE, FALSE, NULL);
2393
- if (request.event == NULL) {
2394
- return LIBUSB_ERROR_NO_MEM;
2395
- }
2396
-
2397
- if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) {
2398
- usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0));
2399
- CloseHandle(request.event);
2400
- return LIBUSB_ERROR_OTHER;
2401
- }
2402
-
2403
- do {
2404
- r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS);
2405
- if (r == WAIT_TIMEOUT) {
2406
- usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
2407
- }
2408
- else if (r == WAIT_FAILED) {
2409
- usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0));
2410
- }
2411
- } while (r == WAIT_TIMEOUT);
2412
- CloseHandle(request.event);
2413
-
2414
- if (r == WAIT_OBJECT_0) {
2415
- return LIBUSB_SUCCESS;
2416
- }
2417
- else {
2418
- return LIBUSB_ERROR_OTHER;
2419
- }
2420
- }
2421
- // Fall through and return real-time if monotonic was not detected @ timer init
2422
- case USBI_CLOCK_REALTIME:
2423
- // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
2424
- // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
2425
- // Note however that our resolution is bounded by the Windows system time
2426
- // functions and is at best of the order of 1 ms (or, usually, worse)
2427
- GetSystemTimeAsFileTime(&filetime);
2428
- rtime.LowPart = filetime.dwLowDateTime;
2429
- rtime.HighPart = filetime.dwHighDateTime;
2430
- rtime.QuadPart -= epoch_time;
2431
- tp->tv_sec = (long)(rtime.QuadPart / 10000000);
2432
- tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
2433
- return LIBUSB_SUCCESS;
2434
- default:
2435
- return LIBUSB_ERROR_INVALID_PARAM;
2436
- }
2437
- }
2438
-
2439
-
2440
- // NB: MSVC6 does not support named initializers.
2441
- const struct usbi_os_backend windows_backend = {
2442
- "Windows",
2443
- USBI_CAP_HAS_HID_ACCESS,
2444
- windows_init,
2445
- windows_exit,
2446
-
2447
- windows_get_device_list,
2448
- NULL, /* hotplug_poll */
2449
- windows_open,
2450
- windows_close,
2451
-
2452
- windows_get_device_descriptor,
2453
- windows_get_active_config_descriptor,
2454
- windows_get_config_descriptor,
2455
- NULL, /* get_config_descriptor_by_value() */
2456
-
2457
- windows_get_configuration,
2458
- windows_set_configuration,
2459
- windows_claim_interface,
2460
- windows_release_interface,
2461
-
2462
- windows_set_interface_altsetting,
2463
- windows_clear_halt,
2464
- windows_reset_device,
2465
-
2466
- NULL, /* alloc_streams */
2467
- NULL, /* free_streams */
2468
-
2469
- windows_kernel_driver_active,
2470
- windows_detach_kernel_driver,
2471
- windows_attach_kernel_driver,
2472
-
2473
- windows_destroy_device,
2474
-
2475
- windows_submit_transfer,
2476
- windows_cancel_transfer,
2477
- windows_clear_transfer_priv,
2478
-
2479
- windows_handle_events,
2480
- NULL, /* handle_transfer_completion() */
2481
-
2482
- windows_clock_gettime,
2483
- #if defined(USBI_TIMERFD_AVAILABLE)
2484
- NULL,
2485
- #endif
2486
- sizeof(struct windows_device_priv),
2487
- sizeof(struct windows_device_handle_priv),
2488
- sizeof(struct windows_transfer_priv),
2489
- };
2490
-
2491
-
2492
- /*
2493
- * USB API backends
2494
- */
2495
- static int unsupported_init(int sub_api, struct libusb_context *ctx) {
2496
- return LIBUSB_SUCCESS;
2497
- }
2498
- static int unsupported_exit(int sub_api) {
2499
- return LIBUSB_SUCCESS;
2500
- }
2501
- static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) {
2502
- PRINT_UNSUPPORTED_API(open);
2503
- }
2504
- static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) {
2505
- usbi_dbg("unsupported API call for 'close'");
2506
- }
2507
- static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2508
- PRINT_UNSUPPORTED_API(configure_endpoints);
2509
- }
2510
- static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2511
- PRINT_UNSUPPORTED_API(claim_interface);
2512
- }
2513
- static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) {
2514
- PRINT_UNSUPPORTED_API(set_interface_altsetting);
2515
- }
2516
- static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2517
- PRINT_UNSUPPORTED_API(release_interface);
2518
- }
2519
- static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) {
2520
- PRINT_UNSUPPORTED_API(clear_halt);
2521
- }
2522
- static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) {
2523
- PRINT_UNSUPPORTED_API(reset_device);
2524
- }
2525
- static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
2526
- PRINT_UNSUPPORTED_API(submit_bulk_transfer);
2527
- }
2528
- static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
2529
- PRINT_UNSUPPORTED_API(submit_iso_transfer);
2530
- }
2531
- static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) {
2532
- PRINT_UNSUPPORTED_API(submit_control_transfer);
2533
- }
2534
- static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) {
2535
- PRINT_UNSUPPORTED_API(abort_control);
2536
- }
2537
- static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) {
2538
- PRINT_UNSUPPORTED_API(abort_transfers);
2539
- }
2540
- static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
2541
- PRINT_UNSUPPORTED_API(copy_transfer_data);
2542
- }
2543
- static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) {
2544
- return LIBUSB_SUCCESS;
2545
- }
2546
- // These names must be uppercase
2547
- const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "USB3HUB", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB", "VUSB3HUB", "AMDHUB30"};
2548
- const char* composite_driver_names[] = {"USBCCGP"};
2549
- const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
2550
- const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2551
- const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2552
- {
2553
- USB_API_UNSUPPORTED,
2554
- "Unsupported API",
2555
- NULL,
2556
- 0,
2557
- unsupported_init,
2558
- unsupported_exit,
2559
- unsupported_open,
2560
- unsupported_close,
2561
- unsupported_configure_endpoints,
2562
- unsupported_claim_interface,
2563
- unsupported_set_interface_altsetting,
2564
- unsupported_release_interface,
2565
- unsupported_clear_halt,
2566
- unsupported_reset_device,
2567
- unsupported_submit_bulk_transfer,
2568
- unsupported_submit_iso_transfer,
2569
- unsupported_submit_control_transfer,
2570
- unsupported_abort_control,
2571
- unsupported_abort_transfers,
2572
- unsupported_copy_transfer_data,
2573
- }, {
2574
- USB_API_HUB,
2575
- "HUB API",
2576
- hub_driver_names,
2577
- ARRAYSIZE(hub_driver_names),
2578
- unsupported_init,
2579
- unsupported_exit,
2580
- unsupported_open,
2581
- unsupported_close,
2582
- unsupported_configure_endpoints,
2583
- unsupported_claim_interface,
2584
- unsupported_set_interface_altsetting,
2585
- unsupported_release_interface,
2586
- unsupported_clear_halt,
2587
- unsupported_reset_device,
2588
- unsupported_submit_bulk_transfer,
2589
- unsupported_submit_iso_transfer,
2590
- unsupported_submit_control_transfer,
2591
- unsupported_abort_control,
2592
- unsupported_abort_transfers,
2593
- unsupported_copy_transfer_data,
2594
- }, {
2595
- USB_API_COMPOSITE,
2596
- "Composite API",
2597
- composite_driver_names,
2598
- ARRAYSIZE(composite_driver_names),
2599
- composite_init,
2600
- composite_exit,
2601
- composite_open,
2602
- composite_close,
2603
- common_configure_endpoints,
2604
- composite_claim_interface,
2605
- composite_set_interface_altsetting,
2606
- composite_release_interface,
2607
- composite_clear_halt,
2608
- composite_reset_device,
2609
- composite_submit_bulk_transfer,
2610
- composite_submit_iso_transfer,
2611
- composite_submit_control_transfer,
2612
- composite_abort_control,
2613
- composite_abort_transfers,
2614
- composite_copy_transfer_data,
2615
- }, {
2616
- USB_API_WINUSBX,
2617
- "WinUSB-like APIs",
2618
- winusbx_driver_names,
2619
- ARRAYSIZE(winusbx_driver_names),
2620
- winusbx_init,
2621
- winusbx_exit,
2622
- winusbx_open,
2623
- winusbx_close,
2624
- winusbx_configure_endpoints,
2625
- winusbx_claim_interface,
2626
- winusbx_set_interface_altsetting,
2627
- winusbx_release_interface,
2628
- winusbx_clear_halt,
2629
- winusbx_reset_device,
2630
- winusbx_submit_bulk_transfer,
2631
- unsupported_submit_iso_transfer,
2632
- winusbx_submit_control_transfer,
2633
- winusbx_abort_control,
2634
- winusbx_abort_transfers,
2635
- winusbx_copy_transfer_data,
2636
- }, {
2637
- USB_API_HID,
2638
- "HID API",
2639
- hid_driver_names,
2640
- ARRAYSIZE(hid_driver_names),
2641
- hid_init,
2642
- hid_exit,
2643
- hid_open,
2644
- hid_close,
2645
- common_configure_endpoints,
2646
- hid_claim_interface,
2647
- hid_set_interface_altsetting,
2648
- hid_release_interface,
2649
- hid_clear_halt,
2650
- hid_reset_device,
2651
- hid_submit_bulk_transfer,
2652
- unsupported_submit_iso_transfer,
2653
- hid_submit_control_transfer,
2654
- hid_abort_transfers,
2655
- hid_abort_transfers,
2656
- hid_copy_transfer_data,
2657
- },
2658
- };
2659
-
2660
-
2661
- /*
2662
- * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2663
- */
2664
- #define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
2665
- else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0)
2666
-
2667
- static int winusbx_init(int sub_api, struct libusb_context *ctx)
2668
- {
2669
- HMODULE h = NULL;
2670
- bool native_winusb = false;
2671
- int i;
2672
- KLIB_VERSION LibK_Version;
2673
- LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
2674
- LibK_GetVersion_t pLibK_GetVersion = NULL;
2675
-
2676
- h = GetModuleHandleA("libusbK");
2677
- if (h == NULL) {
2678
- h = LoadLibraryA("libusbK");
2679
- }
2680
- if (h == NULL) {
2681
- usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
2682
- h = GetModuleHandleA("WinUSB");
2683
- if (h == NULL) {
2684
- h = LoadLibraryA("WinUSB");
2685
- } if (h == NULL) {
2686
- usbi_warn(ctx, "WinUSB DLL is not available either, "
2687
- "you will not be able to access devices outside of enumeration");
2688
- return LIBUSB_ERROR_NOT_FOUND;
2689
- }
2690
- } else {
2691
- usbi_dbg("using libusbK DLL for universal access");
2692
- pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion");
2693
- if (pLibK_GetVersion != NULL) {
2694
- pLibK_GetVersion(&LibK_Version);
2695
- usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2696
- LibK_Version.Micro, LibK_Version.Nano);
2697
- }
2698
- pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress");
2699
- if (pLibK_GetProcAddress == NULL) {
2700
- usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2701
- return LIBUSB_ERROR_NOT_FOUND;
2702
- }
2703
- }
2704
- native_winusb = (pLibK_GetProcAddress == NULL);
2705
- for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) {
2706
- WinUSBX_Set(AbortPipe);
2707
- WinUSBX_Set(ControlTransfer);
2708
- WinUSBX_Set(FlushPipe);
2709
- WinUSBX_Set(Free);
2710
- WinUSBX_Set(GetAssociatedInterface);
2711
- WinUSBX_Set(GetCurrentAlternateSetting);
2712
- WinUSBX_Set(GetDescriptor);
2713
- WinUSBX_Set(GetOverlappedResult);
2714
- WinUSBX_Set(GetPipePolicy);
2715
- WinUSBX_Set(GetPowerPolicy);
2716
- WinUSBX_Set(Initialize);
2717
- WinUSBX_Set(QueryDeviceInformation);
2718
- WinUSBX_Set(QueryInterfaceSettings);
2719
- WinUSBX_Set(QueryPipe);
2720
- WinUSBX_Set(ReadPipe);
2721
- WinUSBX_Set(ResetPipe);
2722
- WinUSBX_Set(SetCurrentAlternateSetting);
2723
- WinUSBX_Set(SetPipePolicy);
2724
- WinUSBX_Set(SetPowerPolicy);
2725
- WinUSBX_Set(WritePipe);
2726
- if (!native_winusb) {
2727
- WinUSBX_Set(ResetDevice);
2728
- }
2729
- if (WinUSBX[i].Initialize != NULL) {
2730
- WinUSBX[i].initialized = true;
2731
- usbi_dbg("initalized sub API %s", sub_api_name[i]);
2732
- } else {
2733
- usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]);
2734
- WinUSBX[i].initialized = false;
2735
- }
2736
- }
2737
- return LIBUSB_SUCCESS;
2738
- }
2739
-
2740
- static int winusbx_exit(int sub_api)
2741
- {
2742
- return LIBUSB_SUCCESS;
2743
- }
2744
-
2745
- // NB: open and close must ensure that they only handle interface of
2746
- // the right API type, as these functions can be called wholesale from
2747
- // composite_open(), with interfaces belonging to different APIs
2748
- static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2749
- {
2750
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2751
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2752
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2753
-
2754
- HANDLE file_handle;
2755
- int i;
2756
-
2757
- CHECK_WINUSBX_AVAILABLE(sub_api);
2758
-
2759
- // WinUSB requires a seperate handle for each interface
2760
- for (i = 0; i < USB_MAXINTERFACES; i++) {
2761
- if ( (priv->usb_interface[i].path != NULL)
2762
- && (priv->usb_interface[i].apib->id == USB_API_WINUSBX) ) {
2763
- file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2764
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2765
- if (file_handle == INVALID_HANDLE_VALUE) {
2766
- usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2767
- switch(GetLastError()) {
2768
- case ERROR_FILE_NOT_FOUND: // The device was disconnected
2769
- return LIBUSB_ERROR_NO_DEVICE;
2770
- case ERROR_ACCESS_DENIED:
2771
- return LIBUSB_ERROR_ACCESS;
2772
- default:
2773
- return LIBUSB_ERROR_IO;
2774
- }
2775
- }
2776
- handle_priv->interface_handle[i].dev_handle = file_handle;
2777
- }
2778
- }
2779
-
2780
- return LIBUSB_SUCCESS;
2781
- }
2782
-
2783
- static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2784
- {
2785
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2786
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2787
- HANDLE handle;
2788
- int i;
2789
-
2790
- if (sub_api == SUB_API_NOTSET)
2791
- sub_api = priv->sub_api;
2792
- if (!WinUSBX[sub_api].initialized)
2793
- return;
2794
-
2795
- if (priv->apib->id == USB_API_COMPOSITE) {
2796
- // If this is a composite device, just free and close all WinUSB-like
2797
- // interfaces directly (each is independent and not associated with another)
2798
- for (i = 0; i < USB_MAXINTERFACES; i++) {
2799
- if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2800
- handle = handle_priv->interface_handle[i].api_handle;
2801
- if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
2802
- WinUSBX[sub_api].Free(handle);
2803
- }
2804
- handle = handle_priv->interface_handle[i].dev_handle;
2805
- if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
2806
- CloseHandle(handle);
2807
- }
2808
- }
2809
- }
2810
- }
2811
- else {
2812
- // If this is a WinUSB device, free all interfaces above interface 0,
2813
- // then free and close interface 0 last
2814
- for (i = 1; i < USB_MAXINTERFACES; i++) {
2815
- handle = handle_priv->interface_handle[i].api_handle;
2816
- if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
2817
- WinUSBX[sub_api].Free(handle);
2818
- }
2819
- }
2820
- handle = handle_priv->interface_handle[0].api_handle;
2821
- if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
2822
- WinUSBX[sub_api].Free(handle);
2823
- }
2824
- handle = handle_priv->interface_handle[0].dev_handle;
2825
- if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
2826
- CloseHandle(handle);
2827
- }
2828
- }
2829
- }
2830
-
2831
- static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2832
- {
2833
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2834
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2835
- HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2836
- UCHAR policy;
2837
- ULONG timeout = 0;
2838
- uint8_t endpoint_address;
2839
- int i;
2840
-
2841
- CHECK_WINUSBX_AVAILABLE(sub_api);
2842
-
2843
- // With handle and enpoints set (in parent), we can setup the default pipe properties
2844
- // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2845
- for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) {
2846
- endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i];
2847
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2848
- PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) {
2849
- usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2850
- }
2851
- if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) {
2852
- continue; // Other policies don't apply to control endpoint or libusb0
2853
- }
2854
- policy = false;
2855
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2856
- SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
2857
- usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2858
- }
2859
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2860
- IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) {
2861
- usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2862
- }
2863
- policy = true;
2864
- /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2865
- https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2866
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2867
- ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) {
2868
- usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2869
- }
2870
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2871
- AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) {
2872
- usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2873
- }
2874
- }
2875
-
2876
- return LIBUSB_SUCCESS;
2877
- }
2878
-
2879
- static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2880
- {
2881
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
2882
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2883
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2884
- bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2885
- HANDLE file_handle, winusb_handle;
2886
- DWORD err;
2887
- int i;
2888
- SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
2889
- HDEVINFO dev_info = INVALID_HANDLE_VALUE;
2890
- SP_DEVINFO_DATA dev_info_data;
2891
- char* dev_path_no_guid = NULL;
2892
- char filter_path[] = "\\\\.\\libusb0-0000";
2893
- bool found_filter = false;
2894
-
2895
- CHECK_WINUSBX_AVAILABLE(sub_api);
2896
-
2897
- // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2898
- // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2899
- if ((is_using_usbccgp) || (iface == 0)) {
2900
- // composite device (independent interfaces) or interface 0
2901
- file_handle = handle_priv->interface_handle[iface].dev_handle;
2902
- if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
2903
- return LIBUSB_ERROR_NOT_FOUND;
2904
- }
2905
-
2906
- if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2907
- handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2908
- err = GetLastError();
2909
- switch(err) {
2910
- case ERROR_BAD_COMMAND:
2911
- // The device was disconnected
2912
- usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
2913
- return LIBUSB_ERROR_NO_DEVICE;
2914
- default:
2915
- // it may be that we're using the libusb0 filter driver.
2916
- // TODO: can we move this whole business into the K/0 DLL?
2917
- for (i = 0; ; i++) {
2918
- safe_free(dev_interface_details);
2919
- safe_free(dev_path_no_guid);
2920
- dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path);
2921
- if ((found_filter) || (dev_interface_details == NULL)) {
2922
- break;
2923
- }
2924
- // ignore GUID part
2925
- dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{"));
2926
- if (safe_strncmp(dev_path_no_guid, priv->usb_interface[iface].path, safe_strlen(dev_path_no_guid)) == 0) {
2927
- file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
2928
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
2929
- if (file_handle == INVALID_HANDLE_VALUE) {
2930
- usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2931
- } else {
2932
- WinUSBX[sub_api].Free(winusb_handle);
2933
- if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle))
2934
- found_filter = true;
2935
- else
2936
- usbi_err(ctx, "could not initialize filter driver for %s", filter_path);
2937
- }
2938
- }
2939
- }
2940
- if (!found_filter) {
2941
- usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
2942
- return LIBUSB_ERROR_ACCESS;
2943
- }
2944
- }
2945
- }
2946
- handle_priv->interface_handle[iface].api_handle = winusb_handle;
2947
- } else {
2948
- // For all other interfaces, use GetAssociatedInterface()
2949
- winusb_handle = handle_priv->interface_handle[0].api_handle;
2950
- // It is a requirement for multiple interface devices on Windows that, to you
2951
- // must first claim the first interface before you claim the others
2952
- if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2953
- file_handle = handle_priv->interface_handle[0].dev_handle;
2954
- if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2955
- handle_priv->interface_handle[0].api_handle = winusb_handle;
2956
- usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
2957
- } else {
2958
- usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
2959
- return LIBUSB_ERROR_ACCESS;
2960
- }
2961
- }
2962
- if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1),
2963
- &handle_priv->interface_handle[iface].api_handle)) {
2964
- handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2965
- switch(GetLastError()) {
2966
- case ERROR_NO_MORE_ITEMS: // invalid iface
2967
- return LIBUSB_ERROR_NOT_FOUND;
2968
- case ERROR_BAD_COMMAND: // The device was disconnected
2969
- return LIBUSB_ERROR_NO_DEVICE;
2970
- case ERROR_ALREADY_EXISTS: // already claimed
2971
- return LIBUSB_ERROR_BUSY;
2972
- default:
2973
- usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
2974
- return LIBUSB_ERROR_ACCESS;
2975
- }
2976
- }
2977
- }
2978
- usbi_dbg("claimed interface %d", iface);
2979
- handle_priv->active_interface = iface;
2980
-
2981
- return LIBUSB_SUCCESS;
2982
- }
2983
-
2984
- static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
2985
- {
2986
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
2987
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
2988
- HANDLE winusb_handle;
2989
-
2990
- CHECK_WINUSBX_AVAILABLE(sub_api);
2991
-
2992
- winusb_handle = handle_priv->interface_handle[iface].api_handle;
2993
- if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
2994
- return LIBUSB_ERROR_NOT_FOUND;
2995
- }
2996
-
2997
- WinUSBX[sub_api].Free(winusb_handle);
2998
- handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2999
-
3000
- return LIBUSB_SUCCESS;
3001
- }
3002
-
3003
- /*
3004
- * Return the first valid interface (of the same API type), for control transfers
3005
- */
3006
- static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
3007
- {
3008
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3009
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3010
- int i;
3011
-
3012
- if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
3013
- usbi_dbg("unsupported API ID");
3014
- return -1;
3015
- }
3016
-
3017
- for (i=0; i<USB_MAXINTERFACES; i++) {
3018
- if ( (handle_priv->interface_handle[i].dev_handle != 0)
3019
- && (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
3020
- && (handle_priv->interface_handle[i].api_handle != 0)
3021
- && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
3022
- && (priv->usb_interface[i].apib->id == api_id) ) {
3023
- return i;
3024
- }
3025
- }
3026
- return -1;
3027
- }
3028
-
3029
- /*
3030
- * Lookup interface by endpoint address. -1 if not found
3031
- */
3032
- static int interface_by_endpoint(struct windows_device_priv *priv,
3033
- struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address)
3034
- {
3035
- int i, j;
3036
- for (i=0; i<USB_MAXINTERFACES; i++) {
3037
- if (handle_priv->interface_handle[i].api_handle == INVALID_HANDLE_VALUE)
3038
- continue;
3039
- if (handle_priv->interface_handle[i].api_handle == 0)
3040
- continue;
3041
- if (priv->usb_interface[i].endpoint == NULL)
3042
- continue;
3043
- for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3044
- if (priv->usb_interface[i].endpoint[j] == endpoint_address) {
3045
- return i;
3046
- }
3047
- }
3048
- }
3049
- return -1;
3050
- }
3051
-
3052
- static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
3053
- {
3054
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3055
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3056
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3057
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3058
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(
3059
- transfer->dev_handle);
3060
- WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
3061
- ULONG size;
3062
- HANDLE winusb_handle;
3063
- int current_interface;
3064
- struct winfd wfd;
3065
-
3066
- CHECK_WINUSBX_AVAILABLE(sub_api);
3067
-
3068
- transfer_priv->pollable_fd = INVALID_WINFD;
3069
- size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
3070
-
3071
- if (size > MAX_CTRL_BUFFER_LENGTH)
3072
- return LIBUSB_ERROR_INVALID_PARAM;
3073
-
3074
- current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
3075
- if (current_interface < 0) {
3076
- if (auto_claim(transfer, &current_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) {
3077
- return LIBUSB_ERROR_NOT_FOUND;
3078
- }
3079
- }
3080
-
3081
- usbi_dbg("will use interface %d", current_interface);
3082
- winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3083
-
3084
- wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
3085
- // Always use the handle returned from usbi_create_fd (wfd.handle)
3086
- if (wfd.fd < 0) {
3087
- return LIBUSB_ERROR_NO_MEM;
3088
- }
3089
-
3090
- // Sending of set configuration control requests from WinUSB creates issues
3091
- if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
3092
- && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
3093
- if (setup->value != priv->active_config) {
3094
- usbi_warn(ctx, "cannot set configuration other than the default one");
3095
- usbi_free_fd(&wfd);
3096
- return LIBUSB_ERROR_INVALID_PARAM;
3097
- }
3098
- wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3099
- wfd.overlapped->InternalHigh = 0;
3100
- } else {
3101
- if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
3102
- if(GetLastError() != ERROR_IO_PENDING) {
3103
- usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
3104
- usbi_free_fd(&wfd);
3105
- return LIBUSB_ERROR_IO;
3106
- }
3107
- } else {
3108
- wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3109
- wfd.overlapped->InternalHigh = (DWORD)size;
3110
- }
3111
- }
3112
-
3113
- // Use priv_transfer to store data needed for async polling
3114
- transfer_priv->pollable_fd = wfd;
3115
- transfer_priv->interface_number = (uint8_t)current_interface;
3116
-
3117
- return LIBUSB_SUCCESS;
3118
- }
3119
-
3120
- static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
3121
- {
3122
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3123
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3124
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3125
- HANDLE winusb_handle;
3126
-
3127
- CHECK_WINUSBX_AVAILABLE(sub_api);
3128
-
3129
- if (altsetting > 255) {
3130
- return LIBUSB_ERROR_INVALID_PARAM;
3131
- }
3132
-
3133
- winusb_handle = handle_priv->interface_handle[iface].api_handle;
3134
- if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
3135
- usbi_err(ctx, "interface must be claimed first");
3136
- return LIBUSB_ERROR_NOT_FOUND;
3137
- }
3138
-
3139
- if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) {
3140
- usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
3141
- return LIBUSB_ERROR_IO;
3142
- }
3143
-
3144
- return LIBUSB_SUCCESS;
3145
- }
3146
-
3147
- static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
3148
- {
3149
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3150
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3151
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3152
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3153
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3154
- HANDLE winusb_handle;
3155
- bool ret;
3156
- int current_interface;
3157
- struct winfd wfd;
3158
-
3159
- CHECK_WINUSBX_AVAILABLE(sub_api);
3160
-
3161
- transfer_priv->pollable_fd = INVALID_WINFD;
3162
-
3163
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3164
- if (current_interface < 0) {
3165
- usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
3166
- return LIBUSB_ERROR_NOT_FOUND;
3167
- }
3168
-
3169
- usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3170
-
3171
- winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3172
-
3173
- wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
3174
- // Always use the handle returned from usbi_create_fd (wfd.handle)
3175
- if (wfd.fd < 0) {
3176
- return LIBUSB_ERROR_NO_MEM;
3177
- }
3178
-
3179
- if (IS_XFERIN(transfer)) {
3180
- usbi_dbg("reading %d bytes", transfer->length);
3181
- ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
3182
- } else {
3183
- usbi_dbg("writing %d bytes", transfer->length);
3184
- ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped);
3185
- }
3186
- if (!ret) {
3187
- if(GetLastError() != ERROR_IO_PENDING) {
3188
- usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
3189
- usbi_free_fd(&wfd);
3190
- return LIBUSB_ERROR_IO;
3191
- }
3192
- } else {
3193
- wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
3194
- wfd.overlapped->InternalHigh = (DWORD)transfer->length;
3195
- }
3196
-
3197
- transfer_priv->pollable_fd = wfd;
3198
- transfer_priv->interface_number = (uint8_t)current_interface;
3199
-
3200
- return LIBUSB_SUCCESS;
3201
- }
3202
-
3203
- static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3204
- {
3205
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3206
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3207
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3208
- HANDLE winusb_handle;
3209
- int current_interface;
3210
-
3211
- CHECK_WINUSBX_AVAILABLE(sub_api);
3212
-
3213
- current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3214
- if (current_interface < 0) {
3215
- usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
3216
- return LIBUSB_ERROR_NOT_FOUND;
3217
- }
3218
-
3219
- usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
3220
- winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3221
-
3222
- if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3223
- usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
3224
- return LIBUSB_ERROR_NO_DEVICE;
3225
- }
3226
-
3227
- return LIBUSB_SUCCESS;
3228
- }
3229
-
3230
- /*
3231
- * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed
3232
- * through testing as well):
3233
- * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel
3234
- * the control transfer using CancelIo"
3235
- */
3236
- static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer)
3237
- {
3238
- // Cancelling of the I/O is done in the parent
3239
- return LIBUSB_SUCCESS;
3240
- }
3241
-
3242
- static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
3243
- {
3244
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3245
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
3246
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
3247
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
3248
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
3249
- HANDLE winusb_handle;
3250
- int current_interface;
3251
-
3252
- CHECK_WINUSBX_AVAILABLE(sub_api);
3253
-
3254
- current_interface = transfer_priv->interface_number;
3255
- if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
3256
- usbi_err(ctx, "program assertion failed: invalid interface_number");
3257
- return LIBUSB_ERROR_NOT_FOUND;
3258
- }
3259
- usbi_dbg("will use interface %d", current_interface);
3260
-
3261
- winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3262
-
3263
- if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) {
3264
- usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
3265
- return LIBUSB_ERROR_NO_DEVICE;
3266
- }
3267
-
3268
- return LIBUSB_SUCCESS;
3269
- }
3270
-
3271
- /*
3272
- * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3273
- * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3274
- * "WinUSB does not support host-initiated reset port and cycle port operations" and
3275
- * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3276
- * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3277
- * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3278
- */
3279
- // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3280
- static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3281
- {
3282
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3283
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3284
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3285
- struct winfd wfd;
3286
- HANDLE winusb_handle;
3287
- int i, j;
3288
-
3289
- CHECK_WINUSBX_AVAILABLE(sub_api);
3290
-
3291
- // Reset any available pipe (except control)
3292
- for (i=0; i<USB_MAXINTERFACES; i++) {
3293
- winusb_handle = handle_priv->interface_handle[i].api_handle;
3294
- for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0;)
3295
- {
3296
- // Cancel any pollable I/O
3297
- usbi_remove_pollfd(ctx, wfd.fd);
3298
- usbi_free_fd(&wfd);
3299
- wfd = handle_to_winfd(winusb_handle);
3300
- }
3301
-
3302
- if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3303
- for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) {
3304
- usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3305
- if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3306
- usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s",
3307
- priv->usb_interface[i].endpoint[j], windows_error_str(0));
3308
- }
3309
- // FlushPipe seems to fail on OUT pipes
3310
- if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3311
- && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) {
3312
- usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s",
3313
- priv->usb_interface[i].endpoint[j], windows_error_str(0));
3314
- }
3315
- if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) {
3316
- usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s",
3317
- priv->usb_interface[i].endpoint[j], windows_error_str(0));
3318
- }
3319
- }
3320
- }
3321
- }
3322
-
3323
- // libusbK & libusb0 have the ability to issue an actual device reset
3324
- if (WinUSBX[sub_api].ResetDevice != NULL) {
3325
- winusb_handle = handle_priv->interface_handle[0].api_handle;
3326
- if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) {
3327
- WinUSBX[sub_api].ResetDevice(winusb_handle);
3328
- }
3329
- }
3330
- return LIBUSB_SUCCESS;
3331
- }
3332
-
3333
- static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
3334
- {
3335
- itransfer->transferred += io_size;
3336
- return LIBUSB_TRANSFER_COMPLETED;
3337
- }
3338
-
3339
- /*
3340
- * Internal HID Support functions (from libusb-win32)
3341
- * Note that functions that complete data transfer synchronously must return
3342
- * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3343
- */
3344
- static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3345
- static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
3346
-
3347
- static int _hid_wcslen(WCHAR *str)
3348
- {
3349
- int i = 0;
3350
- while (str[i] && (str[i] != 0x409)) {
3351
- i++;
3352
- }
3353
- return i;
3354
- }
3355
-
3356
- static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3357
- {
3358
- struct libusb_device_descriptor d;
3359
-
3360
- d.bLength = LIBUSB_DT_DEVICE_SIZE;
3361
- d.bDescriptorType = LIBUSB_DT_DEVICE;
3362
- d.bcdUSB = 0x0200; /* 2.00 */
3363
- d.bDeviceClass = 0;
3364
- d.bDeviceSubClass = 0;
3365
- d.bDeviceProtocol = 0;
3366
- d.bMaxPacketSize0 = 64; /* fix this! */
3367
- d.idVendor = (uint16_t)dev->vid;
3368
- d.idProduct = (uint16_t)dev->pid;
3369
- d.bcdDevice = 0x0100;
3370
- d.iManufacturer = dev->string_index[0];
3371
- d.iProduct = dev->string_index[1];
3372
- d.iSerialNumber = dev->string_index[2];
3373
- d.bNumConfigurations = 1;
3374
-
3375
- if (*size > LIBUSB_DT_DEVICE_SIZE)
3376
- *size = LIBUSB_DT_DEVICE_SIZE;
3377
- memcpy(data, &d, *size);
3378
- return LIBUSB_COMPLETED;
3379
- }
3380
-
3381
- static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3382
- {
3383
- char num_endpoints = 0;
3384
- size_t config_total_len = 0;
3385
- char tmp[HID_MAX_CONFIG_DESC_SIZE];
3386
- struct libusb_config_descriptor *cd;
3387
- struct libusb_interface_descriptor *id;
3388
- struct libusb_hid_descriptor *hd;
3389
- struct libusb_endpoint_descriptor *ed;
3390
- size_t tmp_size;
3391
-
3392
- if (dev->input_report_size)
3393
- num_endpoints++;
3394
- if (dev->output_report_size)
3395
- num_endpoints++;
3396
-
3397
- config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3398
- + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3399
-
3400
-
3401
- cd = (struct libusb_config_descriptor *)tmp;
3402
- id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3403
- hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3404
- + LIBUSB_DT_INTERFACE_SIZE);
3405
- ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3406
- + LIBUSB_DT_INTERFACE_SIZE
3407
- + LIBUSB_DT_HID_SIZE);
3408
-
3409
- cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3410
- cd->bDescriptorType = LIBUSB_DT_CONFIG;
3411
- cd->wTotalLength = (uint16_t) config_total_len;
3412
- cd->bNumInterfaces = 1;
3413
- cd->bConfigurationValue = 1;
3414
- cd->iConfiguration = 0;
3415
- cd->bmAttributes = 1 << 7; /* bus powered */
3416
- cd->MaxPower = 50;
3417
-
3418
- id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3419
- id->bDescriptorType = LIBUSB_DT_INTERFACE;
3420
- id->bInterfaceNumber = 0;
3421
- id->bAlternateSetting = 0;
3422
- id->bNumEndpoints = num_endpoints;
3423
- id->bInterfaceClass = 3;
3424
- id->bInterfaceSubClass = 0;
3425
- id->bInterfaceProtocol = 0;
3426
- id->iInterface = 0;
3427
-
3428
- tmp_size = LIBUSB_DT_HID_SIZE;
3429
- _hid_get_hid_descriptor(dev, hd, &tmp_size);
3430
-
3431
- if (dev->input_report_size) {
3432
- ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3433
- ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3434
- ed->bEndpointAddress = HID_IN_EP;
3435
- ed->bmAttributes = 3;
3436
- ed->wMaxPacketSize = dev->input_report_size - 1;
3437
- ed->bInterval = 10;
3438
- ed = (struct libusb_endpoint_descriptor *)((char*)ed + LIBUSB_DT_ENDPOINT_SIZE);
3439
- }
3440
-
3441
- if (dev->output_report_size) {
3442
- ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3443
- ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3444
- ed->bEndpointAddress = HID_OUT_EP;
3445
- ed->bmAttributes = 3;
3446
- ed->wMaxPacketSize = dev->output_report_size - 1;
3447
- ed->bInterval = 10;
3448
- }
3449
-
3450
- if (*size > config_total_len)
3451
- *size = config_total_len;
3452
- memcpy(data, tmp, *size);
3453
- return LIBUSB_COMPLETED;
3454
- }
3455
-
3456
- static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
3457
- void *data, size_t *size)
3458
- {
3459
- void *tmp = NULL;
3460
- size_t tmp_size = 0;
3461
- int i;
3462
-
3463
- /* language ID, EN-US */
3464
- char string_langid[] = {
3465
- 0x09,
3466
- 0x04
3467
- };
3468
-
3469
- if ((*size < 2) || (*size > 255)) {
3470
- return LIBUSB_ERROR_OVERFLOW;
3471
- }
3472
-
3473
- if (_index == 0) {
3474
- tmp = string_langid;
3475
- tmp_size = sizeof(string_langid)+2;
3476
- } else {
3477
- for (i=0; i<3; i++) {
3478
- if (_index == (dev->string_index[i])) {
3479
- tmp = dev->string[i];
3480
- tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
3481
- break;
3482
- }
3483
- }
3484
- if (i == 3) { // not found
3485
- return LIBUSB_ERROR_INVALID_PARAM;
3486
- }
3487
- }
3488
-
3489
- if(!tmp_size) {
3490
- return LIBUSB_ERROR_INVALID_PARAM;
3491
- }
3492
-
3493
- if (tmp_size < *size) {
3494
- *size = tmp_size;
3495
- }
3496
- // 2 byte header
3497
- ((uint8_t*)data)[0] = (uint8_t)*size;
3498
- ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
3499
- memcpy((uint8_t*)data+2, tmp, *size-2);
3500
- return LIBUSB_COMPLETED;
3501
- }
3502
-
3503
- static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3504
- {
3505
- struct libusb_hid_descriptor d;
3506
- uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3507
- size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3508
-
3509
- _hid_get_report_descriptor(dev, tmp, &report_len);
3510
-
3511
- d.bLength = LIBUSB_DT_HID_SIZE;
3512
- d.bDescriptorType = LIBUSB_DT_HID;
3513
- d.bcdHID = 0x0110; /* 1.10 */
3514
- d.bCountryCode = 0;
3515
- d.bNumDescriptors = 1;
3516
- d.bClassDescriptorType = LIBUSB_DT_REPORT;
3517
- d.wClassDescriptorLength = (uint16_t)report_len;
3518
-
3519
- if (*size > LIBUSB_DT_HID_SIZE)
3520
- *size = LIBUSB_DT_HID_SIZE;
3521
- memcpy(data, &d, *size);
3522
- return LIBUSB_COMPLETED;
3523
- }
3524
-
3525
- static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
3526
- {
3527
- uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3528
- size_t i = 0;
3529
-
3530
- /* usage page (0xFFA0 == vendor defined) */
3531
- d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
3532
- /* usage (vendor defined) */
3533
- d[i++] = 0x09; d[i++] = 0x01;
3534
- /* start collection (application) */
3535
- d[i++] = 0xA1; d[i++] = 0x01;
3536
- /* input report */
3537
- if (dev->input_report_size) {
3538
- /* usage (vendor defined) */
3539
- d[i++] = 0x09; d[i++] = 0x01;
3540
- /* logical minimum (0) */
3541
- d[i++] = 0x15; d[i++] = 0x00;
3542
- /* logical maximum (255) */
3543
- d[i++] = 0x25; d[i++] = 0xFF;
3544
- /* report size (8 bits) */
3545
- d[i++] = 0x75; d[i++] = 0x08;
3546
- /* report count */
3547
- d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
3548
- /* input (data, variable, absolute) */
3549
- d[i++] = 0x81; d[i++] = 0x00;
3550
- }
3551
- /* output report */
3552
- if (dev->output_report_size) {
3553
- /* usage (vendor defined) */
3554
- d[i++] = 0x09; d[i++] = 0x02;
3555
- /* logical minimum (0) */
3556
- d[i++] = 0x15; d[i++] = 0x00;
3557
- /* logical maximum (255) */
3558
- d[i++] = 0x25; d[i++] = 0xFF;
3559
- /* report size (8 bits) */
3560
- d[i++] = 0x75; d[i++] = 0x08;
3561
- /* report count */
3562
- d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
3563
- /* output (data, variable, absolute) */
3564
- d[i++] = 0x91; d[i++] = 0x00;
3565
- }
3566
- /* feature report */
3567
- if (dev->feature_report_size) {
3568
- /* usage (vendor defined) */
3569
- d[i++] = 0x09; d[i++] = 0x03;
3570
- /* logical minimum (0) */
3571
- d[i++] = 0x15; d[i++] = 0x00;
3572
- /* logical maximum (255) */
3573
- d[i++] = 0x25; d[i++] = 0xFF;
3574
- /* report size (8 bits) */
3575
- d[i++] = 0x75; d[i++] = 0x08;
3576
- /* report count */
3577
- d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
3578
- /* feature (data, variable, absolute) */
3579
- d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3580
- }
3581
-
3582
- /* end collection */
3583
- d[i++] = 0xC0;
3584
-
3585
- if (*size > i)
3586
- *size = i;
3587
- memcpy(data, d, *size);
3588
- return LIBUSB_COMPLETED;
3589
- }
3590
-
3591
- static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
3592
- int type, int _index, void *data, size_t *size)
3593
- {
3594
- switch(type) {
3595
- case LIBUSB_DT_DEVICE:
3596
- usbi_dbg("LIBUSB_DT_DEVICE");
3597
- return _hid_get_device_descriptor(dev, data, size);
3598
- case LIBUSB_DT_CONFIG:
3599
- usbi_dbg("LIBUSB_DT_CONFIG");
3600
- if (!_index)
3601
- return _hid_get_config_descriptor(dev, data, size);
3602
- return LIBUSB_ERROR_INVALID_PARAM;
3603
- case LIBUSB_DT_STRING:
3604
- usbi_dbg("LIBUSB_DT_STRING");
3605
- return _hid_get_string_descriptor(dev, _index, data, size);
3606
- case LIBUSB_DT_HID:
3607
- usbi_dbg("LIBUSB_DT_HID");
3608
- if (!_index)
3609
- return _hid_get_hid_descriptor(dev, data, size);
3610
- return LIBUSB_ERROR_INVALID_PARAM;
3611
- case LIBUSB_DT_REPORT:
3612
- usbi_dbg("LIBUSB_DT_REPORT");
3613
- if (!_index)
3614
- return _hid_get_report_descriptor(dev, data, size);
3615
- return LIBUSB_ERROR_INVALID_PARAM;
3616
- case LIBUSB_DT_PHYSICAL:
3617
- usbi_dbg("LIBUSB_DT_PHYSICAL");
3618
- if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3619
- return LIBUSB_COMPLETED;
3620
- return LIBUSB_ERROR_OTHER;
3621
- }
3622
- usbi_dbg("unsupported");
3623
- return LIBUSB_ERROR_NOT_SUPPORTED;
3624
- }
3625
-
3626
- static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3627
- struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3628
- int report_type)
3629
- {
3630
- uint8_t *buf;
3631
- DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
3632
- int r = LIBUSB_SUCCESS;
3633
-
3634
- if (tp->hid_buffer != NULL) {
3635
- usbi_dbg("program assertion failed: hid_buffer is not NULL");
3636
- }
3637
-
3638
- if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3639
- usbi_dbg("invalid size (%d)", *size);
3640
- return LIBUSB_ERROR_INVALID_PARAM;
3641
- }
3642
-
3643
- switch (report_type) {
3644
- case HID_REPORT_TYPE_INPUT:
3645
- ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3646
- break;
3647
- case HID_REPORT_TYPE_FEATURE:
3648
- ioctl_code = IOCTL_HID_GET_FEATURE;
3649
- break;
3650
- default:
3651
- usbi_dbg("unknown HID report type %d", report_type);
3652
- return LIBUSB_ERROR_INVALID_PARAM;
3653
- }
3654
-
3655
- // Add a trailing byte to detect overflows
3656
- buf = (uint8_t*)calloc(expected_size+1, 1);
3657
- if (buf == NULL) {
3658
- return LIBUSB_ERROR_NO_MEM;
3659
- }
3660
- buf[0] = (uint8_t)id; // Must be set always
3661
- usbi_dbg("report ID: 0x%02X", buf[0]);
3662
-
3663
- tp->hid_expected_size = expected_size;
3664
- read_size = expected_size;
3665
-
3666
- // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3667
- if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
3668
- buf, expected_size+1, &read_size, overlapped)) {
3669
- if (GetLastError() != ERROR_IO_PENDING) {
3670
- usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
3671
- safe_free(buf);
3672
- return LIBUSB_ERROR_IO;
3673
- }
3674
- // Asynchronous wait
3675
- tp->hid_buffer = buf;
3676
- tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
3677
- return LIBUSB_SUCCESS;
3678
- }
3679
-
3680
- // Transfer completed synchronously => copy and discard extra buffer
3681
- if (read_size == 0) {
3682
- usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
3683
- *size = 0;
3684
- } else {
3685
- if (buf[0] != id) {
3686
- usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3687
- }
3688
- if ((size_t)read_size > expected_size) {
3689
- r = LIBUSB_ERROR_OVERFLOW;
3690
- usbi_dbg("OVERFLOW!");
3691
- } else {
3692
- r = LIBUSB_COMPLETED;
3693
- }
3694
-
3695
- *size = MIN((size_t)read_size, *size);
3696
- if (id == 0) {
3697
- // Discard report ID
3698
- memcpy(data, buf+1, *size);
3699
- } else {
3700
- memcpy(data, buf, *size);
3701
- }
3702
- }
3703
- safe_free(buf);
3704
- return r;
3705
- }
3706
-
3707
- static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
3708
- struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
3709
- int report_type)
3710
- {
3711
- uint8_t *buf = NULL;
3712
- DWORD ioctl_code, write_size= (DWORD)*size;
3713
-
3714
- if (tp->hid_buffer != NULL) {
3715
- usbi_dbg("program assertion failed: hid_buffer is not NULL");
3716
- }
3717
-
3718
- if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
3719
- usbi_dbg("invalid size (%d)", *size);
3720
- return LIBUSB_ERROR_INVALID_PARAM;
3721
- }
3722
-
3723
- switch (report_type) {
3724
- case HID_REPORT_TYPE_OUTPUT:
3725
- ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3726
- break;
3727
- case HID_REPORT_TYPE_FEATURE:
3728
- ioctl_code = IOCTL_HID_SET_FEATURE;
3729
- break;
3730
- default:
3731
- usbi_dbg("unknown HID report type %d", report_type);
3732
- return LIBUSB_ERROR_INVALID_PARAM;
3733
- }
3734
-
3735
- usbi_dbg("report ID: 0x%02X", id);
3736
- // When report IDs are not used (i.e. when id == 0), we must add
3737
- // a null report ID. Otherwise, we just use original data buffer
3738
- if (id == 0) {
3739
- write_size++;
3740
- }
3741
- buf = (uint8_t*) malloc(write_size);
3742
- if (buf == NULL) {
3743
- return LIBUSB_ERROR_NO_MEM;
3744
- }
3745
- if (id == 0) {
3746
- buf[0] = 0;
3747
- memcpy(buf + 1, data, *size);
3748
- } else {
3749
- // This seems like a waste, but if we don't duplicate the
3750
- // data, we'll get issues when freeing hid_buffer
3751
- memcpy(buf, data, *size);
3752
- if (buf[0] != id) {
3753
- usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3754
- }
3755
- }
3756
-
3757
- // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3758
- if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3759
- buf, write_size, &write_size, overlapped)) {
3760
- if (GetLastError() != ERROR_IO_PENDING) {
3761
- usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
3762
- safe_free(buf);
3763
- return LIBUSB_ERROR_IO;
3764
- }
3765
- tp->hid_buffer = buf;
3766
- tp->hid_dest = NULL;
3767
- return LIBUSB_SUCCESS;
3768
- }
3769
-
3770
- // Transfer completed synchronously
3771
- *size = write_size;
3772
- if (write_size == 0) {
3773
- usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
3774
- }
3775
- safe_free(buf);
3776
- return LIBUSB_COMPLETED;
3777
- }
3778
-
3779
- static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
3780
- int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
3781
- size_t *size, OVERLAPPED* overlapped)
3782
- {
3783
- int report_type = (value >> 8) & 0xFF;
3784
- int report_id = value & 0xFF;
3785
-
3786
- if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3787
- && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
3788
- return LIBUSB_ERROR_INVALID_PARAM;
3789
-
3790
- if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3791
- return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3792
-
3793
- if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3794
- return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3795
-
3796
- return LIBUSB_ERROR_INVALID_PARAM;
3797
- }
3798
-
3799
-
3800
- /*
3801
- * HID API functions
3802
- */
3803
- static int hid_init(int sub_api, struct libusb_context *ctx)
3804
- {
3805
- DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
3806
- DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
3807
- DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
3808
- DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
3809
- DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
3810
- DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
3811
- DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
3812
- DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
3813
- DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
3814
- DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
3815
- DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
3816
- DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
3817
- DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
3818
- DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
3819
- DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
3820
- DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
3821
-
3822
- api_hid_available = true;
3823
- return LIBUSB_SUCCESS;
3824
- }
3825
-
3826
- static int hid_exit(int sub_api)
3827
- {
3828
- return LIBUSB_SUCCESS;
3829
- }
3830
-
3831
- // NB: open and close must ensure that they only handle interface of
3832
- // the right API type, as these functions can be called wholesale from
3833
- // composite_open(), with interfaces belonging to different APIs
3834
- static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3835
- {
3836
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
3837
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3838
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3839
-
3840
- HIDD_ATTRIBUTES hid_attributes;
3841
- PHIDP_PREPARSED_DATA preparsed_data = NULL;
3842
- HIDP_CAPS capabilities;
3843
- HIDP_VALUE_CAPS *value_caps;
3844
-
3845
- HANDLE hid_handle = INVALID_HANDLE_VALUE;
3846
- int i, j;
3847
- // report IDs handling
3848
- ULONG size[3];
3849
- const char* type[3] = {"input", "output", "feature"};
3850
- int nb_ids[2]; // zero and nonzero report IDs
3851
-
3852
- CHECK_HID_AVAILABLE;
3853
- if (priv->hid == NULL) {
3854
- usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
3855
- return LIBUSB_ERROR_NOT_FOUND;
3856
- }
3857
-
3858
- for (i = 0; i < USB_MAXINTERFACES; i++) {
3859
- if ( (priv->usb_interface[i].path != NULL)
3860
- && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
3861
- hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
3862
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3863
- /*
3864
- * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3865
- * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3866
- * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
3867
- * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
3868
- * HidD_GetFeature (if the device supports Feature reports)."
3869
- */
3870
- if (hid_handle == INVALID_HANDLE_VALUE) {
3871
- usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
3872
- hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
3873
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
3874
- if (hid_handle == INVALID_HANDLE_VALUE) {
3875
- usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
3876
- switch(GetLastError()) {
3877
- case ERROR_FILE_NOT_FOUND: // The device was disconnected
3878
- return LIBUSB_ERROR_NO_DEVICE;
3879
- case ERROR_ACCESS_DENIED:
3880
- return LIBUSB_ERROR_ACCESS;
3881
- default:
3882
- return LIBUSB_ERROR_IO;
3883
- }
3884
- }
3885
- priv->usb_interface[i].restricted_functionality = true;
3886
- }
3887
- handle_priv->interface_handle[i].api_handle = hid_handle;
3888
- }
3889
- }
3890
-
3891
- hid_attributes.Size = sizeof(hid_attributes);
3892
- do {
3893
- if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
3894
- usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
3895
- break;
3896
- }
3897
-
3898
- priv->hid->vid = hid_attributes.VendorID;
3899
- priv->hid->pid = hid_attributes.ProductID;
3900
-
3901
- // Set the maximum available input buffer size
3902
- for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
3903
- usbi_dbg("set maximum input buffer size to %d", i/2);
3904
-
3905
- // Get the maximum input and output report size
3906
- if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
3907
- usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
3908
- break;
3909
- }
3910
- if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
3911
- usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
3912
- break;
3913
- }
3914
-
3915
- // Find out if interrupt will need report IDs
3916
- size[0] = capabilities.NumberInputValueCaps;
3917
- size[1] = capabilities.NumberOutputValueCaps;
3918
- size[2] = capabilities.NumberFeatureValueCaps;
3919
- for (j=HidP_Input; j<=HidP_Feature; j++) {
3920
- usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
3921
- priv->hid->uses_report_ids[j] = false;
3922
- if (size[j] > 0) {
3923
- value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS));
3924
- if ( (value_caps != NULL)
3925
- && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
3926
- && (size[j] >= 1) ) {
3927
- nb_ids[0] = 0;
3928
- nb_ids[1] = 0;
3929
- for (i=0; i<(int)size[j]; i++) {
3930
- usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
3931
- if (value_caps[i].ReportID != 0) {
3932
- nb_ids[1]++;
3933
- } else {
3934
- nb_ids[0]++;
3935
- }
3936
- }
3937
- if (nb_ids[1] != 0) {
3938
- if (nb_ids[0] != 0) {
3939
- usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
3940
- type[j]);
3941
- }
3942
- priv->hid->uses_report_ids[j] = true;
3943
- }
3944
- } else {
3945
- usbi_warn(ctx, " could not process %s report IDs", type[j]);
3946
- }
3947
- safe_free(value_caps);
3948
- }
3949
- }
3950
-
3951
- // Set the report sizes
3952
- priv->hid->input_report_size = capabilities.InputReportByteLength;
3953
- priv->hid->output_report_size = capabilities.OutputReportByteLength;
3954
- priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
3955
-
3956
- // Fetch string descriptors
3957
- priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
3958
- if (priv->hid->string_index[0] != 0) {
3959
- HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
3960
- sizeof(priv->hid->string[0]));
3961
- } else {
3962
- priv->hid->string[0][0] = 0;
3963
- }
3964
- priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
3965
- if (priv->hid->string_index[1] != 0) {
3966
- HidD_GetProductString(hid_handle, priv->hid->string[1],
3967
- sizeof(priv->hid->string[1]));
3968
- } else {
3969
- priv->hid->string[1][0] = 0;
3970
- }
3971
- priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
3972
- if (priv->hid->string_index[2] != 0) {
3973
- HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
3974
- sizeof(priv->hid->string[2]));
3975
- } else {
3976
- priv->hid->string[2][0] = 0;
3977
- }
3978
- } while(0);
3979
-
3980
- if (preparsed_data) {
3981
- HidD_FreePreparsedData(preparsed_data);
3982
- }
3983
-
3984
- return LIBUSB_SUCCESS;
3985
- }
3986
-
3987
- static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
3988
- {
3989
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
3990
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
3991
- HANDLE file_handle;
3992
- int i;
3993
-
3994
- if (!api_hid_available)
3995
- return;
3996
-
3997
- for (i = 0; i < USB_MAXINTERFACES; i++) {
3998
- if (priv->usb_interface[i].apib->id == USB_API_HID) {
3999
- file_handle = handle_priv->interface_handle[i].api_handle;
4000
- if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
4001
- CloseHandle(file_handle);
4002
- }
4003
- }
4004
- }
4005
- }
4006
-
4007
- static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4008
- {
4009
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4010
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4011
-
4012
- CHECK_HID_AVAILABLE;
4013
-
4014
- // NB: Disconnection detection is not possible in this function
4015
- if (priv->usb_interface[iface].path == NULL) {
4016
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
4017
- }
4018
-
4019
- // We use dev_handle as a flag for interface claimed
4020
- if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
4021
- return LIBUSB_ERROR_BUSY; // already claimed
4022
- }
4023
-
4024
- handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
4025
-
4026
- usbi_dbg("claimed interface %d", iface);
4027
- handle_priv->active_interface = iface;
4028
-
4029
- return LIBUSB_SUCCESS;
4030
- }
4031
-
4032
- static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4033
- {
4034
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4035
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4036
-
4037
- CHECK_HID_AVAILABLE;
4038
-
4039
- if (priv->usb_interface[iface].path == NULL) {
4040
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
4041
- }
4042
-
4043
- if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
4044
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
4045
- }
4046
-
4047
- handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
4048
-
4049
- return LIBUSB_SUCCESS;
4050
- }
4051
-
4052
- static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4053
- {
4054
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4055
-
4056
- CHECK_HID_AVAILABLE;
4057
-
4058
- if (altsetting > 255) {
4059
- return LIBUSB_ERROR_INVALID_PARAM;
4060
- }
4061
-
4062
- if (altsetting != 0) {
4063
- usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
4064
- return LIBUSB_ERROR_NOT_SUPPORTED;
4065
- }
4066
-
4067
- return LIBUSB_SUCCESS;
4068
- }
4069
-
4070
- static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4071
- {
4072
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4073
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4074
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4075
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4076
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4077
- WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
4078
- HANDLE hid_handle;
4079
- struct winfd wfd;
4080
- int current_interface, config;
4081
- size_t size;
4082
- int r = LIBUSB_ERROR_INVALID_PARAM;
4083
-
4084
- CHECK_HID_AVAILABLE;
4085
-
4086
- transfer_priv->pollable_fd = INVALID_WINFD;
4087
- safe_free(transfer_priv->hid_buffer);
4088
- transfer_priv->hid_dest = NULL;
4089
- size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
4090
-
4091
- if (size > MAX_CTRL_BUFFER_LENGTH) {
4092
- return LIBUSB_ERROR_INVALID_PARAM;
4093
- }
4094
-
4095
- current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
4096
- if (current_interface < 0) {
4097
- if (auto_claim(transfer, &current_interface, USB_API_HID) != LIBUSB_SUCCESS) {
4098
- return LIBUSB_ERROR_NOT_FOUND;
4099
- }
4100
- }
4101
-
4102
- usbi_dbg("will use interface %d", current_interface);
4103
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4104
- // Always use the handle returned from usbi_create_fd (wfd.handle)
4105
- wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
4106
- if (wfd.fd < 0) {
4107
- return LIBUSB_ERROR_NOT_FOUND;
4108
- }
4109
-
4110
- switch(LIBUSB_REQ_TYPE(setup->request_type)) {
4111
- case LIBUSB_REQUEST_TYPE_STANDARD:
4112
- switch(setup->request) {
4113
- case LIBUSB_REQUEST_GET_DESCRIPTOR:
4114
- r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
4115
- (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
4116
- break;
4117
- case LIBUSB_REQUEST_GET_CONFIGURATION:
4118
- r = windows_get_configuration(transfer->dev_handle, &config);
4119
- if (r == LIBUSB_SUCCESS) {
4120
- size = 1;
4121
- ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
4122
- r = LIBUSB_COMPLETED;
4123
- }
4124
- break;
4125
- case LIBUSB_REQUEST_SET_CONFIGURATION:
4126
- if (setup->value == priv->active_config) {
4127
- r = LIBUSB_COMPLETED;
4128
- } else {
4129
- usbi_warn(ctx, "cannot set configuration other than the default one");
4130
- r = LIBUSB_ERROR_NOT_SUPPORTED;
4131
- }
4132
- break;
4133
- case LIBUSB_REQUEST_GET_INTERFACE:
4134
- size = 1;
4135
- ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
4136
- r = LIBUSB_COMPLETED;
4137
- break;
4138
- case LIBUSB_REQUEST_SET_INTERFACE:
4139
- r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value);
4140
- if (r == LIBUSB_SUCCESS) {
4141
- r = LIBUSB_COMPLETED;
4142
- }
4143
- break;
4144
- default:
4145
- usbi_warn(ctx, "unsupported HID control request");
4146
- r = LIBUSB_ERROR_NOT_SUPPORTED;
4147
- break;
4148
- }
4149
- break;
4150
- case LIBUSB_REQUEST_TYPE_CLASS:
4151
- r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
4152
- setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
4153
- &size, wfd.overlapped);
4154
- break;
4155
- default:
4156
- usbi_warn(ctx, "unsupported HID control request");
4157
- r = LIBUSB_ERROR_NOT_SUPPORTED;
4158
- break;
4159
- }
4160
-
4161
- if (r == LIBUSB_COMPLETED) {
4162
- // Force request to be completed synchronously. Transferred size has been set by previous call
4163
- wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4164
- // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
4165
- // set InternalHigh to the number of bytes transferred
4166
- wfd.overlapped->InternalHigh = (DWORD)size;
4167
- r = LIBUSB_SUCCESS;
4168
- }
4169
-
4170
- if (r == LIBUSB_SUCCESS) {
4171
- // Use priv_transfer to store data needed for async polling
4172
- transfer_priv->pollable_fd = wfd;
4173
- transfer_priv->interface_number = (uint8_t)current_interface;
4174
- } else {
4175
- usbi_free_fd(&wfd);
4176
- }
4177
-
4178
- return r;
4179
- }
4180
-
4181
- static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4182
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4183
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4184
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4185
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4186
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4187
- struct winfd wfd;
4188
- HANDLE hid_handle;
4189
- bool direction_in, ret;
4190
- int current_interface, length;
4191
- DWORD size;
4192
- int r = LIBUSB_SUCCESS;
4193
-
4194
- CHECK_HID_AVAILABLE;
4195
-
4196
- transfer_priv->pollable_fd = INVALID_WINFD;
4197
- transfer_priv->hid_dest = NULL;
4198
- safe_free(transfer_priv->hid_buffer);
4199
-
4200
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4201
- if (current_interface < 0) {
4202
- usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4203
- return LIBUSB_ERROR_NOT_FOUND;
4204
- }
4205
-
4206
- usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
4207
-
4208
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4209
- direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
4210
-
4211
- wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
4212
- // Always use the handle returned from usbi_create_fd (wfd.handle)
4213
- if (wfd.fd < 0) {
4214
- return LIBUSB_ERROR_NO_MEM;
4215
- }
4216
-
4217
- // If report IDs are not in use, an extra prefix byte must be added
4218
- if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
4219
- || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
4220
- length = transfer->length+1;
4221
- } else {
4222
- length = transfer->length;
4223
- }
4224
- // Add a trailing byte to detect overflows on input
4225
- transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
4226
- if (transfer_priv->hid_buffer == NULL) {
4227
- return LIBUSB_ERROR_NO_MEM;
4228
- }
4229
- transfer_priv->hid_expected_size = length;
4230
-
4231
- if (direction_in) {
4232
- transfer_priv->hid_dest = transfer->buffer;
4233
- usbi_dbg("reading %d bytes (report ID: 0x00)", length);
4234
- ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
4235
- } else {
4236
- if (!priv->hid->uses_report_ids[1]) {
4237
- memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
4238
- } else {
4239
- // We could actually do without the calloc and memcpy in this case
4240
- memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4241
- }
4242
- usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4243
- ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
4244
- }
4245
- if (!ret) {
4246
- if (GetLastError() != ERROR_IO_PENDING) {
4247
- usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
4248
- usbi_free_fd(&wfd);
4249
- safe_free(transfer_priv->hid_buffer);
4250
- return LIBUSB_ERROR_IO;
4251
- }
4252
- } else {
4253
- // Only write operations that completed synchronously need to free up
4254
- // hid_buffer. For reads, copy_transfer_data() handles that process.
4255
- if (!direction_in) {
4256
- safe_free(transfer_priv->hid_buffer);
4257
- }
4258
- if (size == 0) {
4259
- usbi_err(ctx, "program assertion failed - no data was transferred");
4260
- size = 1;
4261
- }
4262
- if (size > (size_t)length) {
4263
- usbi_err(ctx, "OVERFLOW!");
4264
- r = LIBUSB_ERROR_OVERFLOW;
4265
- }
4266
- wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
4267
- wfd.overlapped->InternalHigh = size;
4268
- }
4269
-
4270
- transfer_priv->pollable_fd = wfd;
4271
- transfer_priv->interface_number = (uint8_t)current_interface;
4272
-
4273
- return r;
4274
- }
4275
-
4276
- static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4277
- {
4278
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4279
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
4280
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4281
- HANDLE hid_handle;
4282
- int current_interface;
4283
-
4284
- CHECK_HID_AVAILABLE;
4285
-
4286
- current_interface = transfer_priv->interface_number;
4287
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4288
- CancelIo(hid_handle);
4289
-
4290
- return LIBUSB_SUCCESS;
4291
- }
4292
-
4293
- static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4294
- {
4295
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4296
- HANDLE hid_handle;
4297
- int current_interface;
4298
-
4299
- CHECK_HID_AVAILABLE;
4300
-
4301
- // Flushing the queues on all interfaces is the best we can achieve
4302
- for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4303
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4304
- if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
4305
- HidD_FlushQueue(hid_handle);
4306
- }
4307
- }
4308
- return LIBUSB_SUCCESS;
4309
- }
4310
-
4311
- static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4312
- {
4313
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4314
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4315
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4316
- HANDLE hid_handle;
4317
- int current_interface;
4318
-
4319
- CHECK_HID_AVAILABLE;
4320
-
4321
- current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4322
- if (current_interface < 0) {
4323
- usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4324
- return LIBUSB_ERROR_NOT_FOUND;
4325
- }
4326
-
4327
- usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
4328
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4329
-
4330
- // No endpoint selection with Microsoft's implementation, so we try to flush the
4331
- // whole interface. Should be OK for most case scenarios
4332
- if (!HidD_FlushQueue(hid_handle)) {
4333
- usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
4334
- // Device was probably disconnected
4335
- return LIBUSB_ERROR_NO_DEVICE;
4336
- }
4337
-
4338
- return LIBUSB_SUCCESS;
4339
- }
4340
-
4341
- // This extra function is only needed for HID
4342
- static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) {
4343
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4344
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4345
- struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4346
- int r = LIBUSB_TRANSFER_COMPLETED;
4347
- uint32_t corrected_size = io_size;
4348
-
4349
- if (transfer_priv->hid_buffer != NULL) {
4350
- // If we have a valid hid_buffer, it means the transfer was async
4351
- if (transfer_priv->hid_dest != NULL) { // Data readout
4352
- if (corrected_size > 0) {
4353
- // First, check for overflow
4354
- if (corrected_size > transfer_priv->hid_expected_size) {
4355
- usbi_err(ctx, "OVERFLOW!");
4356
- corrected_size = (uint32_t)transfer_priv->hid_expected_size;
4357
- r = LIBUSB_TRANSFER_OVERFLOW;
4358
- }
4359
-
4360
- if (transfer_priv->hid_buffer[0] == 0) {
4361
- // Discard the 1 byte report ID prefix
4362
- corrected_size--;
4363
- memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
4364
- } else {
4365
- memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
4366
- }
4367
- }
4368
- transfer_priv->hid_dest = NULL;
4369
- }
4370
- // For write, we just need to free the hid buffer
4371
- safe_free(transfer_priv->hid_buffer);
4372
- }
4373
- itransfer->transferred += corrected_size;
4374
- return r;
4375
- }
4376
-
4377
-
4378
- /*
4379
- * Composite API functions
4380
- */
4381
- static int composite_init(int sub_api, struct libusb_context *ctx)
4382
- {
4383
- return LIBUSB_SUCCESS;
4384
- }
4385
-
4386
- static int composite_exit(int sub_api)
4387
- {
4388
- return LIBUSB_SUCCESS;
4389
- }
4390
-
4391
- static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4392
- {
4393
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4394
- int r = LIBUSB_ERROR_NOT_FOUND;
4395
- uint8_t i;
4396
- // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4397
- bool available[SUB_API_MAX+1] = {0};
4398
-
4399
- for (i=0; i<USB_MAXINTERFACES; i++) {
4400
- switch (priv->usb_interface[i].apib->id) {
4401
- case USB_API_WINUSBX:
4402
- if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4403
- available[priv->usb_interface[i].sub_api] = true;
4404
- break;
4405
- case USB_API_HID:
4406
- available[SUB_API_MAX] = true;
4407
- break;
4408
- default:
4409
- break;
4410
- }
4411
- }
4412
-
4413
- for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4414
- if (available[i]) {
4415
- r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4416
- if (r != LIBUSB_SUCCESS) {
4417
- return r;
4418
- }
4419
- }
4420
- }
4421
- if (available[SUB_API_MAX]) { // HID driver
4422
- r = hid_open(SUB_API_NOTSET, dev_handle);
4423
- }
4424
- return r;
4425
- }
4426
-
4427
- static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4428
- {
4429
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4430
- uint8_t i;
4431
- // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
4432
- bool available[SUB_API_MAX+1] = {0};
4433
-
4434
- for (i=0; i<USB_MAXINTERFACES; i++) {
4435
- switch (priv->usb_interface[i].apib->id) {
4436
- case USB_API_WINUSBX:
4437
- if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4438
- available[priv->usb_interface[i].sub_api] = true;
4439
- break;
4440
- case USB_API_HID:
4441
- available[SUB_API_MAX] = true;
4442
- break;
4443
- default:
4444
- break;
4445
- }
4446
- }
4447
-
4448
- for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
4449
- if (available[i]) {
4450
- usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4451
- }
4452
- }
4453
- if (available[SUB_API_MAX]) { // HID driver
4454
- hid_close(SUB_API_NOTSET, dev_handle);
4455
- }
4456
- }
4457
-
4458
- static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4459
- {
4460
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4461
- return priv->usb_interface[iface].apib->
4462
- claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4463
- }
4464
-
4465
- static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting)
4466
- {
4467
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4468
- return priv->usb_interface[iface].apib->
4469
- set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4470
- }
4471
-
4472
- static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
4473
- {
4474
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4475
- return priv->usb_interface[iface].apib->
4476
- release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4477
- }
4478
-
4479
- static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4480
- {
4481
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4482
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4483
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4484
- struct libusb_config_descriptor *conf_desc;
4485
- WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
4486
- int iface, pass, r;
4487
-
4488
- // Interface shouldn't matter for control, but it does in practice, with Windows'
4489
- // restrictions with regards to accessing HID keyboards and mice. Try to target
4490
- // a specific interface first, if possible.
4491
- switch (LIBUSB_REQ_RECIPIENT(setup->request_type)) {
4492
- case LIBUSB_RECIPIENT_INTERFACE:
4493
- iface = setup->index & 0xFF;
4494
- break;
4495
- case LIBUSB_RECIPIENT_ENDPOINT:
4496
- r = libusb_get_config_descriptor(transfer->dev_handle->dev, (uint8_t)(priv->active_config-1), &conf_desc);
4497
- if (r == LIBUSB_SUCCESS) {
4498
- iface = get_interface_by_endpoint(conf_desc, (setup->index & 0xFF));
4499
- libusb_free_config_descriptor(conf_desc);
4500
- break;
4501
- }
4502
- // Fall through if not able to determine interface
4503
- default:
4504
- iface = -1;
4505
- break;
4506
- }
4507
-
4508
- // Try and target a specific interface if the control setup indicates such
4509
- if ((iface >= 0) && (iface < USB_MAXINTERFACES)) {
4510
- usbi_dbg("attempting control transfer targeted to interface %d", iface);
4511
- if (priv->usb_interface[iface].path != NULL) {
4512
- r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
4513
- if (r == LIBUSB_SUCCESS) {
4514
- return r;
4515
- }
4516
- }
4517
- }
4518
-
4519
- // Either not targeted to a specific interface or no luck in doing so.
4520
- // Try a 2 pass approach with all interfaces.
4521
- for (pass = 0; pass < 2; pass++) {
4522
- for (iface = 0; iface < USB_MAXINTERFACES; iface++) {
4523
- if (priv->usb_interface[iface].path != NULL) {
4524
- if ((pass == 0) && (priv->usb_interface[iface].restricted_functionality)) {
4525
- usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", iface);
4526
- continue;
4527
- }
4528
- usbi_dbg("using interface %d", iface);
4529
- r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
4530
- // If not supported on this API, it may be supported on another, so don't give up yet!!
4531
- if (r == LIBUSB_ERROR_NOT_SUPPORTED) {
4532
- continue;
4533
- }
4534
- return r;
4535
- }
4536
- }
4537
- }
4538
-
4539
- usbi_err(ctx, "no libusb supported interfaces to complete request");
4540
- return LIBUSB_ERROR_NOT_FOUND;
4541
- }
4542
-
4543
- static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) {
4544
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4545
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4546
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4547
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4548
- int current_interface;
4549
-
4550
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4551
- if (current_interface < 0) {
4552
- usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4553
- return LIBUSB_ERROR_NOT_FOUND;
4554
- }
4555
-
4556
- return priv->usb_interface[current_interface].apib->
4557
- submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4558
-
4559
- static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) {
4560
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4561
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
4562
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
4563
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4564
- int current_interface;
4565
-
4566
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4567
- if (current_interface < 0) {
4568
- usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
4569
- return LIBUSB_ERROR_NOT_FOUND;
4570
- }
4571
-
4572
- return priv->usb_interface[current_interface].apib->
4573
- submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);}
4574
-
4575
- static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4576
- {
4577
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
4578
- struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
4579
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4580
- int current_interface;
4581
-
4582
- current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4583
- if (current_interface < 0) {
4584
- usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
4585
- return LIBUSB_ERROR_NOT_FOUND;
4586
- }
4587
-
4588
- return priv->usb_interface[current_interface].apib->
4589
- clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);}
4590
-
4591
- static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer)
4592
- {
4593
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4594
- struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4595
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4596
-
4597
- return priv->usb_interface[transfer_priv->interface_number].apib->
4598
- abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4599
-
4600
- static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
4601
- {
4602
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4603
- struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4604
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4605
-
4606
- return priv->usb_interface[transfer_priv->interface_number].apib->
4607
- abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer);}
4608
-
4609
- static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4610
- {
4611
- struct windows_device_priv *priv = _device_priv(dev_handle->dev);
4612
- int r;
4613
- uint8_t i;
4614
- bool available[SUB_API_MAX];
4615
- for (i = 0; i<SUB_API_MAX; i++) {
4616
- available[i] = false;
4617
- }
4618
- for (i=0; i<USB_MAXINTERFACES; i++) {
4619
- if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4620
- && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
4621
- available[priv->usb_interface[i].sub_api] = true;
4622
- }
4623
- }
4624
- for (i=0; i<SUB_API_MAX; i++) {
4625
- if (available[i]) {
4626
- r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4627
- if (r != LIBUSB_SUCCESS) {
4628
- return r;
4629
- }
4630
- }
4631
- }
4632
- return LIBUSB_SUCCESS;
4633
- }
4634
-
4635
- static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
4636
- {
4637
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4638
- struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
4639
- struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
4640
-
4641
- return priv->usb_interface[transfer_priv->interface_number].apib->
4642
- copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size);
4643
- }