usb 2.17.0 → 3.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/LICENSE +18 -4
  2. package/README.md +25 -516
  3. package/dist/index.d.ts +67 -13
  4. package/dist/index.js +333 -64
  5. package/index.d.ts +89 -0
  6. package/index.js +583 -0
  7. package/package.json +53 -33
  8. package/CHANGELOG.md +0 -294
  9. package/binding.gyp +0 -128
  10. package/dist/index.js.map +0 -1
  11. package/dist/usb/bindings.d.ts +0 -266
  12. package/dist/usb/bindings.js +0 -10
  13. package/dist/usb/bindings.js.map +0 -1
  14. package/dist/usb/capability.d.ts +0 -13
  15. package/dist/usb/capability.js +0 -17
  16. package/dist/usb/capability.js.map +0 -1
  17. package/dist/usb/descriptors.d.ts +0 -128
  18. package/dist/usb/descriptors.js +0 -3
  19. package/dist/usb/descriptors.js.map +0 -1
  20. package/dist/usb/device.d.ts +0 -100
  21. package/dist/usb/device.js +0 -297
  22. package/dist/usb/device.js.map +0 -1
  23. package/dist/usb/endpoint.d.ts +0 -94
  24. package/dist/usb/endpoint.js +0 -219
  25. package/dist/usb/endpoint.js.map +0 -1
  26. package/dist/usb/index.d.ts +0 -31
  27. package/dist/usb/index.js +0 -116
  28. package/dist/usb/index.js.map +0 -1
  29. package/dist/usb/interface.d.ts +0 -80
  30. package/dist/usb/interface.js +0 -133
  31. package/dist/usb/interface.js.map +0 -1
  32. package/dist/webusb/index.d.ts +0 -64
  33. package/dist/webusb/index.js +0 -295
  34. package/dist/webusb/index.js.map +0 -1
  35. package/dist/webusb/webusb-device.d.ts +0 -54
  36. package/dist/webusb/webusb-device.js +0 -434
  37. package/dist/webusb/webusb-device.js.map +0 -1
  38. package/libusb/.clang-tidy +0 -34
  39. package/libusb/.codespellrc +0 -3
  40. package/libusb/.private/README.txt +0 -5
  41. package/libusb/.private/appveyor_build.sh +0 -26
  42. package/libusb/.private/bm.sh +0 -54
  43. package/libusb/.private/ci-build.sh +0 -92
  44. package/libusb/.private/ci-container-build.sh +0 -67
  45. package/libusb/.private/post-rewrite.sh +0 -32
  46. package/libusb/.private/pre-commit.sh +0 -52
  47. package/libusb/.private/wbs.txt +0 -43
  48. package/libusb/.travis.yml +0 -58
  49. package/libusb/AUTHORS +0 -231
  50. package/libusb/COPYING +0 -504
  51. package/libusb/ChangeLog +0 -365
  52. package/libusb/HACKING +0 -25
  53. package/libusb/INSTALL_WIN.txt +0 -52
  54. package/libusb/KEYS +0 -123
  55. package/libusb/Makefile.am +0 -50
  56. package/libusb/NEWS +0 -2
  57. package/libusb/PORTING +0 -94
  58. package/libusb/README +0 -29
  59. package/libusb/README.git +0 -41
  60. package/libusb/TODO +0 -2
  61. package/libusb/Xcode/common.xcconfig +0 -92
  62. package/libusb/Xcode/config.h +0 -31
  63. package/libusb/Xcode/debug.xcconfig +0 -32
  64. package/libusb/Xcode/libusb.xcconfig +0 -21
  65. package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +0 -1391
  66. package/libusb/Xcode/libusb_debug.xcconfig +0 -21
  67. package/libusb/Xcode/libusb_release.xcconfig +0 -21
  68. package/libusb/Xcode/release.xcconfig +0 -30
  69. package/libusb/android/README +0 -152
  70. package/libusb/android/config.h +0 -55
  71. package/libusb/android/examples/unrooted_android.c +0 -301
  72. package/libusb/android/examples/unrooted_android.h +0 -36
  73. package/libusb/android/jni/Android.mk +0 -23
  74. package/libusb/android/jni/Application.mk +0 -40
  75. package/libusb/android/jni/examples.mk +0 -168
  76. package/libusb/android/jni/libusb.mk +0 -60
  77. package/libusb/android/jni/tests.mk +0 -45
  78. package/libusb/appveyor.yml +0 -108
  79. package/libusb/autogen.sh +0 -10
  80. package/libusb/bootstrap.sh +0 -10
  81. package/libusb/configure.ac +0 -450
  82. package/libusb/doc/Makefile.in +0 -22
  83. package/libusb/doc/doxygen.cfg.in +0 -2571
  84. package/libusb/doc/libusb.png +0 -0
  85. package/libusb/examples/Makefile.am +0 -12
  86. package/libusb/examples/dpfp.c +0 -711
  87. package/libusb/examples/ezusb.c +0 -846
  88. package/libusb/examples/ezusb.h +0 -109
  89. package/libusb/examples/fxload.c +0 -310
  90. package/libusb/examples/hotplugtest.c +0 -147
  91. package/libusb/examples/listdevs.c +0 -73
  92. package/libusb/examples/sam3u_benchmark.c +0 -228
  93. package/libusb/examples/testlibusb.c +0 -312
  94. package/libusb/examples/xusb.c +0 -1254
  95. package/libusb/libusb/Makefile.am +0 -98
  96. package/libusb/libusb/Makefile.am.extra +0 -26
  97. package/libusb/libusb/core.c +0 -2925
  98. package/libusb/libusb/descriptor.c +0 -1558
  99. package/libusb/libusb/hotplug.c +0 -489
  100. package/libusb/libusb/io.c +0 -2865
  101. package/libusb/libusb/libusb-1.0.def +0 -199
  102. package/libusb/libusb/libusb-1.0.rc +0 -53
  103. package/libusb/libusb/libusb.h +0 -2421
  104. package/libusb/libusb/libusbi.h +0 -1535
  105. package/libusb/libusb/os/darwin_usb.c +0 -2977
  106. package/libusb/libusb/os/darwin_usb.h +0 -156
  107. package/libusb/libusb/os/emscripten_webusb.cpp +0 -875
  108. package/libusb/libusb/os/events_posix.c +0 -340
  109. package/libusb/libusb/os/events_posix.h +0 -62
  110. package/libusb/libusb/os/events_windows.c +0 -214
  111. package/libusb/libusb/os/events_windows.h +0 -46
  112. package/libusb/libusb/os/haiku_pollfs.cpp +0 -372
  113. package/libusb/libusb/os/haiku_usb.h +0 -113
  114. package/libusb/libusb/os/haiku_usb_backend.cpp +0 -532
  115. package/libusb/libusb/os/haiku_usb_raw.cpp +0 -231
  116. package/libusb/libusb/os/haiku_usb_raw.h +0 -188
  117. package/libusb/libusb/os/linux_netlink.c +0 -401
  118. package/libusb/libusb/os/linux_udev.c +0 -321
  119. package/libusb/libusb/os/linux_usbfs.c +0 -2829
  120. package/libusb/libusb/os/linux_usbfs.h +0 -221
  121. package/libusb/libusb/os/netbsd_usb.c +0 -617
  122. package/libusb/libusb/os/null_usb.c +0 -111
  123. package/libusb/libusb/os/openbsd_usb.c +0 -700
  124. package/libusb/libusb/os/sunos_usb.c +0 -1619
  125. package/libusb/libusb/os/sunos_usb.h +0 -79
  126. package/libusb/libusb/os/threads_posix.c +0 -126
  127. package/libusb/libusb/os/threads_posix.h +0 -98
  128. package/libusb/libusb/os/threads_windows.c +0 -40
  129. package/libusb/libusb/os/threads_windows.h +0 -113
  130. package/libusb/libusb/os/windows_common.c +0 -923
  131. package/libusb/libusb/os/windows_common.h +0 -424
  132. package/libusb/libusb/os/windows_usbdk.c +0 -724
  133. package/libusb/libusb/os/windows_usbdk.h +0 -106
  134. package/libusb/libusb/os/windows_winusb.c +0 -4766
  135. package/libusb/libusb/os/windows_winusb.h +0 -787
  136. package/libusb/libusb/strerror.c +0 -223
  137. package/libusb/libusb/sync.c +0 -342
  138. package/libusb/libusb/version.h +0 -18
  139. package/libusb/libusb/version_nano.h +0 -1
  140. package/libusb/libusb-1.0.pc.in +0 -11
  141. package/libusb/msvc/Base.props +0 -60
  142. package/libusb/msvc/Configuration.Application.props +0 -7
  143. package/libusb/msvc/Configuration.Base.props +0 -47
  144. package/libusb/msvc/Configuration.DynamicLibrary.props +0 -21
  145. package/libusb/msvc/Configuration.StaticLibrary.props +0 -7
  146. package/libusb/msvc/ProjectConfigurations.Base.props +0 -69
  147. package/libusb/msvc/build_all.ps1 +0 -17
  148. package/libusb/msvc/config.h +0 -58
  149. package/libusb/msvc/dpfp.vcxproj +0 -33
  150. package/libusb/msvc/dpfp_threaded.vcxproj +0 -38
  151. package/libusb/msvc/fxload.vcxproj +0 -46
  152. package/libusb/msvc/getopt/getopt.c +0 -1060
  153. package/libusb/msvc/getopt/getopt.h +0 -180
  154. package/libusb/msvc/getopt/getopt1.c +0 -188
  155. package/libusb/msvc/getopt.vcxproj +0 -33
  156. package/libusb/msvc/hotplugtest.vcxproj +0 -32
  157. package/libusb/msvc/init_context.vcxproj +0 -35
  158. package/libusb/msvc/libusb.sln +0 -542
  159. package/libusb/msvc/libusb_dll.vcxproj +0 -61
  160. package/libusb/msvc/libusb_static.vcxproj +0 -49
  161. package/libusb/msvc/listdevs.vcxproj +0 -32
  162. package/libusb/msvc/sam3u_benchmark.vcxproj +0 -33
  163. package/libusb/msvc/set_option.vcxproj +0 -35
  164. package/libusb/msvc/stress.vcxproj +0 -35
  165. package/libusb/msvc/stress_mt.vcxproj +0 -33
  166. package/libusb/msvc/testlibusb.vcxproj +0 -32
  167. package/libusb/msvc/xusb.vcxproj +0 -38
  168. package/libusb/tests/Makefile.am +0 -40
  169. package/libusb/tests/init_context.c +0 -153
  170. package/libusb/tests/libusb_testlib.h +0 -76
  171. package/libusb/tests/macos.c +0 -130
  172. package/libusb/tests/set_option.c +0 -253
  173. package/libusb/tests/stress.c +0 -172
  174. package/libusb/tests/stress_mt.c +0 -267
  175. package/libusb/tests/testlib.c +0 -184
  176. package/libusb/tests/umockdev.c +0 -1175
  177. package/libusb/tests/webusb-test-shim/index.js +0 -12
  178. package/libusb/tests/webusb-test-shim/package-lock.json +0 -50
  179. package/libusb/tests/webusb-test-shim/package.json +0 -10
  180. package/libusb.gypi +0 -154
  181. package/libusb_config/config.h +0 -1
  182. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  183. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  184. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  185. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  186. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  187. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  188. package/prebuilds/linux-ia32/node.napi.node +0 -0
  189. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  190. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  191. package/prebuilds/win32-arm64/node.napi.node +0 -0
  192. package/prebuilds/win32-ia32/node.napi.node +0 -0
  193. package/prebuilds/win32-x64/node.napi.node +0 -0
  194. package/src/device.cc +0 -439
  195. package/src/helpers.h +0 -64
  196. package/src/hotplug/hotplug.h +0 -22
  197. package/src/hotplug/libusb.cc +0 -90
  198. package/src/hotplug/windows.cc +0 -168
  199. package/src/node_usb.cc +0 -314
  200. package/src/node_usb.h +0 -131
  201. package/src/thread_name.cc +0 -79
  202. package/src/thread_name.h +0 -11
  203. package/src/transfer.cc +0 -143
  204. package/src/uv_async_queue.h +0 -41
  205. package/test/usb.coffee +0 -250
  206. package/test/webusb.coffee +0 -227
  207. package/test/worker.cjs +0 -13
@@ -1,4766 +0,0 @@
1
- /*
2
- * windows backend for libusb 1.0
3
- * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4
- * Copyright © 2016-2018 Chris Dickens <christopher.a.dickens@gmail.com>
5
- * With contributions from Michael Plante, Orin Eman et al.
6
- * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
7
- * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
8
- * Hash table functions adapted from glibc, by Ulrich Drepper et al.
9
- * Major code testing contribution by Xiaofan Chen
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
- *
16
- * This library is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
- * Lesser General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU Lesser General Public
22
- * License along with this library; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
- */
25
-
26
- #include <config.h>
27
-
28
- #include <windows.h>
29
- #include <setupapi.h>
30
- #include <ctype.h>
31
- #include <stdio.h>
32
- #include <stdlib.h>
33
-
34
- #include "libusbi.h"
35
- #include "windows_winusb.h"
36
-
37
- #define HANDLE_VALID(h) (((h) != NULL) && ((h) != INVALID_HANDLE_VALUE))
38
-
39
- // The below macro is used in conjunction with safe loops.
40
- #define LOOP_BREAK(err) \
41
- { \
42
- r = err; \
43
- continue; \
44
- }
45
-
46
- // WinUSB-like API prototypes
47
- static bool winusbx_init(struct libusb_context *ctx);
48
- static void winusbx_exit(void);
49
- static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle);
50
- static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle);
51
- static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
52
- static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
53
- static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
54
- static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
55
- static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting);
56
- static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
57
- static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
58
- static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
59
- static int winusbx_cancel_transfer(int sub_api, struct usbi_transfer *itransfer);
60
- static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
61
- static enum libusb_transfer_status winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length);
62
- // HID API prototypes
63
- static bool hid_init(struct libusb_context *ctx);
64
- static void hid_exit(void);
65
- static int hid_open(int sub_api, struct libusb_device_handle *dev_handle);
66
- static void hid_close(int sub_api, struct libusb_device_handle *dev_handle);
67
- static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
68
- static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
69
- static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting);
70
- static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
71
- static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
72
- static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
73
- static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
74
- static enum libusb_transfer_status hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length);
75
- // Composite API prototypes
76
- static int composite_open(int sub_api, struct libusb_device_handle *dev_handle);
77
- static void composite_close(int sub_api, struct libusb_device_handle *dev_handle);
78
- static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
79
- static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting);
80
- static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
81
- static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
82
- static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
83
- static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
84
- static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
85
- static int composite_cancel_transfer(int sub_api, struct usbi_transfer *itransfer);
86
- static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle);
87
- static enum libusb_transfer_status composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length);
88
-
89
- static usbi_mutex_t autoclaim_lock;
90
-
91
- // API globals
92
- static struct winusb_interface WinUSBX[SUB_API_MAX];
93
- #define CHECK_WINUSBX_AVAILABLE(sub_api) \
94
- do { \
95
- if (sub_api == SUB_API_NOTSET) \
96
- sub_api = priv->sub_api; \
97
- if (WinUSBX[sub_api].hDll == NULL) \
98
- return LIBUSB_ERROR_ACCESS; \
99
- } while (0)
100
-
101
- #define CHECK_HID_AVAILABLE \
102
- do { \
103
- if (DLL_HANDLE_NAME(hid) == NULL) \
104
- return LIBUSB_ERROR_ACCESS; \
105
- } while (0)
106
-
107
- #if defined(ENABLE_LOGGING)
108
- static const char *guid_to_string(const GUID *guid, char guid_string[MAX_GUID_STRING_LENGTH])
109
- {
110
- if (guid == NULL) {
111
- guid_string[0] = '\0';
112
- return guid_string;
113
- }
114
-
115
- sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
116
- (unsigned int)guid->Data1, guid->Data2, guid->Data3,
117
- guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
118
- guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
119
-
120
- return guid_string;
121
- }
122
- #endif
123
-
124
- static bool string_to_guid(const char guid_string[MAX_GUID_STRING_LENGTH], GUID *guid)
125
- {
126
- unsigned short tmp[4];
127
- int num_chars = -1;
128
- char extra;
129
- int r;
130
-
131
- // Unfortunately MinGW complains that '%hhx' is not a valid format specifier,
132
- // even though Visual Studio 2013 and later support it. Rather than complicating
133
- // the logic in this function with '#ifdef's, use a temporary array on the stack
134
- // to store the conversions.
135
- r = sscanf(guid_string, "{%8x-%4hx-%4hx-%4hx-%4hx%4hx%4hx}%n%c",
136
- (unsigned int *)&guid->Data1, &guid->Data2, &guid->Data3,
137
- &tmp[0], &tmp[1], &tmp[2], &tmp[3], &num_chars, &extra);
138
-
139
- if ((r != 7) || (num_chars != 38))
140
- return false;
141
-
142
- // Extract the bytes from the 2-byte shorts
143
- guid->Data4[0] = (unsigned char)((tmp[0] >> 8) & 0xFF);
144
- guid->Data4[1] = (unsigned char)(tmp[0] & 0xFF);
145
- guid->Data4[2] = (unsigned char)((tmp[1] >> 8) & 0xFF);
146
- guid->Data4[3] = (unsigned char)(tmp[1] & 0xFF);
147
- guid->Data4[4] = (unsigned char)((tmp[2] >> 8) & 0xFF);
148
- guid->Data4[5] = (unsigned char)(tmp[2] & 0xFF);
149
- guid->Data4[6] = (unsigned char)((tmp[3] >> 8) & 0xFF);
150
- guid->Data4[7] = (unsigned char)(tmp[3] & 0xFF);
151
-
152
- return true;
153
- }
154
-
155
- /*
156
- * Normalize Microsoft's paths: return a duplicate of the given path
157
- * with all characters converted to uppercase
158
- */
159
- static char *normalize_path(const char *path)
160
- {
161
- char *ret_path = _strdup(path);
162
- char *p;
163
-
164
- if (ret_path == NULL)
165
- return NULL;
166
-
167
- for (p = ret_path; *p != '\0'; p++)
168
- *p = (char)toupper((unsigned char)*p);
169
-
170
- return ret_path;
171
- }
172
-
173
- /*
174
- * Cfgmgr32, AdvAPI32, OLE32 and SetupAPI DLL functions
175
- */
176
- static bool init_dlls(struct libusb_context *ctx)
177
- {
178
- DLL_GET_HANDLE(ctx, Cfgmgr32);
179
- DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Parent, true);
180
- DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Child, true);
181
-
182
- // Prefixed to avoid conflict with header files
183
- DLL_GET_HANDLE(ctx, AdvAPI32);
184
- DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegQueryValueExA, true);
185
- DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegCloseKey, true);
186
-
187
- DLL_GET_HANDLE(ctx, SetupAPI);
188
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetClassDevsA, true);
189
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInfo, true);
190
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInterfaces, true);
191
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInstanceIdA, true);
192
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInterfaceDetailA, true);
193
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceRegistryPropertyA, true);
194
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiDestroyDeviceInfoList, true);
195
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDevRegKey, true);
196
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDeviceInterfaceRegKey, true);
197
-
198
- return true;
199
- }
200
-
201
- static void exit_dlls(void)
202
- {
203
- DLL_FREE_HANDLE(SetupAPI);
204
- DLL_FREE_HANDLE(AdvAPI32);
205
- DLL_FREE_HANDLE(Cfgmgr32);
206
- }
207
-
208
- /*
209
- * enumerate interfaces for the whole USB class
210
- *
211
- * Parameters:
212
- * dev_info: a pointer to a dev_info list
213
- * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
214
- * enumerator: the generic USB class for which to retrieve interface details
215
- * index: zero based index of the interface in the device info list
216
- *
217
- * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
218
- * structure returned and call this function repeatedly using the same guid (with an
219
- * incremented index starting at zero) until all interfaces have been returned.
220
- */
221
- static bool get_devinfo_data(struct libusb_context *ctx,
222
- HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char *enumerator, unsigned _index)
223
- {
224
- if (_index == 0) {
225
- *dev_info = pSetupDiGetClassDevsA(NULL, enumerator, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
226
- if (*dev_info == INVALID_HANDLE_VALUE) {
227
- usbi_err(ctx, "could not obtain device info set for PnP enumerator '%s': %s",
228
- enumerator, windows_error_str(0));
229
- return false;
230
- }
231
- }
232
-
233
- dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
234
- if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) {
235
- if (GetLastError() != ERROR_NO_MORE_ITEMS)
236
- usbi_err(ctx, "could not obtain device info data for PnP enumerator '%s' index %u: %s",
237
- enumerator, _index, windows_error_str(0));
238
-
239
- pSetupDiDestroyDeviceInfoList(*dev_info);
240
- *dev_info = INVALID_HANDLE_VALUE;
241
- return false;
242
- }
243
- return true;
244
- }
245
-
246
- /*
247
- * enumerate interfaces for a specific GUID
248
- *
249
- * Parameters:
250
- * dev_info: a pointer to a dev_info list
251
- * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed)
252
- * guid: the GUID for which to retrieve interface details
253
- * index: zero based index of the interface in the device info list
254
- *
255
- * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA
256
- * structure returned and call this function repeatedly using the same guid (with an
257
- * incremented index starting at zero) until all interfaces have been returned.
258
- */
259
- static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
260
- PSP_DEVINFO_DATA dev_info_data, LPCGUID guid, DWORD *_index, char **dev_interface_path)
261
- {
262
- SP_DEVICE_INTERFACE_DATA dev_interface_data;
263
- PSP_DEVICE_INTERFACE_DETAIL_DATA_A dev_interface_details;
264
- char guid_string[MAX_GUID_STRING_LENGTH];
265
- DWORD size;
266
-
267
- #ifndef ENABLE_LOGGING
268
- UNUSED(*guid_string);
269
- #endif
270
- dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
271
- dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
272
- for (;;) {
273
- if (!pSetupDiEnumDeviceInfo(dev_info, *_index, dev_info_data)) {
274
- if (GetLastError() != ERROR_NO_MORE_ITEMS) {
275
- usbi_err(ctx, "Could not obtain device info data for %s index %lu: %s",
276
- guid_to_string(guid, guid_string), ULONG_CAST(*_index), windows_error_str(0));
277
- return LIBUSB_ERROR_OTHER;
278
- }
279
-
280
- // No more devices
281
- return LIBUSB_SUCCESS;
282
- }
283
-
284
- // Always advance the index for the next iteration
285
- (*_index)++;
286
-
287
- if (pSetupDiEnumDeviceInterfaces(dev_info, dev_info_data, guid, 0, &dev_interface_data))
288
- break;
289
-
290
- if (GetLastError() != ERROR_NO_MORE_ITEMS) {
291
- usbi_err(ctx, "Could not obtain interface data for %s devInst %lX: %s",
292
- guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
293
- return LIBUSB_ERROR_OTHER;
294
- }
295
-
296
- // Device does not have an interface matching this GUID, skip
297
- }
298
-
299
- // Read interface data (dummy + actual) to access the device path
300
- if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
301
- // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
302
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
303
- usbi_err(ctx, "could not access interface data (dummy) for %s devInst %lX: %s",
304
- guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
305
- return LIBUSB_ERROR_OTHER;
306
- }
307
- } else {
308
- usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong");
309
- return LIBUSB_ERROR_OTHER;
310
- }
311
-
312
- dev_interface_details = malloc(size);
313
- if (dev_interface_details == NULL) {
314
- usbi_err(ctx, "could not allocate interface data for %s devInst %lX",
315
- guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst));
316
- return LIBUSB_ERROR_NO_MEM;
317
- }
318
-
319
- dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
320
- if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data,
321
- dev_interface_details, size, NULL, NULL)) {
322
- usbi_err(ctx, "could not access interface data (actual) for %s devInst %lX: %s",
323
- guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
324
- free(dev_interface_details);
325
- return LIBUSB_ERROR_OTHER;
326
- }
327
-
328
- *dev_interface_path = normalize_path(dev_interface_details->DevicePath);
329
- free(dev_interface_details);
330
-
331
- if (*dev_interface_path == NULL) {
332
- usbi_err(ctx, "could not allocate interface path for %s devInst %lX",
333
- guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst));
334
- return LIBUSB_ERROR_NO_MEM;
335
- }
336
-
337
- return LIBUSB_SUCCESS;
338
- }
339
-
340
- /* For libusb0 filter */
341
- static int get_interface_details_filter(struct libusb_context *ctx, HDEVINFO *dev_info,
342
- DWORD _index, char *filter_path, char **dev_interface_path)
343
- {
344
- const GUID *libusb0_guid = &GUID_DEVINTERFACE_LIBUSB0_FILTER;
345
- SP_DEVICE_INTERFACE_DATA dev_interface_data;
346
- PSP_DEVICE_INTERFACE_DETAIL_DATA_A dev_interface_details;
347
- HKEY hkey_dev_interface;
348
- DWORD size;
349
- int err = LIBUSB_ERROR_OTHER;
350
-
351
- if (_index == 0) {
352
- *dev_info = pSetupDiGetClassDevsA(libusb0_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
353
- if (*dev_info == INVALID_HANDLE_VALUE) {
354
- usbi_err(ctx, "could not obtain device info set: %s", windows_error_str(0));
355
- return LIBUSB_ERROR_OTHER;
356
- }
357
- }
358
-
359
- dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
360
- if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, libusb0_guid, _index, &dev_interface_data)) {
361
- if (GetLastError() != ERROR_NO_MORE_ITEMS) {
362
- usbi_err(ctx, "Could not obtain interface data for index %lu: %s",
363
- ULONG_CAST(_index), windows_error_str(0));
364
- goto err_exit;
365
- }
366
-
367
- pSetupDiDestroyDeviceInfoList(*dev_info);
368
- *dev_info = INVALID_HANDLE_VALUE;
369
- return LIBUSB_SUCCESS;
370
- }
371
-
372
- // Read interface data (dummy + actual) to access the device path
373
- if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) {
374
- // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
375
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
376
- usbi_err(ctx, "could not access interface data (dummy) for index %lu: %s",
377
- ULONG_CAST(_index), windows_error_str(0));
378
- goto err_exit;
379
- }
380
- } else {
381
- usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong");
382
- goto err_exit;
383
- }
384
-
385
- dev_interface_details = malloc(size);
386
- if (dev_interface_details == NULL) {
387
- usbi_err(ctx, "could not allocate interface data for index %lu", ULONG_CAST(_index));
388
- err = LIBUSB_ERROR_NO_MEM;
389
- goto err_exit;
390
- }
391
-
392
- dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
393
- if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, dev_interface_details, size, NULL, NULL)) {
394
- usbi_err(ctx, "could not access interface data (actual) for index %lu: %s",
395
- ULONG_CAST(_index), windows_error_str(0));
396
- free(dev_interface_details);
397
- goto err_exit;
398
- }
399
-
400
- *dev_interface_path = normalize_path(dev_interface_details->DevicePath);
401
- free(dev_interface_details);
402
-
403
- if (*dev_interface_path == NULL) {
404
- usbi_err(ctx, "could not allocate interface path for index %lu", ULONG_CAST(_index));
405
- err = LIBUSB_ERROR_NO_MEM;
406
- goto err_exit;
407
- }
408
-
409
- // [trobinso] lookup the libusb0 symbolic index.
410
- hkey_dev_interface = pSetupDiOpenDeviceInterfaceRegKey(*dev_info, &dev_interface_data, 0, KEY_READ);
411
- if (hkey_dev_interface != INVALID_HANDLE_VALUE) {
412
- DWORD libusb0_symboliclink_index = 0;
413
- DWORD value_length = sizeof(DWORD);
414
- LONG status;
415
-
416
- status = pRegQueryValueExA(hkey_dev_interface, "LUsb0", NULL, NULL,
417
- (LPBYTE)&libusb0_symboliclink_index, &value_length);
418
- if (status == ERROR_SUCCESS) {
419
- if (libusb0_symboliclink_index < 256) {
420
- // libusb0.sys is connected to this device instance.
421
- // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
422
- sprintf(filter_path, "\\\\.\\libusb0-%04u", (unsigned int)libusb0_symboliclink_index);
423
- usbi_dbg(ctx, "assigned libusb0 symbolic link %s", filter_path);
424
- } else {
425
- // libusb0.sys was connected to this device instance at one time; but not anymore.
426
- }
427
- }
428
- pRegCloseKey(hkey_dev_interface);
429
- } else {
430
- usbi_warn(ctx, "could not open device interface registry key for index %lu: %s",
431
- ULONG_CAST(_index), windows_error_str(0));
432
- // TODO: should this be an error?
433
- }
434
-
435
- return LIBUSB_SUCCESS;
436
-
437
- err_exit:
438
- pSetupDiDestroyDeviceInfoList(*dev_info);
439
- *dev_info = INVALID_HANDLE_VALUE;
440
- return err;
441
- }
442
-
443
- /*
444
- * Returns the first known ancestor of a device
445
- */
446
- static struct libusb_device *get_ancestor(struct libusb_context *ctx,
447
- DEVINST devinst, PDEVINST _parent_devinst)
448
- {
449
- struct libusb_device *dev = NULL;
450
- DEVINST parent_devinst;
451
-
452
- while (dev == NULL) {
453
- if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS)
454
- break;
455
- devinst = parent_devinst;
456
- dev = usbi_get_device_by_session_id(ctx, (unsigned long)devinst);
457
- }
458
-
459
- if ((dev != NULL) && (_parent_devinst != NULL))
460
- *_parent_devinst = devinst;
461
-
462
- return dev;
463
- }
464
-
465
- /*
466
- * Determine which interface the given endpoint address belongs to
467
- */
468
- static int get_interface_by_endpoint(struct libusb_config_descriptor *conf_desc, uint8_t ep)
469
- {
470
- const struct libusb_interface *intf;
471
- const struct libusb_interface_descriptor *intf_desc;
472
- uint8_t i, k;
473
- int j;
474
-
475
- for (i = 0; i < conf_desc->bNumInterfaces; i++) {
476
- intf = &conf_desc->interface[i];
477
- for (j = 0; j < intf->num_altsetting; j++) {
478
- intf_desc = &intf->altsetting[j];
479
- for (k = 0; k < intf_desc->bNumEndpoints; k++) {
480
- if (intf_desc->endpoint[k].bEndpointAddress == ep) {
481
- usbi_dbg(NULL, "found endpoint %02X on interface %d", intf_desc->bInterfaceNumber, i);
482
- return intf_desc->bInterfaceNumber;
483
- }
484
- }
485
- }
486
- }
487
-
488
- usbi_dbg(NULL, "endpoint %02X not found on any interface", ep);
489
- return LIBUSB_ERROR_NOT_FOUND;
490
- }
491
-
492
- static const struct libusb_interface_descriptor *get_interface_descriptor_by_number(struct libusb_device_handle *dev_handle, struct libusb_config_descriptor *conf_desc, int iface, uint8_t altsetting)
493
- {
494
- int i;
495
-
496
- for (i = 0; i < conf_desc->bNumInterfaces; i++) {
497
- if (altsetting < conf_desc->interface[i].num_altsetting && conf_desc->interface[i].altsetting[altsetting].bInterfaceNumber == iface) {
498
- return &conf_desc->interface[i].altsetting[altsetting];
499
- }
500
- }
501
-
502
- usbi_err(HANDLE_CTX(dev_handle), "interface %d with altsetting %d not found for device", iface, (int)altsetting);
503
- return NULL;
504
- }
505
-
506
- /*
507
- * Open a device and associate the HANDLE with the context's I/O completion port
508
- */
509
- static HANDLE windows_open(struct libusb_device_handle *dev_handle, const char *path, DWORD access)
510
- {
511
- struct libusb_context *ctx = HANDLE_CTX(dev_handle);
512
- struct windows_context_priv *priv = usbi_get_context_priv(ctx);
513
- HANDLE handle;
514
-
515
- handle = CreateFileA(path, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
516
- if (handle == INVALID_HANDLE_VALUE)
517
- return handle;
518
-
519
- if (CreateIoCompletionPort(handle, priv->completion_port, (ULONG_PTR)dev_handle, 0) == NULL) {
520
- usbi_err(ctx, "failed to associate handle to I/O completion port: %s", windows_error_str(0));
521
- CloseHandle(handle);
522
- return INVALID_HANDLE_VALUE;
523
- }
524
-
525
- return handle;
526
- }
527
-
528
- /*
529
- * Populate the endpoints addresses of the device_priv interface helper structs
530
- */
531
- static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
532
- {
533
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
534
- struct libusb_config_descriptor *conf_desc;
535
- const struct libusb_interface_descriptor *if_desc;
536
- int i, r;
537
-
538
- r = libusb_get_active_config_descriptor(dev_handle->dev, &conf_desc);
539
- if (r != LIBUSB_SUCCESS) {
540
- usbi_warn(HANDLE_CTX(dev_handle), "could not read config descriptor: error %d", r);
541
- return r;
542
- }
543
-
544
- if_desc = get_interface_descriptor_by_number(dev_handle, conf_desc, iface, altsetting);
545
- if (if_desc == NULL) {
546
- r = LIBUSB_ERROR_NOT_FOUND;
547
- goto end;
548
- }
549
-
550
- safe_free(priv->usb_interface[iface].endpoint);
551
-
552
- if (if_desc->bNumEndpoints == 0) {
553
- usbi_dbg(HANDLE_CTX(dev_handle), "no endpoints found for interface %u", iface);
554
- } else {
555
- priv->usb_interface[iface].endpoint = malloc(if_desc->bNumEndpoints);
556
- if (priv->usb_interface[iface].endpoint == NULL) {
557
- r = LIBUSB_ERROR_NO_MEM;
558
- goto end;
559
- }
560
- priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
561
- for (i = 0; i < if_desc->bNumEndpoints; i++) {
562
- priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
563
- usbi_dbg(HANDLE_CTX(dev_handle), "(re)assigned endpoint %02X to interface %u", priv->usb_interface[iface].endpoint[i], iface);
564
- }
565
- }
566
-
567
- // Extra init may be required to configure endpoints
568
- if (priv->apib->configure_endpoints)
569
- r = priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface);
570
-
571
- if (r == LIBUSB_SUCCESS)
572
- priv->usb_interface[iface].current_altsetting = altsetting;
573
-
574
- end:
575
- libusb_free_config_descriptor(conf_desc);
576
- return r;
577
- }
578
-
579
- // Lookup for a match in the list of API driver names
580
- // return -1 if not found, driver match number otherwise
581
- static int get_sub_api(char *driver, int api)
582
- {
583
- const char sep_str[2] = {LIST_SEPARATOR, 0};
584
- char *tok, *tmp_str;
585
- size_t len = strlen(driver);
586
- int i;
587
-
588
- if (len == 0)
589
- return SUB_API_NOTSET;
590
-
591
- tmp_str = _strdup(driver);
592
- if (tmp_str == NULL)
593
- return SUB_API_NOTSET;
594
-
595
- tok = strtok(tmp_str, sep_str);
596
- while (tok != NULL) {
597
- for (i = 0; i < usb_api_backend[api].nb_driver_names; i++) {
598
- if (_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) {
599
- free(tmp_str);
600
- return i;
601
- }
602
- }
603
- tok = strtok(NULL, sep_str);
604
- }
605
-
606
- free(tmp_str);
607
- return SUB_API_NOTSET;
608
- }
609
-
610
- /*
611
- * auto-claiming and auto-release helper functions
612
- */
613
- static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type)
614
- {
615
- struct winusb_device_handle_priv *handle_priv =
616
- get_winusb_device_handle_priv(transfer->dev_handle);
617
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
618
- int current_interface = *interface_number;
619
- int r = LIBUSB_SUCCESS;
620
-
621
- switch (api_type) {
622
- case USB_API_WINUSBX:
623
- case USB_API_HID:
624
- break;
625
- default:
626
- return LIBUSB_ERROR_INVALID_PARAM;
627
- }
628
-
629
- usbi_mutex_lock(&autoclaim_lock);
630
- if (current_interface < 0) { // No serviceable interface was found
631
- for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
632
- // Must claim an interface of the same API type
633
- if ((priv->usb_interface[current_interface].apib->id == api_type)
634
- && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS)) {
635
- usbi_dbg(TRANSFER_CTX(transfer), "auto-claimed interface %d for control request", current_interface);
636
- if (handle_priv->autoclaim_count[current_interface] != 0)
637
- usbi_err(TRANSFER_CTX(transfer), "program assertion failed - autoclaim_count was nonzero");
638
- handle_priv->autoclaim_count[current_interface]++;
639
- break;
640
- }
641
- }
642
- if (current_interface == USB_MAXINTERFACES) {
643
- usbi_err(TRANSFER_CTX(transfer), "could not auto-claim any interface");
644
- r = LIBUSB_ERROR_NOT_FOUND;
645
- }
646
- } else {
647
- // If we have a valid interface that was autoclaimed, we must increment
648
- // its autoclaim count so that we can prevent an early release.
649
- if (handle_priv->autoclaim_count[current_interface] != 0)
650
- handle_priv->autoclaim_count[current_interface]++;
651
- }
652
- usbi_mutex_unlock(&autoclaim_lock);
653
-
654
- *interface_number = current_interface;
655
- return r;
656
- }
657
-
658
- static void auto_release(struct usbi_transfer *itransfer)
659
- {
660
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
661
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
662
- libusb_device_handle *dev_handle = transfer->dev_handle;
663
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
664
- int r;
665
-
666
- usbi_mutex_lock(&autoclaim_lock);
667
- if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) {
668
- handle_priv->autoclaim_count[transfer_priv->interface_number]--;
669
- if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
670
- r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
671
- if (r == LIBUSB_SUCCESS)
672
- usbi_dbg(ITRANSFER_CTX(itransfer), "auto-released interface %d", transfer_priv->interface_number);
673
- else
674
- usbi_dbg(ITRANSFER_CTX(itransfer), "failed to auto-release interface %d (%s)",
675
- transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
676
- }
677
- }
678
- usbi_mutex_unlock(&autoclaim_lock);
679
- }
680
-
681
- /*
682
- * init: libusb backend init function
683
- */
684
- static int winusb_init(struct libusb_context *ctx)
685
- {
686
- int i;
687
-
688
- // Load DLL imports
689
- if (!init_dlls(ctx)) {
690
- usbi_err(ctx, "could not resolve DLL functions");
691
- return LIBUSB_ERROR_OTHER;
692
- }
693
-
694
- // Initialize the low level APIs (we don't care about errors at this stage)
695
- for (i = 0; i < USB_API_MAX; i++) {
696
- if (usb_api_backend[i].init && !usb_api_backend[i].init(ctx))
697
- usbi_warn(ctx, "error initializing %s backend",
698
- usb_api_backend[i].designation);
699
- }
700
-
701
- // We need a lock for proper auto-release
702
- usbi_mutex_init(&autoclaim_lock);
703
-
704
- return LIBUSB_SUCCESS;
705
- }
706
-
707
- /*
708
- * exit: libusb backend deinitialization function
709
- */
710
- static void winusb_exit(struct libusb_context *ctx)
711
- {
712
- int i;
713
-
714
- UNUSED(ctx);
715
-
716
- usbi_mutex_destroy(&autoclaim_lock);
717
-
718
- for (i = 0; i < USB_API_MAX; i++) {
719
- if (usb_api_backend[i].exit)
720
- usb_api_backend[i].exit();
721
- }
722
-
723
- exit_dlls();
724
- }
725
-
726
- /*
727
- * fetch and cache all the config descriptors through I/O
728
- */
729
- static void cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle)
730
- {
731
- struct libusb_context *ctx = DEVICE_CTX(dev);
732
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
733
- DWORD size, ret_size;
734
- uint8_t i, num_configurations;
735
-
736
- USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request
737
- PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request
738
- PUSB_CONFIGURATION_DESCRIPTOR cd_data;
739
-
740
- num_configurations = dev->device_descriptor.bNumConfigurations;
741
- if (num_configurations == 0)
742
- return;
743
-
744
- assert(sizeof(USB_DESCRIPTOR_REQUEST) == USB_DESCRIPTOR_REQUEST_SIZE);
745
-
746
- priv->config_descriptor = calloc(num_configurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR));
747
- if (priv->config_descriptor == NULL) {
748
- usbi_err(ctx, "could not allocate configuration descriptor array for '%s'", priv->dev_id);
749
- return;
750
- }
751
-
752
- for (i = 0; i <= num_configurations; i++) {
753
- safe_free(cd_buf_actual);
754
-
755
- if (i == num_configurations)
756
- break;
757
-
758
- size = sizeof(cd_buf_short);
759
- memset(&cd_buf_short.desc, 0, sizeof(cd_buf_short.desc));
760
-
761
- cd_buf_short.req.ConnectionIndex = (ULONG)dev->port_number;
762
- cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
763
- cd_buf_short.req.SetupPacket.bRequest = LIBUSB_REQUEST_GET_DESCRIPTOR;
764
- cd_buf_short.req.SetupPacket.wValue = (LIBUSB_DT_CONFIG << 8) | i;
765
- cd_buf_short.req.SetupPacket.wIndex = 0;
766
- cd_buf_short.req.SetupPacket.wLength = (USHORT)sizeof(USB_CONFIGURATION_DESCRIPTOR);
767
-
768
- // Dummy call to get the required data size. Initial failures are reported as info rather
769
- // than error as they can occur for non-penalizing situations, such as with some hubs.
770
- // coverity[tainted_data_argument]
771
- if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
772
- &cd_buf_short, size, &ret_size, NULL)) {
773
- usbi_info(ctx, "could not access configuration descriptor %u (dummy) for '%s': %s", i, priv->dev_id, windows_error_str(0));
774
- continue;
775
- }
776
-
777
- if ((ret_size != size) || (cd_buf_short.desc.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
778
- usbi_info(ctx, "unexpected configuration descriptor %u size (dummy) for '%s'", i, priv->dev_id);
779
- continue;
780
- }
781
-
782
- size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.desc.wTotalLength;
783
- cd_buf_actual = malloc(size);
784
- if (cd_buf_actual == NULL) {
785
- usbi_err(ctx, "could not allocate configuration descriptor %u buffer for '%s'", i, priv->dev_id);
786
- continue;
787
- }
788
-
789
- // Actual call
790
- cd_buf_actual->ConnectionIndex = (ULONG)dev->port_number;
791
- cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
792
- cd_buf_actual->SetupPacket.bRequest = LIBUSB_REQUEST_GET_DESCRIPTOR;
793
- cd_buf_actual->SetupPacket.wValue = (LIBUSB_DT_CONFIG << 8) | i;
794
- cd_buf_actual->SetupPacket.wIndex = 0;
795
- cd_buf_actual->SetupPacket.wLength = cd_buf_short.desc.wTotalLength;
796
-
797
- if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
798
- cd_buf_actual, size, &ret_size, NULL)) {
799
- usbi_err(ctx, "could not access configuration descriptor %u (actual) for '%s': %s", i, priv->dev_id, windows_error_str(0));
800
- continue;
801
- }
802
-
803
- cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR *)cd_buf_actual + USB_DESCRIPTOR_REQUEST_SIZE);
804
-
805
- if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.desc.wTotalLength)) {
806
- usbi_err(ctx, "unexpected configuration descriptor %u size (actual) for '%s'", i, priv->dev_id);
807
- continue;
808
- }
809
-
810
- if (cd_data->bDescriptorType != LIBUSB_DT_CONFIG) {
811
- usbi_err(ctx, "descriptor %u not a configuration descriptor for '%s'", i, priv->dev_id);
812
- continue;
813
- }
814
-
815
- usbi_dbg(ctx, "cached config descriptor %u (bConfigurationValue=%u, %u bytes)",
816
- i, cd_data->bConfigurationValue, cd_data->wTotalLength);
817
-
818
- // Cache the descriptor
819
- priv->config_descriptor[i] = cd_data;
820
- cd_buf_actual = NULL;
821
- }
822
- }
823
-
824
- #define ROOT_HUB_FS_CONFIG_DESC_LENGTH 0x19
825
- #define ROOT_HUB_HS_CONFIG_DESC_LENGTH 0x19
826
- #define ROOT_HUB_SS_CONFIG_DESC_LENGTH 0x1f
827
- #define CONFIG_DESC_WTOTAL_LENGTH_OFFSET 0x02
828
- #define CONFIG_DESC_EP_MAX_PACKET_OFFSET 0x16
829
- #define CONFIG_DESC_EP_BINTERVAL_OFFSET 0x18
830
-
831
- static const uint8_t root_hub_config_descriptor_template[] = {
832
- // Configuration Descriptor
833
- LIBUSB_DT_CONFIG_SIZE, // bLength
834
- LIBUSB_DT_CONFIG, // bDescriptorType
835
- 0x00, 0x00, // wTotalLength (filled in)
836
- 0x01, // bNumInterfaces
837
- 0x01, // bConfigurationValue
838
- 0x00, // iConfiguration
839
- 0xc0, // bmAttributes (reserved + self-powered)
840
- 0x00, // bMaxPower
841
- // Interface Descriptor
842
- LIBUSB_DT_INTERFACE_SIZE, // bLength
843
- LIBUSB_DT_INTERFACE, // bDescriptorType
844
- 0x00, // bInterfaceNumber
845
- 0x00, // bAlternateSetting
846
- 0x01, // bNumEndpoints
847
- LIBUSB_CLASS_HUB, // bInterfaceClass
848
- 0x00, // bInterfaceSubClass
849
- 0x00, // bInterfaceProtocol
850
- 0x00, // iInterface
851
- // Endpoint Descriptor
852
- LIBUSB_DT_ENDPOINT_SIZE, // bLength
853
- LIBUSB_DT_ENDPOINT, // bDescriptorType
854
- 0x81, // bEndpointAddress
855
- 0x03, // bmAttributes (Interrupt)
856
- 0x00, 0x00, // wMaxPacketSize (filled in)
857
- 0x00, // bInterval (filled in)
858
- // SuperSpeed Endpoint Companion Descriptor
859
- LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE, // bLength
860
- LIBUSB_DT_SS_ENDPOINT_COMPANION, // bDescriptorType
861
- 0x00, // bMaxBurst
862
- 0x00, // bmAttributes
863
- 0x02, 0x00 // wBytesPerInterval
864
- };
865
-
866
- static int alloc_root_hub_config_desc(struct libusb_device *dev, ULONG num_ports,
867
- uint8_t config_desc_length, uint8_t ep_interval)
868
- {
869
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
870
- uint8_t *ptr;
871
-
872
- priv->config_descriptor = malloc(sizeof(*priv->config_descriptor));
873
- if (priv->config_descriptor == NULL)
874
- return LIBUSB_ERROR_NO_MEM;
875
-
876
- // Most config descriptors come from cache_config_descriptors() which obtains the
877
- // descriptors from the hub using an allocated USB_DESCRIPTOR_REQUEST structure.
878
- // To avoid an extra malloc + memcpy we just hold on to the USB_DESCRIPTOR_REQUEST
879
- // structure we already have and back up the pointer in windows_device_priv_release()
880
- // when freeing the descriptors. To keep a single execution path, we need to offset
881
- // the pointer here by the same amount.
882
- ptr = malloc(USB_DESCRIPTOR_REQUEST_SIZE + config_desc_length);
883
- if (ptr == NULL)
884
- return LIBUSB_ERROR_NO_MEM;
885
-
886
- ptr += USB_DESCRIPTOR_REQUEST_SIZE;
887
-
888
- memcpy(ptr, root_hub_config_descriptor_template, config_desc_length);
889
- ptr[CONFIG_DESC_WTOTAL_LENGTH_OFFSET] = config_desc_length;
890
- ptr[CONFIG_DESC_EP_MAX_PACKET_OFFSET] = (uint8_t)((num_ports + 7) / 8);
891
- ptr[CONFIG_DESC_EP_BINTERVAL_OFFSET] = ep_interval;
892
-
893
- priv->config_descriptor[0] = (PUSB_CONFIGURATION_DESCRIPTOR)ptr;
894
- priv->active_config = 1;
895
-
896
- return 0;
897
- }
898
-
899
- static int init_root_hub(struct libusb_device *dev)
900
- {
901
- struct libusb_context *ctx = DEVICE_CTX(dev);
902
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
903
- USB_NODE_CONNECTION_INFORMATION_EX conn_info;
904
- USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2;
905
- USB_NODE_INFORMATION hub_info;
906
- enum libusb_speed speed = LIBUSB_SPEED_UNKNOWN;
907
- uint8_t config_desc_length;
908
- uint8_t ep_interval;
909
- HANDLE handle;
910
- ULONG port_number, num_ports;
911
- DWORD size;
912
- int r;
913
-
914
- // Determining the speed of a root hub is painful. Microsoft does not directly report the speed
915
- // capabilities of the root hub itself, only its ports and/or connected devices. Therefore we
916
- // are forced to query each individual port of the root hub to try and infer the root hub's
917
- // speed. Note that we have to query all ports because the presence of a device on that port
918
- // changes if/how Windows returns any useful speed information.
919
- handle = CreateFileA(priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
920
- if (handle == INVALID_HANDLE_VALUE) {
921
- usbi_err(ctx, "could not open root hub %s: %s", priv->path, windows_error_str(0));
922
- return LIBUSB_ERROR_ACCESS;
923
- }
924
-
925
- if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_INFORMATION, NULL, 0, &hub_info, sizeof(hub_info), &size, NULL)) {
926
- usbi_warn(ctx, "could not get root hub info for '%s': %s", priv->dev_id, windows_error_str(0));
927
- CloseHandle(handle);
928
- return LIBUSB_ERROR_ACCESS;
929
- }
930
-
931
- num_ports = hub_info.u.HubInformation.HubDescriptor.bNumberOfPorts;
932
- usbi_dbg(ctx, "root hub '%s' reports %lu ports", priv->dev_id, ULONG_CAST(num_ports));
933
-
934
- if (windows_version >= WINDOWS_8) {
935
- // Windows 8 and later is better at reporting the speed capabilities of the root hub,
936
- // but it is not perfect. If no device is attached to the port being queried, the
937
- // returned information will only indicate whether that port supports USB 3.0 signalling.
938
- // That is not enough information to distinguish between SuperSpeed and SuperSpeed Plus.
939
- for (port_number = 1; port_number <= num_ports; port_number++) {
940
- conn_info_v2.ConnectionIndex = port_number;
941
- conn_info_v2.Length = sizeof(conn_info_v2);
942
- conn_info_v2.SupportedUsbProtocols.Usb300 = 1;
943
- if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2,
944
- &conn_info_v2, sizeof(conn_info_v2), &conn_info_v2, sizeof(conn_info_v2), &size, NULL)) {
945
- usbi_warn(ctx, "could not get node connection information (V2) for root hub '%s' port %lu: %s",
946
- priv->dev_id, ULONG_CAST(port_number), windows_error_str(0));
947
- break;
948
- }
949
-
950
- if (conn_info_v2.Flags.DeviceIsSuperSpeedPlusCapableOrHigher)
951
- speed = MAX(speed, LIBUSB_SPEED_SUPER_PLUS);
952
- else if (conn_info_v2.Flags.DeviceIsSuperSpeedCapableOrHigher || conn_info_v2.SupportedUsbProtocols.Usb300)
953
- speed = MAX(speed, LIBUSB_SPEED_SUPER);
954
- else if (conn_info_v2.SupportedUsbProtocols.Usb200)
955
- speed = MAX(speed, LIBUSB_SPEED_HIGH);
956
- else
957
- speed = MAX(speed, LIBUSB_SPEED_FULL);
958
- }
959
-
960
- if (speed != LIBUSB_SPEED_UNKNOWN)
961
- goto make_descriptors;
962
- }
963
-
964
- // At this point the speed is still not known, most likely because we are executing on
965
- // Windows 7 or earlier. The following hackery peeks into the root hub's Device ID and
966
- // tries to extract speed information from it, based on observed naming conventions.
967
- // If this does not work, we will query individual ports of the root hub.
968
- if (strstr(priv->dev_id, "ROOT_HUB31") != NULL)
969
- speed = LIBUSB_SPEED_SUPER_PLUS;
970
- else if (strstr(priv->dev_id, "ROOT_HUB30") != NULL)
971
- speed = LIBUSB_SPEED_SUPER;
972
- else if (strstr(priv->dev_id, "ROOT_HUB20") != NULL)
973
- speed = LIBUSB_SPEED_HIGH;
974
-
975
- if (speed != LIBUSB_SPEED_UNKNOWN)
976
- goto make_descriptors;
977
-
978
- // Windows only reports speed information about a connected device. This means that a root
979
- // hub with no connected devices or devices that are all operating at a speed less than the
980
- // highest speed that the root hub supports will not give us the correct speed.
981
- for (port_number = 1; port_number <= num_ports; port_number++) {
982
- conn_info.ConnectionIndex = port_number;
983
- if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, sizeof(conn_info),
984
- &conn_info, sizeof(conn_info), &size, NULL)) {
985
- usbi_warn(ctx, "could not get node connection information for root hub '%s' port %lu: %s",
986
- priv->dev_id, ULONG_CAST(port_number), windows_error_str(0));
987
- continue;
988
- }
989
-
990
- if (conn_info.ConnectionStatus != DeviceConnected)
991
- continue;
992
-
993
- if (conn_info.Speed == UsbHighSpeed) {
994
- speed = LIBUSB_SPEED_HIGH;
995
- break;
996
- }
997
- }
998
-
999
- make_descriptors:
1000
- CloseHandle(handle);
1001
-
1002
- dev->device_descriptor.bLength = LIBUSB_DT_DEVICE_SIZE;
1003
- dev->device_descriptor.bDescriptorType = LIBUSB_DT_DEVICE;
1004
- dev->device_descriptor.bDeviceClass = LIBUSB_CLASS_HUB;
1005
- if ((dev->device_descriptor.idVendor == 0) && (dev->device_descriptor.idProduct == 0)) {
1006
- dev->device_descriptor.idVendor = 0x1d6b; // Linux Foundation
1007
- dev->device_descriptor.idProduct = (uint16_t)speed;
1008
- }
1009
- dev->device_descriptor.bcdDevice = 0x0100;
1010
- dev->device_descriptor.bNumConfigurations = 1;
1011
-
1012
- switch (speed) {
1013
- case LIBUSB_SPEED_SUPER_PLUS:
1014
- dev->device_descriptor.bcdUSB = 0x0310;
1015
- config_desc_length = ROOT_HUB_SS_CONFIG_DESC_LENGTH;
1016
- ep_interval = 0x0c; // 256ms
1017
- break;
1018
- case LIBUSB_SPEED_SUPER:
1019
- dev->device_descriptor.bcdUSB = 0x0300;
1020
- config_desc_length = ROOT_HUB_SS_CONFIG_DESC_LENGTH;
1021
- ep_interval = 0x0c; // 256ms
1022
- break;
1023
- case LIBUSB_SPEED_HIGH:
1024
- dev->device_descriptor.bcdUSB = 0x0200;
1025
- config_desc_length = ROOT_HUB_HS_CONFIG_DESC_LENGTH;
1026
- ep_interval = 0x0c; // 256ms
1027
- break;
1028
- case LIBUSB_SPEED_LOW: // Not used, but keeps compiler happy
1029
- case LIBUSB_SPEED_UNKNOWN:
1030
- // This case means absolutely no information about this root hub was determined.
1031
- // There is not much choice than to be pessimistic and label this as a
1032
- // full-speed device.
1033
- speed = LIBUSB_SPEED_FULL;
1034
- // fallthrough
1035
- case LIBUSB_SPEED_FULL:
1036
- dev->device_descriptor.bcdUSB = 0x0110;
1037
- config_desc_length = ROOT_HUB_FS_CONFIG_DESC_LENGTH;
1038
- ep_interval = 0xff; // 255ms
1039
- break;
1040
- default: // Impossible, buts keeps compiler happy
1041
- usbi_err(ctx, "program assertion failed - unknown root hub speed");
1042
- return LIBUSB_ERROR_INVALID_PARAM;
1043
- }
1044
-
1045
- if (speed >= LIBUSB_SPEED_SUPER) {
1046
- dev->device_descriptor.bDeviceProtocol = 0x03; // USB 3.0 Hub
1047
- dev->device_descriptor.bMaxPacketSize0 = 0x09; // 2^9 bytes
1048
- } else {
1049
- dev->device_descriptor.bMaxPacketSize0 = 0x40; // 64 bytes
1050
- }
1051
-
1052
- dev->speed = speed;
1053
-
1054
- r = alloc_root_hub_config_desc(dev, num_ports, config_desc_length, ep_interval);
1055
- if (r)
1056
- usbi_err(ctx, "could not allocate config descriptor for root hub '%s'", priv->dev_id);
1057
-
1058
- return r;
1059
- }
1060
-
1061
- /*
1062
- * Populate a libusb device structure
1063
- */
1064
- static int init_device(struct libusb_device *dev, struct libusb_device *parent_dev,
1065
- uint8_t port_number, DEVINST devinst)
1066
- {
1067
- struct libusb_context *ctx = NULL;
1068
- struct libusb_device *tmp_dev;
1069
- struct winusb_device_priv *priv, *parent_priv, *tmp_priv;
1070
- USB_NODE_CONNECTION_INFORMATION_EX conn_info;
1071
- USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2;
1072
- HANDLE hub_handle;
1073
- DWORD size;
1074
- uint8_t bus_number, depth;
1075
- int r;
1076
-
1077
- priv = usbi_get_device_priv(dev);
1078
-
1079
- // If the device is already initialized, we can stop here
1080
- if (priv->initialized)
1081
- return LIBUSB_SUCCESS;
1082
-
1083
- if (parent_dev != NULL) { // Not a HCD root hub
1084
- ctx = DEVICE_CTX(dev);
1085
- parent_priv = usbi_get_device_priv(parent_dev);
1086
- if (parent_priv->apib->id != USB_API_HUB) {
1087
- usbi_warn(ctx, "parent for device '%s' is not a hub", priv->dev_id);
1088
- return LIBUSB_ERROR_NOT_FOUND;
1089
- }
1090
-
1091
- // Calculate depth and fetch bus number
1092
- bus_number = parent_dev->bus_number;
1093
- if (bus_number == 0) {
1094
- tmp_dev = get_ancestor(ctx, devinst, &devinst);
1095
- if (tmp_dev != parent_dev) {
1096
- usbi_err(ctx, "program assertion failed - first ancestor is not parent");
1097
- return LIBUSB_ERROR_NOT_FOUND;
1098
- }
1099
- libusb_unref_device(tmp_dev);
1100
-
1101
- for (depth = 1; bus_number == 0; depth++) {
1102
- tmp_dev = get_ancestor(ctx, devinst, &devinst);
1103
- if (tmp_dev == NULL) {
1104
- usbi_warn(ctx, "ancestor for device '%s' not found at depth %u", priv->dev_id, depth);
1105
- return LIBUSB_ERROR_NO_DEVICE;
1106
- }
1107
- if (tmp_dev->bus_number != 0) {
1108
- bus_number = tmp_dev->bus_number;
1109
- tmp_priv = usbi_get_device_priv(tmp_dev);
1110
- depth += tmp_priv->depth;
1111
- }
1112
- libusb_unref_device(tmp_dev);
1113
- }
1114
- } else {
1115
- depth = parent_priv->depth + 1;
1116
- }
1117
-
1118
- if (bus_number == 0) {
1119
- usbi_err(ctx, "program assertion failed - bus number not found for '%s'", priv->dev_id);
1120
- return LIBUSB_ERROR_NOT_FOUND;
1121
- }
1122
-
1123
- dev->bus_number = bus_number;
1124
- dev->port_number = port_number;
1125
- dev->parent_dev = parent_dev;
1126
- priv->depth = depth;
1127
-
1128
- hub_handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
1129
- if (hub_handle == INVALID_HANDLE_VALUE) {
1130
- usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0));
1131
- return LIBUSB_ERROR_ACCESS;
1132
- }
1133
-
1134
- conn_info.ConnectionIndex = (ULONG)port_number;
1135
- // coverity[tainted_data_argument]
1136
-
1137
- if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, sizeof(conn_info),
1138
- &conn_info, sizeof(conn_info), &size, NULL)) {
1139
- usbi_warn(ctx, "could not get node connection information for device '%s': %s",
1140
- priv->dev_id, windows_error_str(0));
1141
- CloseHandle(hub_handle);
1142
- return LIBUSB_ERROR_NO_DEVICE;
1143
- }
1144
-
1145
- if (conn_info.ConnectionStatus == NoDeviceConnected) {
1146
- usbi_err(ctx, "device '%s' is no longer connected!", priv->dev_id);
1147
- CloseHandle(hub_handle);
1148
- return LIBUSB_ERROR_NO_DEVICE;
1149
- }
1150
-
1151
- if ((conn_info.DeviceDescriptor.bLength != LIBUSB_DT_DEVICE_SIZE)
1152
- || (conn_info.DeviceDescriptor.bDescriptorType != LIBUSB_DT_DEVICE)) {
1153
- usbi_err(ctx, "device '%s' has invalid descriptor!", priv->dev_id);
1154
- CloseHandle(hub_handle);
1155
- return LIBUSB_ERROR_OTHER;
1156
- }
1157
-
1158
- static_assert(sizeof(dev->device_descriptor) == sizeof(conn_info.DeviceDescriptor),
1159
- "mismatch between libusb and OS device descriptor sizes");
1160
- memcpy(&dev->device_descriptor, &conn_info.DeviceDescriptor, LIBUSB_DT_DEVICE_SIZE);
1161
- usbi_localize_device_descriptor(&dev->device_descriptor);
1162
-
1163
- if (conn_info.CurrentConfigurationValue == 0) {
1164
- usbi_dbg(ctx, "found %u configurations for device '%s' but device is not configured (i.e. current config: 0), ignoring it",
1165
- dev->device_descriptor.bNumConfigurations,
1166
- priv->dev_id);
1167
- CloseHandle(hub_handle);
1168
- return LIBUSB_ERROR_OTHER;
1169
- }
1170
-
1171
- priv->active_config = conn_info.CurrentConfigurationValue;
1172
- usbi_dbg(ctx, "found %u configurations (current config: %u) for device '%s'",
1173
- dev->device_descriptor.bNumConfigurations, priv->active_config, priv->dev_id);
1174
-
1175
- // Cache as many config descriptors as we can
1176
- cache_config_descriptors(dev, hub_handle);
1177
-
1178
- // In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8
1179
- if (windows_version >= WINDOWS_8) {
1180
- conn_info_v2.ConnectionIndex = (ULONG)port_number;
1181
- conn_info_v2.Length = sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2);
1182
- conn_info_v2.SupportedUsbProtocols.Usb300 = 1;
1183
- if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2,
1184
- &conn_info_v2, sizeof(conn_info_v2), &conn_info_v2, sizeof(conn_info_v2), &size, NULL)) {
1185
- usbi_warn(ctx, "could not get node connection information (V2) for device '%s': %s",
1186
- priv->dev_id, windows_error_str(0));
1187
- } else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedPlusOrHigher) {
1188
- conn_info.Speed = UsbSuperSpeedPlus;
1189
- } else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) {
1190
- conn_info.Speed = UsbSuperSpeed;
1191
- }
1192
- }
1193
-
1194
- CloseHandle(hub_handle);
1195
-
1196
- if (conn_info.DeviceAddress > UINT8_MAX)
1197
- usbi_err(ctx, "program assertion failed - device address overflow");
1198
-
1199
- dev->device_address = (uint8_t)conn_info.DeviceAddress;
1200
-
1201
- switch (conn_info.Speed) {
1202
- case UsbLowSpeed: dev->speed = LIBUSB_SPEED_LOW; break;
1203
- case UsbFullSpeed: dev->speed = LIBUSB_SPEED_FULL; break;
1204
- case UsbHighSpeed: dev->speed = LIBUSB_SPEED_HIGH; break;
1205
- case UsbSuperSpeed: dev->speed = LIBUSB_SPEED_SUPER; break;
1206
- case UsbSuperSpeedPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1207
- default:
1208
- usbi_warn(ctx, "unknown device speed %u", conn_info.Speed);
1209
- break;
1210
- }
1211
- } else {
1212
- r = init_root_hub(dev);
1213
- if (r)
1214
- return r;
1215
- }
1216
-
1217
- r = usbi_sanitize_device(dev);
1218
- if (r)
1219
- return r;
1220
-
1221
- priv->initialized = true;
1222
-
1223
- usbi_dbg(ctx, "(bus: %u, addr: %u, depth: %u, port: %u): '%s'",
1224
- dev->bus_number, dev->device_address, priv->depth, dev->port_number, priv->dev_id);
1225
-
1226
- return LIBUSB_SUCCESS;
1227
- }
1228
-
1229
- static bool get_dev_port_number(HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data, DWORD *port_nr)
1230
- {
1231
- char buffer[MAX_KEY_LENGTH];
1232
- DWORD size;
1233
- const char *start = NULL;
1234
- char *end = NULL;
1235
- long long port;
1236
-
1237
- // First try SPDRP_LOCATION_INFORMATION, which returns a REG_SZ. The string *may* have a format
1238
- // similar to "Port_#0002.Hub_#000D", in which case we can extract the port number. However, we
1239
- // cannot extract the port if the returned string does not follow this format.
1240
- if (pSetupDiGetDeviceRegistryPropertyA(dev_info, dev_info_data, SPDRP_LOCATION_INFORMATION,
1241
- NULL, (PBYTE)buffer, sizeof(buffer), NULL)) {
1242
- // Check for the required format.
1243
- if (strncmp(buffer, "Port_#", 6) == 0) {
1244
- start = buffer + 6;
1245
- // Note that 0 is both strtoll's sentinel return value to indicate failure, as well
1246
- // as (obviously) the return value for the literal "0". Fortunately we can always treat
1247
- // 0 as a failure, since Windows USB port numbers are numbered 1..n.
1248
- port = strtoll(start, &end, 10);
1249
- if (port <= 0 || port >= ULONG_MAX || end == start || (*end != '.' && *end != '\0')) {
1250
- return false;
1251
- }
1252
- *port_nr = (DWORD)port;
1253
- return true;
1254
- }
1255
- }
1256
-
1257
- // Next try SPDRP_LOCATION_PATHS, which returns a REG_MULTI_SZ (but we only examine the first
1258
- // string in it). Each path has a format similar to,
1259
- // "PCIROOT(B2)#PCI(0300)#PCI(0000)#USBROOT(0)#USB(1)#USB(2)#USBMI(3)", and the port number is
1260
- // the number within the last "USB(x)" token.
1261
- if (pSetupDiGetDeviceRegistryPropertyA(dev_info, dev_info_data, SPDRP_LOCATION_PATHS,
1262
- NULL, (PBYTE)buffer, sizeof(buffer), NULL)) {
1263
- // Find the last "#USB(x)" substring
1264
- for (char *token = strrchr(buffer, '#'); token != NULL; token = strrchr(buffer, '#')) {
1265
- if (strncmp(token, "#USB(", 5) == 0) {
1266
- start = token + 5;
1267
- port = strtoll(start, &end, 10);
1268
- if (port <= 0 || port >= ULONG_MAX || end == start || (*end != ')' && *end != '\0')) {
1269
- return false;
1270
- }
1271
- *port_nr = (DWORD)port;
1272
- return true;
1273
- }
1274
- // Shorten the string and try again.
1275
- *token = '\0';
1276
- }
1277
- }
1278
-
1279
- // Lastly, try SPDRP_ADDRESS, which returns a REG_DWORD. The address *may* be the port number,
1280
- // which is true for the Microsoft driver but may not be true for other drivers. However, we
1281
- // have no other options here but to accept what it returns.
1282
- return pSetupDiGetDeviceRegistryPropertyA(dev_info, dev_info_data, SPDRP_ADDRESS,
1283
- NULL, (PBYTE)port_nr, sizeof(*port_nr), &size) && (size == sizeof(*port_nr));
1284
- }
1285
-
1286
- static int enumerate_hcd_root_hub(struct libusb_context *ctx, const char *dev_id,
1287
- DEVINST devinst)
1288
- {
1289
- DEVINST child_devinst;
1290
- struct libusb_device* dev;
1291
-
1292
- if (CM_Get_Child(&child_devinst, devinst, 0) != CR_SUCCESS) {
1293
- usbi_warn(ctx, "could not get child devinst for '%s'", dev_id);
1294
- return LIBUSB_SUCCESS;
1295
- }
1296
-
1297
- dev = usbi_get_device_by_session_id(ctx, (unsigned long)child_devinst);
1298
- if (dev == NULL) {
1299
- usbi_warn(ctx, "HCD '%s' child not found", dev_id);
1300
- return LIBUSB_SUCCESS;
1301
- }
1302
-
1303
- if (sscanf(dev_id, "PCI\\VEN_%04hx&DEV_%04hx%*s", &dev->device_descriptor.idVendor, &dev->device_descriptor.idProduct) != 2)
1304
- usbi_warn(ctx, "could not infer VID/PID of HCD from '%s'", dev_id);
1305
- libusb_unref_device(dev);
1306
- return LIBUSB_SUCCESS;
1307
- }
1308
-
1309
- // Returns the api type, or 0 if not found/unsupported
1310
- static void get_api_type(HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data,
1311
- int *api, int *sub_api)
1312
- {
1313
- // Precedence for filter drivers vs driver is in the order of this array
1314
- struct driver_lookup lookup[3] = {
1315
- {"\0\0", SPDRP_SERVICE, "driver"},
1316
- {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"},
1317
- {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"}
1318
- };
1319
- DWORD size, reg_type;
1320
- unsigned k, l;
1321
- int i, j;
1322
-
1323
- // Check the service & filter names to know the API we should use
1324
- for (k = 0; k < 3; k++) {
1325
- if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop,
1326
- &reg_type, (PBYTE)lookup[k].list, MAX_KEY_LENGTH, &size)) {
1327
- // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ
1328
- if (lookup[k].reg_prop == SPDRP_SERVICE)
1329
- // our buffers are MAX_KEY_LENGTH + 1 so we can overflow if needed
1330
- lookup[k].list[strlen(lookup[k].list) + 1] = 0;
1331
-
1332
- // MULTI_SZ is a pain to work with. Turn it into something much more manageable
1333
- // NB: none of the driver names we check against contain LIST_SEPARATOR,
1334
- // (currently ';'), so even if an unsupported one does, it's not an issue
1335
- for (l = 0; (lookup[k].list[l] != 0) || (lookup[k].list[l + 1] != 0); l++) {
1336
- if (lookup[k].list[l] == 0)
1337
- lookup[k].list[l] = LIST_SEPARATOR;
1338
- }
1339
- usbi_dbg(NULL, "%s(s): %s", lookup[k].designation, lookup[k].list);
1340
- } else {
1341
- if (GetLastError() != ERROR_INVALID_DATA)
1342
- usbi_dbg(NULL, "could not access %s: %s", lookup[k].designation, windows_error_str(0));
1343
- lookup[k].list[0] = 0;
1344
- }
1345
- }
1346
-
1347
- for (i = 2; i < USB_API_MAX; i++) {
1348
- for (k = 0; k < 3; k++) {
1349
- j = get_sub_api(lookup[k].list, i);
1350
- if (j >= 0) {
1351
- usbi_dbg(NULL, "matched %s name against %s", lookup[k].designation,
1352
- (i != USB_API_WINUSBX) ? usb_api_backend[i].designation : usb_api_backend[i].driver_name_list[j]);
1353
- *api = i;
1354
- *sub_api = j;
1355
- return;
1356
- }
1357
- }
1358
- }
1359
- }
1360
-
1361
- static int set_composite_interface(struct libusb_context *ctx, struct libusb_device *dev,
1362
- char *dev_interface_path, char *device_id, int api, int sub_api)
1363
- {
1364
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
1365
- int interface_number;
1366
- const char *mi_str;
1367
- int iadi, iadintfi;
1368
- char* endptr;
1369
- struct libusb_interface_association_descriptor_array *iad_array;
1370
- const struct libusb_interface_association_descriptor *iad;
1371
-
1372
- // Because MI_## are not necessarily in sequential order (some composite
1373
- // devices will have only MI_00 & MI_03 for instance), we retrieve the actual
1374
- // interface number from the path's MI value
1375
- mi_str = strstr(device_id, "MI_");
1376
-
1377
- endptr = NULL;
1378
- // This initialization, while redundant, is needed to make MSVC happy
1379
- interface_number = -1;
1380
-
1381
- if (mi_str != NULL) {
1382
- interface_number = strtoul(&mi_str[3], &endptr, 16);
1383
- }
1384
-
1385
- if (mi_str == NULL || endptr - &mi_str[3] != 2) {
1386
- usbi_warn(ctx, "failure to read interface number for %s, using default value", device_id);
1387
- interface_number = 0;
1388
- }
1389
-
1390
- if (interface_number >= USB_MAXINTERFACES) {
1391
- usbi_warn(ctx, "interface %d too large - ignoring interface path %s", interface_number, dev_interface_path);
1392
- return LIBUSB_ERROR_ACCESS;
1393
- }
1394
-
1395
- if (priv->usb_interface[interface_number].path != NULL) {
1396
- if (api == USB_API_HID) {
1397
- // HID devices can have multiple collections (COL##) for each MI_## interface
1398
- usbi_dbg(ctx, "interface[%d] already set - ignoring HID collection: %s",
1399
- interface_number, device_id);
1400
- return LIBUSB_ERROR_ACCESS;
1401
- }
1402
- // In other cases, just use the latest data
1403
- safe_free(priv->usb_interface[interface_number].path);
1404
- }
1405
-
1406
- usbi_dbg(ctx, "interface[%d] = %s", interface_number, dev_interface_path);
1407
- priv->usb_interface[interface_number].path = dev_interface_path;
1408
- priv->usb_interface[interface_number].apib = &usb_api_backend[api];
1409
- priv->usb_interface[interface_number].sub_api = sub_api;
1410
- if ((api == USB_API_HID) && (priv->hid == NULL)) {
1411
- priv->hid = calloc(1, sizeof(struct hid_device_priv));
1412
- if (priv->hid == NULL)
1413
- return LIBUSB_ERROR_NO_MEM;
1414
- }
1415
-
1416
- // For WinUSBX, set up associations for interfaces grouped by an IAD
1417
- if ((api == USB_API_WINUSBX) && !libusb_get_active_interface_association_descriptors(dev, &iad_array)) {
1418
- for (iadi = 0; iadi < iad_array->length; iadi++) {
1419
- iad = &iad_array->iad[iadi];
1420
- if (iad->bFirstInterface == interface_number) {
1421
- priv->usb_interface[interface_number].num_associated_interfaces = iad->bInterfaceCount;
1422
- priv->usb_interface[interface_number].first_associated_interface = iad->bFirstInterface;
1423
- for (iadintfi = 1; iadintfi < iad->bInterfaceCount; iadintfi++) {
1424
- usbi_dbg(ctx, "interface[%d] is associated with interface[%d]",
1425
- interface_number + iadintfi, interface_number);
1426
- priv->usb_interface[interface_number + iadintfi].apib = &usb_api_backend[api];
1427
- priv->usb_interface[interface_number + iadintfi].sub_api = sub_api;
1428
- priv->usb_interface[interface_number + iadintfi].num_associated_interfaces = iad->bInterfaceCount;
1429
- priv->usb_interface[interface_number + iadintfi].first_associated_interface = iad->bFirstInterface;
1430
- }
1431
- break;
1432
- }
1433
- }
1434
- libusb_free_interface_association_descriptors(iad_array);
1435
- }
1436
-
1437
- return LIBUSB_SUCCESS;
1438
- }
1439
-
1440
- static int set_hid_interface(struct libusb_context *ctx, struct libusb_device *dev,
1441
- char *dev_interface_path)
1442
- {
1443
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
1444
- uint8_t i;
1445
-
1446
- if (priv->hid == NULL) {
1447
- usbi_err(ctx, "program assertion failed - parent is not HID");
1448
- return LIBUSB_ERROR_NO_DEVICE;
1449
- } else if (priv->hid->nb_interfaces == USB_MAXINTERFACES) {
1450
- usbi_err(ctx, "program assertion failed - max USB interfaces reached for HID device");
1451
- return LIBUSB_ERROR_NO_DEVICE;
1452
- }
1453
-
1454
- for (i = 0; i < priv->hid->nb_interfaces; i++) {
1455
- if ((priv->usb_interface[i].path != NULL) && strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
1456
- usbi_dbg(ctx, "interface[%u] already set to %s", i, dev_interface_path);
1457
- return LIBUSB_ERROR_ACCESS;
1458
- }
1459
- }
1460
-
1461
- priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
1462
- priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
1463
- usbi_dbg(ctx, "interface[%u] = %s", priv->hid->nb_interfaces, dev_interface_path);
1464
- priv->hid->nb_interfaces++;
1465
- return LIBUSB_SUCCESS;
1466
- }
1467
-
1468
- // get the n-th device interface GUID indexed by guid_number
1469
- static int get_guid(struct libusb_context *ctx, char *dev_id, HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data,
1470
- int guid_number, GUID **if_guid)
1471
- {
1472
- DWORD size, reg_type;
1473
- HKEY key;
1474
- char *guid_string, *new_guid_string;
1475
- char *guid, *guid_term;
1476
- LONG s;
1477
- int pass, guids_left;
1478
- int err = LIBUSB_SUCCESS;
1479
- #if !defined(ENABLE_LOGGING)
1480
- UNUSED(dev_id);
1481
- #endif
1482
-
1483
- key = pSetupDiOpenDevRegKey(*dev_info, dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
1484
- if (key == INVALID_HANDLE_VALUE) {
1485
- usbi_warn(ctx, "Cannot get the additional GUIDs for '%s'", dev_id);
1486
- return LIBUSB_ERROR_ACCESS;
1487
- }
1488
- // Reserve buffer large enough to hold one GUID with two terminating characters
1489
- size = MAX_GUID_STRING_LENGTH + 1;
1490
- // Allocate memory for storing the guid_string with two extra terminating characters
1491
- // This is necessary for parsing the REG_MULTI_SZ type below
1492
- guid_string = malloc(size + 2);
1493
- if (guid_string == NULL) {
1494
- usbi_err(ctx, "failed to alloc guid_string");
1495
- return LIBUSB_ERROR_NO_MEM;
1496
- }
1497
-
1498
- // The 1st pass tries to get the guid. If it fails due to ERROR_MORE_DATA
1499
- // then reallocate enough memory for the 2nd pass
1500
- for (pass = 0; pass < 2; pass++) {
1501
- // Look for both DeviceInterfaceGUIDs *and* DeviceInterfaceGUID, in that order
1502
- // If multiple GUIDs, find the n-th that is indexed by guid_number
1503
- s = pRegQueryValueExA(key, "DeviceInterfaceGUIDs", NULL, &reg_type,
1504
- (LPBYTE)guid_string, &size);
1505
- if (s == ERROR_FILE_NOT_FOUND)
1506
- s = pRegQueryValueExA(key, "DeviceInterfaceGUID", NULL, &reg_type,
1507
- (LPBYTE)guid_string, &size);
1508
- if (s == ERROR_SUCCESS) {
1509
- // The GUID was read successfully
1510
- break;
1511
- } else if (s == ERROR_FILE_NOT_FOUND) {
1512
- usbi_dbg(ctx, "no DeviceInterfaceGUID registered for '%s'", dev_id);
1513
- err = LIBUSB_ERROR_ACCESS;
1514
- goto exit;
1515
- } else if (s == ERROR_MORE_DATA) {
1516
- if (pass == 1) {
1517
- // Previous pass should have allocated enough memory, but reading failed
1518
- usbi_warn(ctx, "unexpected error from pRegQueryValueExA for '%s'", dev_id);
1519
- err = LIBUSB_ERROR_OTHER;
1520
- goto exit;
1521
- }
1522
- new_guid_string = realloc((void *)guid_string, size + 2);
1523
- if (new_guid_string == NULL) {
1524
- usbi_err(ctx, "failed to realloc guid string");
1525
- err = LIBUSB_ERROR_NO_MEM;
1526
- goto exit;
1527
- }
1528
- guid_string = new_guid_string;
1529
- } else {
1530
- usbi_warn(ctx, "unexpected error from pRegQueryValueExA for '%s'", dev_id);
1531
- err = LIBUSB_ERROR_ACCESS;
1532
- goto exit;
1533
- }
1534
- }
1535
-
1536
- // https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexa#remarks
1537
- // - "string may not have been stored with the proper terminating null characters"
1538
- // - The following GUIDs should be consider as valid:
1539
- // "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\0", "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}",
1540
- // "{xxx.....xx}\0\0\0", "{xxx.....xx}\0{xxx.....xx}\0{xxx.....xx}\0",
1541
- // "{xxx.....xx}\0{xxx.....xx}\0{xxx.....xx}", "{xxx.....xx}{xxx.....xx}{xxx.....xx}",
1542
- // "{xxx.....xx}\0{xxx.....xx}\0{xxx.....xx}\0\0\0\0"
1543
- if ((reg_type == REG_SZ ) || (reg_type == REG_MULTI_SZ)) {
1544
- /* Get the n-th GUID indexed by guid_number since the DeviceInterfaceGUIDs may
1545
- contain more GUIDs */
1546
- guid = guid_string;
1547
- // Add two terminating chars for not overrunning the allocated memory while iterating
1548
- guid[size] = '\0';
1549
- guid[size + 1] = '\0';
1550
- // Iterate the GUIDs in the guid string
1551
- guids_left = guid_number;
1552
- while (guids_left) {
1553
- guid = strchr(guid, '}');
1554
- if (guid == NULL) {
1555
- usbi_warn(ctx, "no GUID with index %d registered for '%s'", guid_number, dev_id);
1556
- err = LIBUSB_ERROR_ACCESS;
1557
- goto exit;
1558
- }
1559
- guid++;
1560
- // Skip the terminating char if available
1561
- if (*guid == '\0') {
1562
- guid++;
1563
- }
1564
- guids_left--;
1565
- }
1566
- // Add terminating char to the string
1567
- guid_term = strchr(guid, '}');
1568
- if (guid_term == NULL) {
1569
- usbi_warn(ctx, "no GUID with index %d registered for '%s'", guid_number, dev_id);
1570
- err = LIBUSB_ERROR_ACCESS;
1571
- goto exit;
1572
- }
1573
- // Terminate the current guid string to handle the variant without separators
1574
- guid_term++;
1575
- *guid_term = '\0';
1576
- } else {
1577
- usbi_warn(ctx, "unexpected type of DeviceInterfaceGUID for '%s'", dev_id);
1578
- err = LIBUSB_ERROR_ACCESS;
1579
- goto exit;
1580
- }
1581
-
1582
- *if_guid = malloc(sizeof(GUID));
1583
- if (*if_guid == NULL) {
1584
- usbi_err(ctx, "failed to alloc if_guid");
1585
- err = LIBUSB_ERROR_NO_MEM;
1586
- goto exit;
1587
- }
1588
- if (!string_to_guid(guid, *if_guid)) {
1589
- usbi_warn(ctx, "device '%s' has malformed DeviceInterfaceGUID string '%s', skipping", dev_id, guid);
1590
- free(*if_guid);
1591
- *if_guid = NULL;
1592
- goto exit;
1593
- }
1594
-
1595
- exit:
1596
- pRegCloseKey(key);
1597
- free(guid_string);
1598
- return err;
1599
- }
1600
-
1601
- /*
1602
- * get_device_list: libusb backend device enumeration function
1603
- */
1604
- static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
1605
- {
1606
- struct discovered_devs *discdevs;
1607
- HDEVINFO *dev_info, dev_info_intf, dev_info_enum;
1608
- SP_DEVINFO_DATA dev_info_data;
1609
- DWORD _index = 0;
1610
- GUID hid_guid;
1611
- int r = LIBUSB_SUCCESS;
1612
- int api, sub_api;
1613
- unsigned int pass, pass_type, i, j;
1614
- char enumerator[16];
1615
- char dev_id[MAX_PATH_LENGTH];
1616
- struct libusb_device *dev, *parent_dev;
1617
- struct winusb_device_priv *priv, *parent_priv;
1618
- char *dev_interface_path = NULL;
1619
- unsigned long session_id;
1620
- DWORD size, port_nr, install_state;
1621
- uint8_t bus_number = 0;
1622
- #if defined(ENABLE_LOGGING)
1623
- char guid_string[MAX_GUID_STRING_LENGTH];
1624
- #endif
1625
- GUID *if_guid;
1626
- #define HUB_PASS 0
1627
- #define DEV_PASS 1
1628
- #define HCD_PASS 2
1629
- #define GEN_PASS 3
1630
- #define HID_PASS 4
1631
- #define EXT_PASS 5
1632
- // Keep a list of guids that will be enumerated
1633
- #define GUID_SIZE_STEP 8
1634
- const GUID **guid_list, **new_guid_list;
1635
- unsigned int guid_size = GUID_SIZE_STEP;
1636
- unsigned int nb_guids;
1637
- // Keep a list of PnP enumerator strings that are found
1638
- const char *usb_enumerator[8] = { "USB" };
1639
- unsigned int nb_usb_enumerators = 1;
1640
- unsigned int usb_enum_index = 0;
1641
- // Keep a list of newly allocated devs to unref
1642
- #define UNREF_SIZE_STEP 16
1643
- libusb_device **unref_list, **new_unref_list;
1644
- unsigned int unref_size = UNREF_SIZE_STEP;
1645
- unsigned int unref_cur = 0;
1646
- DWORD hub_port_nr;
1647
-
1648
- // PASS 0 : enumerate HUBs
1649
- // PASS 1 : (re)enumerate master devices that have a DEVice interface
1650
- // PASS 2 : (re)enumerate HCDs (allow for HCD hotplug)
1651
- // PASS 3 : (re)enumerate GENeric devices (including driverless)
1652
- // and list additional device interface GUIDs to explore
1653
- // PASS 4 : (re)enumerate device interface GUIDs (including HID)
1654
- // and set the device interfaces
1655
- // PASS 5+: (re)enumerate additional EXTra GUID devices
1656
-
1657
- // Init the GUID table
1658
- guid_list = malloc(guid_size * sizeof(void *));
1659
- if (guid_list == NULL) {
1660
- usbi_err(ctx, "failed to alloc guid list");
1661
- return LIBUSB_ERROR_NO_MEM;
1662
- }
1663
-
1664
- guid_list[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
1665
- guid_list[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
1666
- guid_list[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
1667
- guid_list[GEN_PASS] = NULL;
1668
- if (HidD_GetHidGuid != NULL) {
1669
- HidD_GetHidGuid(&hid_guid);
1670
- guid_list[HID_PASS] = &hid_guid;
1671
- } else {
1672
- guid_list[HID_PASS] = NULL;
1673
- }
1674
- nb_guids = EXT_PASS;
1675
-
1676
- unref_list = malloc(unref_size * sizeof(void *));
1677
- if (unref_list == NULL) {
1678
- usbi_err(ctx, "failed to alloc unref list");
1679
- free((void *)guid_list);
1680
- return LIBUSB_ERROR_NO_MEM;
1681
- }
1682
-
1683
- dev_info_intf = pSetupDiGetClassDevsA(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
1684
- if (dev_info_intf == INVALID_HANDLE_VALUE) {
1685
- usbi_err(ctx, "failed to obtain device info list: %s", windows_error_str(0));
1686
- free(unref_list);
1687
- free((void *)guid_list);
1688
- return LIBUSB_ERROR_OTHER;
1689
- }
1690
-
1691
- for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) {
1692
- pass_type = MIN(pass, EXT_PASS);
1693
- #if defined(ENABLE_LOGGING)
1694
- const char * const passname[] = {"HUB", "DEV", "HCD", "GEN", "HID", "EXT"};
1695
- usbi_dbg(ctx, "ENUM pass %s %s", passname[pass_type], guid_to_string(guid_list[pass], guid_string));
1696
- #endif
1697
- if ((pass == HID_PASS) && (guid_list[HID_PASS] == NULL))
1698
- continue;
1699
-
1700
- dev_info = (pass != GEN_PASS) ? &dev_info_intf : &dev_info_enum;
1701
-
1702
- for (i = 0; ; i++) {
1703
- // safe loop: free up any (unprotected) dynamic resource
1704
- // NB: this is always executed before breaking the loop
1705
- safe_free(dev_interface_path);
1706
- priv = parent_priv = NULL;
1707
- dev = parent_dev = NULL;
1708
-
1709
- // Safe loop: end of loop conditions
1710
- if (r != LIBUSB_SUCCESS)
1711
- break;
1712
-
1713
- if (pass != GEN_PASS) {
1714
- // Except for GEN, all passes deal with device interfaces
1715
- r = get_interface_details(ctx, *dev_info, &dev_info_data, guid_list[pass], &_index, &dev_interface_path);
1716
- if ((r != LIBUSB_SUCCESS) || (dev_interface_path == NULL)) {
1717
- _index = 0;
1718
- break;
1719
- }
1720
- } else {
1721
- // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are
1722
- // being listed under the "NUSB3" PnP Symbolic Name rather than "USB".
1723
- // The Intel USB 3.0 driver behaves similar, but uses "IUSB3"
1724
- // The Intel Alpine Ridge USB 3.1 driver uses "IARUSB3"
1725
- for (; usb_enum_index < nb_usb_enumerators; usb_enum_index++) {
1726
- if (get_devinfo_data(ctx, dev_info, &dev_info_data, usb_enumerator[usb_enum_index], i))
1727
- break;
1728
- i = 0;
1729
- }
1730
- if (usb_enum_index == nb_usb_enumerators)
1731
- break;
1732
- }
1733
-
1734
- // Read the Device ID path
1735
- if (!pSetupDiGetDeviceInstanceIdA(*dev_info, &dev_info_data, dev_id, sizeof(dev_id), NULL)) {
1736
- usbi_warn(ctx, "could not read the device instance ID for devInst %lX, skipping",
1737
- ULONG_CAST(dev_info_data.DevInst));
1738
- continue;
1739
- }
1740
-
1741
- usbi_dbg(ctx, "ENUM processing %s", dev_id);
1742
-
1743
- // Set API to use or get additional data from generic pass
1744
- api = USB_API_UNSUPPORTED;
1745
- sub_api = SUB_API_NOTSET;
1746
- switch (pass_type) {
1747
- case HCD_PASS:
1748
- break;
1749
- case HUB_PASS:
1750
- api = USB_API_HUB;
1751
- // Fetch the PnP enumerator class for this hub
1752
- // This will allow us to enumerate all classes during the GEN pass
1753
- if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME,
1754
- NULL, (PBYTE)enumerator, sizeof(enumerator), NULL)) {
1755
- usbi_err(ctx, "could not read enumerator string for device '%s': %s", dev_id, windows_error_str(0));
1756
- LOOP_BREAK(LIBUSB_ERROR_OTHER);
1757
- }
1758
- for (j = 0; j < nb_usb_enumerators; j++) {
1759
- if (strcmp(usb_enumerator[j], enumerator) == 0)
1760
- break;
1761
- }
1762
- if (j == nb_usb_enumerators) {
1763
- usbi_dbg(ctx, "found new PnP enumerator string '%s'", enumerator);
1764
- if (nb_usb_enumerators < ARRAYSIZE(usb_enumerator)) {
1765
- usb_enumerator[nb_usb_enumerators] = _strdup(enumerator);
1766
- if (usb_enumerator[nb_usb_enumerators] != NULL) {
1767
- nb_usb_enumerators++;
1768
- } else {
1769
- usbi_err(ctx, "could not allocate enumerator string '%s'", enumerator);
1770
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1771
- }
1772
- } else {
1773
- usbi_warn(ctx, "too many enumerator strings, some devices may not be accessible");
1774
- }
1775
- }
1776
- break;
1777
- case GEN_PASS:
1778
- // We use the GEN pass to detect driverless devices...
1779
- if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_DRIVER,
1780
- NULL, NULL, 0, NULL) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
1781
- usbi_info(ctx, "The following device has no driver: '%s'", dev_id);
1782
- usbi_info(ctx, "libusb will not be able to access it");
1783
- }
1784
- // ...and to add the additional device interface GUIDs
1785
- r = get_guid(ctx, dev_id, dev_info, &dev_info_data, 0, &if_guid);
1786
- if (r == LIBUSB_SUCCESS && if_guid != NULL) {
1787
- // Check if we've already seen this GUID
1788
- for (j = EXT_PASS; j < nb_guids; j++) {
1789
- if (memcmp(guid_list[j], if_guid, sizeof(*if_guid)) == 0)
1790
- break;
1791
- }
1792
- if (j == nb_guids) {
1793
- usbi_dbg(ctx, "extra GUID: %s", guid_to_string(if_guid, guid_string));
1794
- // Extend the guid_list capacity if needed
1795
- if (nb_guids == guid_size) {
1796
- new_guid_list = realloc((void *)guid_list, (guid_size + GUID_SIZE_STEP) * sizeof(void *));
1797
- if (new_guid_list == NULL) {
1798
- usbi_err(ctx, "failed to realloc guid list");
1799
- free(if_guid);
1800
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1801
- }
1802
- guid_list = new_guid_list;
1803
- guid_size += GUID_SIZE_STEP;
1804
- }
1805
- guid_list[nb_guids++] = if_guid;
1806
- } else {
1807
- // Duplicate, ignore
1808
- free(if_guid);
1809
- }
1810
- } else if (r == LIBUSB_ERROR_ACCESS) {
1811
- r = LIBUSB_SUCCESS;
1812
- } else if (r == LIBUSB_ERROR_NO_MEM) {
1813
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1814
- } else {
1815
- if (r != LIBUSB_SUCCESS) {
1816
- usbi_warn(ctx, "unexpected error during getting DeviceInterfaceGUID for '%s'", dev_id);
1817
- }
1818
- }
1819
- break;
1820
- case HID_PASS:
1821
- api = USB_API_HID;
1822
- break;
1823
- case DEV_PASS:
1824
- case EXT_PASS:
1825
- // Get the API type (after checking that the driver installation is OK)
1826
- if ((!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
1827
- NULL, (PBYTE)&install_state, sizeof(install_state), &size)) || (size != sizeof(install_state))) {
1828
- usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
1829
- dev_id, windows_error_str(0));
1830
- } else if (install_state != 0) {
1831
- usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %lu) - skipping",
1832
- dev_id, ULONG_CAST(install_state));
1833
- continue;
1834
- }
1835
- get_api_type(dev_info, &dev_info_data, &api, &sub_api);
1836
- break;
1837
- default:
1838
- assert(false); // unreachable since all pass types covered explicitly
1839
- }
1840
-
1841
- // Find parent device (for the passes that need it)
1842
- if (pass >= GEN_PASS) {
1843
- parent_dev = get_ancestor(ctx, dev_info_data.DevInst, NULL);
1844
- if (parent_dev == NULL) {
1845
- // Root hubs will not have a parent
1846
- dev = usbi_get_device_by_session_id(ctx, (unsigned long)dev_info_data.DevInst);
1847
- if (dev != NULL) {
1848
- priv = usbi_get_device_priv(dev);
1849
- if (priv->root_hub)
1850
- goto track_unref;
1851
- libusb_unref_device(dev);
1852
- }
1853
-
1854
- usbi_dbg(ctx, "unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id);
1855
- continue;
1856
- }
1857
-
1858
- parent_priv = usbi_get_device_priv(parent_dev);
1859
- // virtual USB devices are also listed during GEN - don't process these yet
1860
- if ((pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB)) {
1861
- libusb_unref_device(parent_dev);
1862
- continue;
1863
- }
1864
- }
1865
-
1866
- // Create new or match existing device, using the devInst as session id
1867
- if ((pass <= GEN_PASS) && (pass != HCD_PASS)) { // For subsequent passes, we'll lookup the parent
1868
- // These are the passes that create "new" devices
1869
- session_id = (unsigned long)dev_info_data.DevInst;
1870
- dev = usbi_get_device_by_session_id(ctx, session_id);
1871
- if (dev == NULL) {
1872
- alloc_device:
1873
- usbi_dbg(ctx, "allocating new device for session [%lX]", session_id);
1874
- dev = usbi_alloc_device(ctx, session_id);
1875
- if (dev == NULL)
1876
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1877
-
1878
- priv = winusb_device_priv_init(dev);
1879
- priv->dev_id = _strdup(dev_id);
1880
- priv->class_guid = dev_info_data.ClassGuid;
1881
- if (priv->dev_id == NULL) {
1882
- libusb_unref_device(dev);
1883
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1884
- }
1885
- } else {
1886
- usbi_dbg(ctx, "found existing device for session [%lX]", session_id);
1887
-
1888
- priv = usbi_get_device_priv(dev);
1889
- if (strcmp(priv->dev_id, dev_id) != 0) {
1890
- usbi_dbg(ctx, "device instance ID for session [%lX] changed", session_id);
1891
- usbi_disconnect_device(dev);
1892
- libusb_unref_device(dev);
1893
- goto alloc_device;
1894
- }
1895
- if (!IsEqualGUID(&priv->class_guid, &dev_info_data.ClassGuid)) {
1896
- usbi_dbg(ctx, "device class GUID for session [%lX] changed", session_id);
1897
- usbi_disconnect_device(dev);
1898
- libusb_unref_device(dev);
1899
- goto alloc_device;
1900
- }
1901
- }
1902
-
1903
- track_unref:
1904
- // Keep track of devices that need unref
1905
- if (unref_cur == unref_size) {
1906
- new_unref_list = realloc(unref_list, (unref_size + UNREF_SIZE_STEP) * sizeof(void *));
1907
- if (new_unref_list == NULL) {
1908
- usbi_err(ctx, "could not realloc list for unref - aborting");
1909
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1910
- }
1911
- unref_list = new_unref_list;
1912
- unref_size += UNREF_SIZE_STEP;
1913
- }
1914
- unref_list[unref_cur++] = dev;
1915
- }
1916
-
1917
- // Setup device
1918
- switch (pass_type) {
1919
- case HUB_PASS:
1920
- case DEV_PASS:
1921
- // If the device has already been setup, don't do it again
1922
- if (priv->path != NULL)
1923
- break;
1924
- // Take care of API initialization
1925
- priv->path = dev_interface_path;
1926
- dev_interface_path = NULL;
1927
- priv->apib = &usb_api_backend[api];
1928
- priv->sub_api = sub_api;
1929
- switch (api) {
1930
- case USB_API_COMPOSITE:
1931
- break;
1932
- case USB_API_HUB:
1933
- parent_dev = get_ancestor(ctx, dev_info_data.DevInst, NULL);
1934
- if (parent_dev == NULL) {
1935
- if (!get_dev_port_number(*dev_info, &dev_info_data, &hub_port_nr) || hub_port_nr == 0) {
1936
- if (bus_number == UINT8_MAX) {
1937
- usbi_warn(ctx, "program assertion failed - found more than %u buses, skipping the rest", UINT8_MAX);
1938
- break;
1939
- }
1940
- priv->root_hub = true;
1941
- dev->bus_number = ++bus_number;
1942
- usbi_dbg(ctx, "assigning Root Hub '%s' bus number %u", dev_id, bus_number);
1943
- }
1944
- } else {
1945
- libusb_unref_device(parent_dev);
1946
- }
1947
- break;
1948
- case USB_API_HID:
1949
- priv->hid = calloc(1, sizeof(struct hid_device_priv));
1950
- if (priv->hid == NULL)
1951
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1952
- break;
1953
- default:
1954
- // For other devices, the first interface is the same as the device
1955
- priv->usb_interface[0].path = _strdup(priv->path);
1956
- if (priv->usb_interface[0].path == NULL)
1957
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1958
- // The following is needed if we want API calls to work for both simple
1959
- // and composite devices.
1960
- for (j = 0; j < USB_MAXINTERFACES; j++)
1961
- priv->usb_interface[j].apib = &usb_api_backend[api];
1962
- break;
1963
- }
1964
- break;
1965
- case HCD_PASS:
1966
- r = enumerate_hcd_root_hub(ctx, dev_id, dev_info_data.DevInst);
1967
- break;
1968
- case GEN_PASS:
1969
- port_nr = 0;
1970
- if (!get_dev_port_number(*dev_info, &dev_info_data, &port_nr))
1971
- usbi_warn(ctx, "could not retrieve port number for device '%s': %s", dev_id, windows_error_str(0));
1972
- r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_info_data.DevInst);
1973
- if (r == LIBUSB_SUCCESS) {
1974
- // Append device to the list of discovered devices
1975
- discdevs = discovered_devs_append(*_discdevs, dev);
1976
- if (!discdevs)
1977
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
1978
-
1979
- *_discdevs = discdevs;
1980
- } else {
1981
- // Failed to initialize a single device doesn't stop us from enumerating all other devices,
1982
- // but we skip it (don't add to list of discovered devices)
1983
- usbi_warn(ctx, "failed to initialize device '%s'", priv->dev_id);
1984
- r = LIBUSB_SUCCESS;
1985
- }
1986
- break;
1987
- case HID_PASS:
1988
- case EXT_PASS:
1989
- if (parent_priv->apib->id == USB_API_HID || parent_priv->apib->id == USB_API_COMPOSITE) {
1990
- if (parent_priv->apib->id == USB_API_HID) {
1991
- usbi_dbg(ctx, "setting HID interface for [%lX]:", parent_dev->session_data);
1992
- r = set_hid_interface(ctx, parent_dev, dev_interface_path);
1993
- } else {
1994
- usbi_dbg(ctx, "setting composite interface for [%lX]:", parent_dev->session_data);
1995
- r = set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id, api, sub_api);
1996
- }
1997
- switch (r) {
1998
- case LIBUSB_SUCCESS:
1999
- dev_interface_path = NULL;
2000
- break;
2001
- case LIBUSB_ERROR_ACCESS:
2002
- // interface has already been set => make sure dev_interface_path is freed then
2003
- r = LIBUSB_SUCCESS;
2004
- break;
2005
- default:
2006
- LOOP_BREAK(r);
2007
- break;
2008
- }
2009
- }
2010
- libusb_unref_device(parent_dev);
2011
- break;
2012
- default:
2013
- assert(false); // unreachable since all pass types covered explicitly
2014
- }
2015
- }
2016
- }
2017
-
2018
- pSetupDiDestroyDeviceInfoList(dev_info_intf);
2019
-
2020
- // Free any additional GUIDs
2021
- for (pass = EXT_PASS; pass < nb_guids; pass++)
2022
- free((void *)guid_list[pass]);
2023
- free((void *)guid_list);
2024
-
2025
- // Free any PnP enumerator strings
2026
- for (i = 1; i < nb_usb_enumerators; i++)
2027
- free((void *)usb_enumerator[i]);
2028
-
2029
- // Unref newly allocated devs
2030
- for (i = 0; i < unref_cur; i++)
2031
- libusb_unref_device(unref_list[i]);
2032
- free(unref_list);
2033
-
2034
- return r;
2035
- }
2036
-
2037
- static int winusb_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len)
2038
- {
2039
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
2040
- PUSB_CONFIGURATION_DESCRIPTOR config_header;
2041
-
2042
- if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL))
2043
- return LIBUSB_ERROR_NOT_FOUND;
2044
-
2045
- config_header = priv->config_descriptor[config_index];
2046
-
2047
- len = MIN(len, config_header->wTotalLength);
2048
- memcpy(buffer, config_header, len);
2049
- return (int)len;
2050
- }
2051
-
2052
- static int winusb_get_config_descriptor_by_value(struct libusb_device *dev, uint8_t bConfigurationValue,
2053
- void **buffer)
2054
- {
2055
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
2056
- PUSB_CONFIGURATION_DESCRIPTOR config_header;
2057
- uint8_t index;
2058
-
2059
- if (priv->config_descriptor == NULL)
2060
- return LIBUSB_ERROR_NOT_FOUND;
2061
-
2062
- for (index = 0; index < dev->device_descriptor.bNumConfigurations; index++) {
2063
- config_header = priv->config_descriptor[index];
2064
- if (config_header == NULL)
2065
- continue;
2066
- if (config_header->bConfigurationValue == bConfigurationValue) {
2067
- *buffer = config_header;
2068
- return (int)config_header->wTotalLength;
2069
- }
2070
- }
2071
-
2072
- return LIBUSB_ERROR_NOT_FOUND;
2073
- }
2074
-
2075
- /*
2076
- * return the cached copy of the active config descriptor
2077
- */
2078
- static int winusb_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len)
2079
- {
2080
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
2081
- void *config_desc;
2082
- int r;
2083
-
2084
- if (priv->active_config == 0)
2085
- return LIBUSB_ERROR_NOT_FOUND;
2086
-
2087
- r = winusb_get_config_descriptor_by_value(dev, priv->active_config, &config_desc);
2088
- if (r < 0)
2089
- return r;
2090
-
2091
- len = MIN(len, (size_t)r);
2092
- memcpy(buffer, config_desc, len);
2093
- return (int)len;
2094
- }
2095
-
2096
- static int winusb_open(struct libusb_device_handle *dev_handle)
2097
- {
2098
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2099
-
2100
- CHECK_SUPPORTED_API(priv->apib, open);
2101
-
2102
- return priv->apib->open(SUB_API_NOTSET, dev_handle);
2103
- }
2104
-
2105
- static void winusb_close(struct libusb_device_handle *dev_handle)
2106
- {
2107
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2108
-
2109
- if (priv->apib->close)
2110
- priv->apib->close(SUB_API_NOTSET, dev_handle);
2111
- }
2112
-
2113
- static int winusb_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config)
2114
- {
2115
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2116
-
2117
- *config = priv->active_config;
2118
- return LIBUSB_SUCCESS;
2119
- }
2120
-
2121
- /*
2122
- * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
2123
- * does not currently expose a service that allows higher-level drivers to set
2124
- * the configuration."
2125
- */
2126
- static int winusb_set_configuration(struct libusb_device_handle *dev_handle, uint8_t config)
2127
- {
2128
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2129
- int r = LIBUSB_SUCCESS;
2130
-
2131
- r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT |
2132
- LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
2133
- LIBUSB_REQUEST_SET_CONFIGURATION, config,
2134
- 0, NULL, 0, 1000);
2135
-
2136
- if (r == LIBUSB_SUCCESS)
2137
- priv->active_config = config;
2138
-
2139
- return r;
2140
- }
2141
-
2142
- static int winusb_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface)
2143
- {
2144
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2145
- int r;
2146
-
2147
- CHECK_SUPPORTED_API(priv->apib, claim_interface);
2148
-
2149
- safe_free(priv->usb_interface[iface].endpoint);
2150
- priv->usb_interface[iface].nb_endpoints = 0;
2151
-
2152
- r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface);
2153
-
2154
- if (r == LIBUSB_SUCCESS)
2155
- r = windows_assign_endpoints(dev_handle, iface, 0);
2156
-
2157
- return r;
2158
- }
2159
-
2160
- static int winusb_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
2161
- {
2162
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2163
- int r;
2164
-
2165
- CHECK_SUPPORTED_API(priv->apib, set_interface_altsetting);
2166
-
2167
- safe_free(priv->usb_interface[iface].endpoint);
2168
- priv->usb_interface[iface].nb_endpoints = 0;
2169
-
2170
- r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting);
2171
-
2172
- if (r == LIBUSB_SUCCESS)
2173
- r = windows_assign_endpoints(dev_handle, iface, altsetting);
2174
-
2175
- return r;
2176
- }
2177
-
2178
- static int winusb_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface)
2179
- {
2180
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2181
-
2182
- CHECK_SUPPORTED_API(priv->apib, release_interface);
2183
-
2184
- return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface);
2185
- }
2186
-
2187
- static int winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
2188
- {
2189
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2190
-
2191
- CHECK_SUPPORTED_API(priv->apib, clear_halt);
2192
-
2193
- return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint);
2194
- }
2195
-
2196
- static int winusb_reset_device(struct libusb_device_handle *dev_handle)
2197
- {
2198
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2199
-
2200
- CHECK_SUPPORTED_API(priv->apib, reset_device);
2201
-
2202
- return priv->apib->reset_device(SUB_API_NOTSET, dev_handle);
2203
- }
2204
-
2205
- static void winusb_destroy_device(struct libusb_device *dev)
2206
- {
2207
- winusb_device_priv_release(dev);
2208
- }
2209
-
2210
- static void winusb_clear_transfer_priv(struct usbi_transfer *itransfer)
2211
- {
2212
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
2213
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2214
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
2215
- int sub_api = priv->sub_api;
2216
-
2217
- safe_free(transfer_priv->hid_buffer);
2218
-
2219
- if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS && sub_api == SUB_API_WINUSB) {
2220
- if (transfer_priv->isoch_buffer_handle != NULL) {
2221
- if (WinUSBX[sub_api].UnregisterIsochBuffer(transfer_priv->isoch_buffer_handle)) {
2222
- transfer_priv->isoch_buffer_handle = NULL;
2223
- } else {
2224
- usbi_warn(TRANSFER_CTX(transfer), "failed to unregister WinUSB isoch buffer: %s", windows_error_str(0));
2225
- }
2226
- }
2227
- }
2228
-
2229
- safe_free(transfer_priv->iso_context);
2230
-
2231
- // When auto claim is in use, attempt to release the auto-claimed interface
2232
- auto_release(itransfer);
2233
- }
2234
-
2235
- static int winusb_submit_transfer(struct usbi_transfer *itransfer)
2236
- {
2237
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2238
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
2239
- int (*transfer_fn)(int, struct usbi_transfer *);
2240
-
2241
- switch (transfer->type) {
2242
- case LIBUSB_TRANSFER_TYPE_CONTROL:
2243
- transfer_fn = priv->apib->submit_control_transfer;
2244
- break;
2245
- case LIBUSB_TRANSFER_TYPE_BULK:
2246
- case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2247
- transfer_fn = priv->apib->submit_bulk_transfer;
2248
- break;
2249
- case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2250
- transfer_fn = priv->apib->submit_iso_transfer;
2251
- break;
2252
- default:
2253
- // Should not get here since windows_submit_transfer() validates
2254
- // the transfer->type field
2255
- usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2256
- return LIBUSB_ERROR_INVALID_PARAM;
2257
- }
2258
-
2259
- if (transfer_fn == NULL) {
2260
- usbi_warn(TRANSFER_CTX(transfer),
2261
- "unsupported transfer type %d (unrecognized device driver)",
2262
- transfer->type);
2263
- return LIBUSB_ERROR_NOT_SUPPORTED;
2264
- }
2265
-
2266
- return transfer_fn(SUB_API_NOTSET, itransfer);
2267
- }
2268
-
2269
- static int winusb_cancel_transfer(struct usbi_transfer *itransfer)
2270
- {
2271
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2272
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
2273
-
2274
- CHECK_SUPPORTED_API(priv->apib, cancel_transfer);
2275
-
2276
- return priv->apib->cancel_transfer(SUB_API_NOTSET, itransfer);
2277
- }
2278
-
2279
- static enum libusb_transfer_status winusb_copy_transfer_data(struct usbi_transfer *itransfer, DWORD length)
2280
- {
2281
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2282
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
2283
-
2284
- if (priv->apib->copy_transfer_data == NULL) {
2285
- usbi_err(TRANSFER_CTX(transfer), "program assertion failed - no function to copy transfer data");
2286
- return LIBUSB_TRANSFER_ERROR;
2287
- }
2288
-
2289
- return priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, length);
2290
- }
2291
-
2292
- // NB: MSVC6 does not support named initializers.
2293
- const struct windows_backend winusb_backend = {
2294
- winusb_init,
2295
- winusb_exit,
2296
- winusb_get_device_list,
2297
- winusb_open,
2298
- winusb_close,
2299
- winusb_get_active_config_descriptor,
2300
- winusb_get_config_descriptor,
2301
- winusb_get_config_descriptor_by_value,
2302
- winusb_get_configuration,
2303
- winusb_set_configuration,
2304
- winusb_claim_interface,
2305
- winusb_release_interface,
2306
- winusb_set_interface_altsetting,
2307
- winusb_clear_halt,
2308
- winusb_reset_device,
2309
- winusb_destroy_device,
2310
- winusb_submit_transfer,
2311
- winusb_cancel_transfer,
2312
- winusb_clear_transfer_priv,
2313
- winusb_copy_transfer_data,
2314
- };
2315
-
2316
- /*
2317
- * USB API backends
2318
- */
2319
-
2320
- static const char * const composite_driver_names[] = {
2321
- "USBCCGP", // (Windows built-in) USB Composite Device
2322
- "dg_ssudbus" // SAMSUNG Mobile USB Composite Device
2323
- };
2324
- static const char * const winusbx_driver_names[] = {"libusbK", "libusb0", "WinUSB"};
2325
- static const char * const hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
2326
- const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
2327
- {
2328
- USB_API_UNSUPPORTED,
2329
- "Unsupported API",
2330
- NULL, /* driver_name_list */
2331
- 0, /* nb_driver_names */
2332
- NULL, /* init */
2333
- NULL, /* exit */
2334
- NULL, /* open */
2335
- NULL, /* close */
2336
- NULL, /* configure_endpoints */
2337
- NULL, /* claim_interface */
2338
- NULL, /* set_interface_altsetting */
2339
- NULL, /* release_interface */
2340
- NULL, /* clear_halt */
2341
- NULL, /* reset_device */
2342
- NULL, /* submit_bulk_transfer */
2343
- NULL, /* submit_iso_transfer */
2344
- NULL, /* submit_control_transfer */
2345
- NULL, /* cancel_transfer */
2346
- NULL, /* copy_transfer_data */
2347
- },
2348
- {
2349
- USB_API_HUB,
2350
- "HUB API",
2351
- NULL, /* driver_name_list */
2352
- 0, /* nb_driver_names */
2353
- NULL, /* init */
2354
- NULL, /* exit */
2355
- NULL, /* open */
2356
- NULL, /* close */
2357
- NULL, /* configure_endpoints */
2358
- NULL, /* claim_interface */
2359
- NULL, /* set_interface_altsetting */
2360
- NULL, /* release_interface */
2361
- NULL, /* clear_halt */
2362
- NULL, /* reset_device */
2363
- NULL, /* submit_bulk_transfer */
2364
- NULL, /* submit_iso_transfer */
2365
- NULL, /* submit_control_transfer */
2366
- NULL, /* cancel_transfer */
2367
- NULL, /* copy_transfer_data */
2368
- },
2369
- {
2370
- USB_API_COMPOSITE,
2371
- "Composite API",
2372
- composite_driver_names,
2373
- ARRAYSIZE(composite_driver_names),
2374
- NULL, /* init */
2375
- NULL, /* exit */
2376
- composite_open,
2377
- composite_close,
2378
- NULL, /* configure_endpoints */
2379
- composite_claim_interface,
2380
- composite_set_interface_altsetting,
2381
- composite_release_interface,
2382
- composite_clear_halt,
2383
- composite_reset_device,
2384
- composite_submit_bulk_transfer,
2385
- composite_submit_iso_transfer,
2386
- composite_submit_control_transfer,
2387
- composite_cancel_transfer,
2388
- composite_copy_transfer_data,
2389
- },
2390
- {
2391
- USB_API_WINUSBX,
2392
- "WinUSB-like APIs",
2393
- winusbx_driver_names,
2394
- ARRAYSIZE(winusbx_driver_names),
2395
- winusbx_init,
2396
- winusbx_exit,
2397
- winusbx_open,
2398
- winusbx_close,
2399
- winusbx_configure_endpoints,
2400
- winusbx_claim_interface,
2401
- winusbx_set_interface_altsetting,
2402
- winusbx_release_interface,
2403
- winusbx_clear_halt,
2404
- winusbx_reset_device,
2405
- winusbx_submit_bulk_transfer,
2406
- winusbx_submit_iso_transfer,
2407
- winusbx_submit_control_transfer,
2408
- winusbx_cancel_transfer,
2409
- winusbx_copy_transfer_data,
2410
- },
2411
- {
2412
- USB_API_HID,
2413
- "HID API",
2414
- hid_driver_names,
2415
- ARRAYSIZE(hid_driver_names),
2416
- hid_init,
2417
- hid_exit,
2418
- hid_open,
2419
- hid_close,
2420
- NULL, /* configure_endpoints */
2421
- hid_claim_interface,
2422
- hid_set_interface_altsetting,
2423
- hid_release_interface,
2424
- hid_clear_halt,
2425
- hid_reset_device,
2426
- hid_submit_bulk_transfer,
2427
- NULL, /* submit_iso_transfer */
2428
- hid_submit_control_transfer,
2429
- NULL, /* cancel_transfer */
2430
- hid_copy_transfer_data,
2431
- },
2432
- };
2433
-
2434
-
2435
- /*
2436
- * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
2437
- */
2438
- #define WinUSB_Set(h, fn, required) \
2439
- do { \
2440
- WinUSBX[SUB_API_WINUSB].fn = (WinUsb_##fn##_t)GetProcAddress(h, "WinUsb_" #fn); \
2441
- if (required && (WinUSBX[SUB_API_WINUSB].fn == NULL)) { \
2442
- usbi_err(ctx, "GetProcAddress() failed for WinUsb_%s", #fn); \
2443
- goto cleanup_winusb; \
2444
- } \
2445
- } while (0)
2446
-
2447
- #define libusbK_Set(sub_api, fn, required) \
2448
- do { \
2449
- pLibK_GetProcAddress((PVOID *)&WinUSBX[sub_api].fn, sub_api, KUSB_FNID_##fn); \
2450
- if (required && (WinUSBX[sub_api].fn == NULL)) { \
2451
- usbi_err(ctx, "LibK_GetProcAddress() failed for LibK_%s", #fn); \
2452
- goto cleanup_libusbk; \
2453
- } \
2454
- } while (0)
2455
-
2456
- static bool winusbx_init(struct libusb_context *ctx)
2457
- {
2458
- HMODULE hWinUSB, hlibusbK;
2459
-
2460
- hWinUSB = load_system_library(ctx, "WinUSB");
2461
- if (hWinUSB != NULL) {
2462
- WinUSB_Set(hWinUSB, AbortPipe, true);
2463
- WinUSB_Set(hWinUSB, ControlTransfer, true);
2464
- WinUSB_Set(hWinUSB, FlushPipe, true);
2465
- WinUSB_Set(hWinUSB, Free, true);
2466
- WinUSB_Set(hWinUSB, GetAssociatedInterface, true);
2467
- WinUSB_Set(hWinUSB, Initialize, true);
2468
- WinUSB_Set(hWinUSB, ReadPipe, true);
2469
- WinUSB_Set(hWinUSB, ResetPipe, true);
2470
- WinUSB_Set(hWinUSB, SetCurrentAlternateSetting, true);
2471
- WinUSB_Set(hWinUSB, SetPipePolicy, true);
2472
- WinUSB_Set(hWinUSB, GetPipePolicy, true);
2473
- WinUSB_Set(hWinUSB, WritePipe, true);
2474
-
2475
- // Check for isochronous transfers support (available starting with Windows 8.1)
2476
- WinUSB_Set(hWinUSB, ReadIsochPipeAsap, false);
2477
- if (WinUSBX[SUB_API_WINUSB].ReadIsochPipeAsap != NULL) {
2478
- WinUSB_Set(hWinUSB, QueryPipeEx, true);
2479
- WinUSB_Set(hWinUSB, RegisterIsochBuffer, true);
2480
- WinUSB_Set(hWinUSB, UnregisterIsochBuffer, true);
2481
- WinUSB_Set(hWinUSB, WriteIsochPipeAsap, true);
2482
- }
2483
-
2484
- WinUSBX[SUB_API_WINUSB].hDll = hWinUSB;
2485
-
2486
- usbi_info(ctx, "WinUSB DLL available (%s isoch support)",
2487
- (WinUSBX[SUB_API_WINUSB].ReadIsochPipeAsap != NULL) ? "with" : "without");
2488
-
2489
- cleanup_winusb:
2490
- if (WinUSBX[SUB_API_WINUSB].hDll == NULL) {
2491
- usbi_err(ctx, "failed to initialize WinUSB");
2492
- memset(&WinUSBX[SUB_API_WINUSB], 0, sizeof(WinUSBX[SUB_API_WINUSB]));
2493
- FreeLibrary(hWinUSB);
2494
- hWinUSB = NULL;
2495
- }
2496
- } else {
2497
- usbi_info(ctx, "WinUSB DLL is not available");
2498
- }
2499
-
2500
- hlibusbK = load_system_library(ctx, "libusbK");
2501
- if (hlibusbK != NULL) {
2502
- LibK_GetVersion_t pLibK_GetVersion;
2503
- LibK_GetProcAddress_t pLibK_GetProcAddress;
2504
- int sub_api = 0;
2505
-
2506
- pLibK_GetVersion = (LibK_GetVersion_t)GetProcAddress(hlibusbK, "LibK_GetVersion");
2507
- if (pLibK_GetVersion != NULL) {
2508
- KLIB_VERSION LibK_Version;
2509
-
2510
- pLibK_GetVersion(&LibK_Version);
2511
- usbi_dbg(ctx, "libusbK DLL found, version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
2512
- LibK_Version.Micro, LibK_Version.Nano);
2513
- } else {
2514
- usbi_dbg(ctx, "libusbK DLL found, version unknown");
2515
- }
2516
-
2517
- pLibK_GetProcAddress = (LibK_GetProcAddress_t)GetProcAddress(hlibusbK, "LibK_GetProcAddress");
2518
- if (pLibK_GetProcAddress == NULL) {
2519
- usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
2520
- goto cleanup_libusbk;
2521
- }
2522
-
2523
- // NB: The below for loop works because the sub_api value for WinUSB
2524
- // is a higher value than that of libusbK and libusb0
2525
- for (; sub_api < SUB_API_WINUSB; sub_api++) {
2526
- libusbK_Set(sub_api, AbortPipe, true);
2527
- libusbK_Set(sub_api, ControlTransfer, true);
2528
- libusbK_Set(sub_api, FlushPipe, true);
2529
- libusbK_Set(sub_api, Free, true);
2530
- libusbK_Set(sub_api, GetAssociatedInterface, true);
2531
- libusbK_Set(sub_api, Initialize, true);
2532
- libusbK_Set(sub_api, ReadPipe, true);
2533
- libusbK_Set(sub_api, ResetPipe, true);
2534
- libusbK_Set(sub_api, SetCurrentAlternateSetting, true);
2535
- libusbK_Set(sub_api, SetPipePolicy, true);
2536
- libusbK_Set(sub_api, WritePipe, true);
2537
-
2538
- // Optional isochronous support
2539
- libusbK_Set(sub_api, IsoReadPipe, false);
2540
- if (WinUSBX[sub_api].IsoReadPipe != NULL)
2541
- libusbK_Set(sub_api, IsoWritePipe, true);
2542
-
2543
- // Optional device reset support
2544
- libusbK_Set(sub_api, ResetDevice, false);
2545
-
2546
- WinUSBX[sub_api].hDll = hlibusbK;
2547
- }
2548
-
2549
- cleanup_libusbk:
2550
- if (sub_api < SUB_API_WINUSB) {
2551
- usbi_err(ctx, "failed to initialize libusbK");
2552
- while (sub_api >= 0) {
2553
- memset(&WinUSBX[sub_api], 0, sizeof(WinUSBX[sub_api]));
2554
- sub_api--;
2555
- }
2556
- FreeLibrary(hlibusbK);
2557
- hlibusbK = NULL;
2558
- }
2559
- } else {
2560
- usbi_info(ctx, "libusbK DLL is not available");
2561
- }
2562
-
2563
- if ((hWinUSB == NULL) && (hlibusbK == NULL)) {
2564
- usbi_warn(ctx, "neither WinUSB nor libusbK DLLs were found, "
2565
- "you will not be able to access devices outside of enumeration");
2566
- return false;
2567
- }
2568
-
2569
- return true;
2570
- }
2571
-
2572
- static void winusbx_exit(void)
2573
- {
2574
- bool loaded = false;
2575
- HMODULE hDll;
2576
-
2577
- hDll = WinUSBX[SUB_API_LIBUSBK].hDll;
2578
- if (hDll != NULL) {
2579
- FreeLibrary(hDll);
2580
- loaded = true;
2581
- }
2582
-
2583
- hDll = WinUSBX[SUB_API_WINUSB].hDll;
2584
- if (hDll != NULL) {
2585
- FreeLibrary(hDll);
2586
- loaded = true;
2587
- }
2588
-
2589
- // Reset the WinUSBX API structures if something was loaded
2590
- if (loaded)
2591
- memset(&WinUSBX, 0, sizeof(WinUSBX));
2592
- }
2593
-
2594
- // NB: open and close must ensure that they only handle interface of
2595
- // the right API type, as these functions can be called wholesale from
2596
- // composite_open(), with interfaces belonging to different APIs
2597
- static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
2598
- {
2599
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2600
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
2601
- HANDLE file_handle;
2602
- int i;
2603
-
2604
- CHECK_WINUSBX_AVAILABLE(sub_api);
2605
-
2606
- // WinUSB requires a separate handle for each interface
2607
- for (i = 0; i < USB_MAXINTERFACES; i++) {
2608
- if ((priv->usb_interface[i].path != NULL)
2609
- && (priv->usb_interface[i].apib->id == USB_API_WINUSBX)) {
2610
- file_handle = windows_open(dev_handle, priv->usb_interface[i].path, GENERIC_READ | GENERIC_WRITE);
2611
- if (file_handle == INVALID_HANDLE_VALUE) {
2612
- usbi_err(HANDLE_CTX(dev_handle), "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
2613
- switch (GetLastError()) {
2614
- case ERROR_FILE_NOT_FOUND: // The device was disconnected
2615
- return LIBUSB_ERROR_NO_DEVICE;
2616
- case ERROR_ACCESS_DENIED:
2617
- return LIBUSB_ERROR_ACCESS;
2618
- default:
2619
- return LIBUSB_ERROR_IO;
2620
- }
2621
- }
2622
-
2623
- handle_priv->interface_handle[i].dev_handle = file_handle;
2624
- }
2625
- }
2626
-
2627
- return LIBUSB_SUCCESS;
2628
- }
2629
-
2630
- static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
2631
- {
2632
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
2633
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2634
- HANDLE handle;
2635
- int i, ai;
2636
-
2637
- if (sub_api == SUB_API_NOTSET)
2638
- sub_api = priv->sub_api;
2639
-
2640
- if (WinUSBX[sub_api].hDll == NULL)
2641
- return;
2642
-
2643
- if (priv->apib->id == USB_API_COMPOSITE) {
2644
- // If this is a composite device, just free and close any WinUSB-like
2645
- // interfaces that are not part of an associated group
2646
- // (each is independent and not associated with another).
2647
- // For associated interface groupings, free interfaces that
2648
- // are NOT the first within that group (i.e. not bFirstInterface),
2649
- // then free & close bFirstInterface last.
2650
- for (i = 0; i < USB_MAXINTERFACES; i++) {
2651
- if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
2652
- if (priv->usb_interface[i].num_associated_interfaces == 0) {
2653
- handle = handle_priv->interface_handle[i].api_handle;
2654
- if (HANDLE_VALID(handle))
2655
- WinUSBX[sub_api].Free(handle);
2656
-
2657
- handle = handle_priv->interface_handle[i].dev_handle;
2658
- if (HANDLE_VALID(handle))
2659
- CloseHandle(handle);
2660
- } else {
2661
- if (i==priv->usb_interface[i].first_associated_interface) {
2662
- //first free all handles for all *other* associated interfaces
2663
- for (ai = 1; ai < priv->usb_interface[i].num_associated_interfaces; ai++) {
2664
- handle = handle_priv->interface_handle[i + ai].api_handle;
2665
- if (HANDLE_VALID(handle))
2666
- WinUSBX[sub_api].Free(handle);
2667
- }
2668
-
2669
- //free & close bFirstInterface
2670
- handle = handle_priv->interface_handle[i].api_handle;
2671
- if (HANDLE_VALID(handle))
2672
- WinUSBX[sub_api].Free(handle);
2673
-
2674
- handle = handle_priv->interface_handle[i].dev_handle;
2675
- if (HANDLE_VALID(handle))
2676
- CloseHandle(handle);
2677
- }
2678
- }
2679
- }
2680
- }
2681
- } else {
2682
- // If this is a WinUSB device, free all interfaces above interface 0,
2683
- // then free and close interface 0 last
2684
- for (i = 1; i < USB_MAXINTERFACES; i++) {
2685
- handle = handle_priv->interface_handle[i].api_handle;
2686
- if (HANDLE_VALID(handle))
2687
- WinUSBX[sub_api].Free(handle);
2688
- }
2689
- handle = handle_priv->interface_handle[0].api_handle;
2690
- if (HANDLE_VALID(handle))
2691
- WinUSBX[sub_api].Free(handle);
2692
-
2693
- handle = handle_priv->interface_handle[0].dev_handle;
2694
- if (HANDLE_VALID(handle))
2695
- CloseHandle(handle);
2696
- }
2697
- }
2698
-
2699
- static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
2700
- {
2701
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
2702
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2703
- HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle;
2704
- UCHAR policy;
2705
- ULONG timeout = 0;
2706
- uint8_t endpoint_address;
2707
- int i;
2708
-
2709
- CHECK_WINUSBX_AVAILABLE(sub_api);
2710
-
2711
- // With handle and endpoints set (in parent), we can setup the default pipe properties
2712
- // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx
2713
- for (i = -1; i < priv->usb_interface[iface].nb_endpoints; i++) {
2714
- endpoint_address = (i == -1) ? 0 : priv->usb_interface[iface].endpoint[i];
2715
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2716
- PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout))
2717
- usbi_dbg(HANDLE_CTX(dev_handle), "failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
2718
-
2719
- if ((i == -1) || (sub_api == SUB_API_LIBUSB0))
2720
- continue; // Other policies don't apply to control endpoint or libusb0
2721
-
2722
- policy = false;
2723
- handle_priv->interface_handle[iface].zlp[endpoint_address] = WINUSB_ZLP_UNSET;
2724
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2725
- SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy))
2726
- usbi_dbg(HANDLE_CTX(dev_handle), "failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
2727
-
2728
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2729
- IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy))
2730
- usbi_dbg(HANDLE_CTX(dev_handle), "failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
2731
-
2732
- policy = true;
2733
- /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
2734
- https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
2735
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2736
- ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy))
2737
- usbi_dbg(HANDLE_CTX(dev_handle), "failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
2738
-
2739
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2740
- AUTO_CLEAR_STALL, sizeof(UCHAR), &policy))
2741
- usbi_dbg(HANDLE_CTX(dev_handle), "failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
2742
-
2743
- if (sub_api == SUB_API_LIBUSBK) {
2744
- if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
2745
- ISO_ALWAYS_START_ASAP, sizeof(UCHAR), &policy))
2746
- usbi_dbg(HANDLE_CTX(dev_handle), "failed to enable ISO_ALWAYS_START_ASAP for endpoint %02X", endpoint_address);
2747
- }
2748
- }
2749
-
2750
- return LIBUSB_SUCCESS;
2751
- }
2752
-
2753
- static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
2754
- {
2755
- struct libusb_context *ctx = HANDLE_CTX(dev_handle);
2756
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
2757
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2758
- bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
2759
- bool is_associated_interface = (priv->usb_interface[iface].num_associated_interfaces != 0);
2760
- HDEVINFO dev_info;
2761
- char *dev_interface_path = NULL;
2762
- char *dev_interface_path_guid_start;
2763
- char filter_path[] = "\\\\.\\libusb0-0000";
2764
- bool found_filter = false;
2765
- HANDLE file_handle, winusb_handle;
2766
- DWORD err, _index;
2767
- int r;
2768
- uint8_t initialized_iface;
2769
-
2770
- CHECK_WINUSBX_AVAILABLE(sub_api);
2771
-
2772
- // If the device is composite, but using the default Windows composite parent driver (usbccgp)
2773
- // or if it's the first WinUSB-like interface, we get a handle through Initialize().
2774
- // If it's an associated interface, and is the first one (iface==bFirstInterface), we also
2775
- // want to get the handle through Initialize(). If it's an associated interface, and NOT
2776
- // the first one, we want to direct control to the 'else' where the handle will be obtained
2777
- // via GetAssociatedInterface().
2778
- if (((is_using_usbccgp) || (iface == 0)) &&
2779
- (!is_associated_interface || (iface==priv->usb_interface[iface].first_associated_interface))) {
2780
- // composite device (independent interfaces) or interface 0
2781
- file_handle = handle_priv->interface_handle[iface].dev_handle;
2782
- if (!HANDLE_VALID(file_handle))
2783
- return LIBUSB_ERROR_NOT_FOUND;
2784
-
2785
- if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2786
- handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2787
- err = GetLastError();
2788
- switch (err) {
2789
- case ERROR_BAD_COMMAND:
2790
- // The device was disconnected
2791
- usbi_err(ctx, "could not access interface %u: %s", iface, windows_error_str(0));
2792
- return LIBUSB_ERROR_NO_DEVICE;
2793
- default:
2794
- // it may be that we're using the libusb0 filter driver.
2795
- // TODO: can we move this whole business into the K/0 DLL?
2796
- r = LIBUSB_SUCCESS;
2797
- for (_index = 0; ; _index++) {
2798
- safe_free(dev_interface_path);
2799
-
2800
- if (found_filter)
2801
- break;
2802
-
2803
- r = get_interface_details_filter(ctx, &dev_info, _index, filter_path, &dev_interface_path);
2804
- if ((r != LIBUSB_SUCCESS) || (dev_interface_path == NULL))
2805
- break;
2806
-
2807
- // ignore GUID part
2808
- dev_interface_path_guid_start = strchr(dev_interface_path, '{');
2809
- if (dev_interface_path_guid_start == NULL)
2810
- continue;
2811
- *dev_interface_path_guid_start = '\0';
2812
-
2813
- if (strncmp(dev_interface_path, priv->usb_interface[iface].path, strlen(dev_interface_path)) == 0) {
2814
- file_handle = windows_open(dev_handle, filter_path, GENERIC_READ | GENERIC_WRITE);
2815
- if (file_handle != INVALID_HANDLE_VALUE) {
2816
- if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2817
- // Replace the existing file handle with the working one
2818
- CloseHandle(handle_priv->interface_handle[iface].dev_handle);
2819
- handle_priv->interface_handle[iface].dev_handle = file_handle;
2820
- found_filter = true;
2821
- } else {
2822
- usbi_err(ctx, "could not initialize filter driver for %s", filter_path);
2823
- CloseHandle(file_handle);
2824
- }
2825
- } else {
2826
- usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
2827
- }
2828
- }
2829
- }
2830
- if (r != LIBUSB_SUCCESS)
2831
- return r;
2832
- if (!found_filter) {
2833
- usbi_err(ctx, "could not access interface %u: %s", iface, windows_error_str(err));
2834
- return LIBUSB_ERROR_ACCESS;
2835
- }
2836
- }
2837
- }
2838
- handle_priv->interface_handle[iface].api_handle = winusb_handle;
2839
- } else {
2840
- if (is_associated_interface) {
2841
- initialized_iface = priv->usb_interface[iface].first_associated_interface;
2842
- if (iface <= initialized_iface) {
2843
- usbi_err(ctx, "invalid associated index. iface=%u, initialized iface=%u", iface, initialized_iface);
2844
- return LIBUSB_ERROR_NOT_FOUND;
2845
- }
2846
- } else {
2847
- initialized_iface = 0;
2848
- }
2849
-
2850
- // For all other interfaces, use GetAssociatedInterface()
2851
- winusb_handle = handle_priv->interface_handle[initialized_iface].api_handle;
2852
- // It is a requirement for multiple interface devices on Windows that, to you
2853
- // must first claim the first interface before you claim the others
2854
- if (!HANDLE_VALID(winusb_handle)) {
2855
- file_handle = handle_priv->interface_handle[initialized_iface].dev_handle;
2856
- if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2857
- handle_priv->interface_handle[initialized_iface].api_handle = winusb_handle;
2858
- usbi_warn(ctx, "auto-claimed interface %u (required to claim %u with WinUSB)", initialized_iface, iface);
2859
- } else {
2860
- usbi_warn(ctx, "failed to auto-claim interface %u (required to claim %u with WinUSB): %s",
2861
- initialized_iface, iface, windows_error_str(0));
2862
- return LIBUSB_ERROR_ACCESS;
2863
- }
2864
- }
2865
- if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface - 1 - initialized_iface),
2866
- &handle_priv->interface_handle[iface].api_handle)) {
2867
- handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2868
- switch (GetLastError()) {
2869
- case ERROR_NO_MORE_ITEMS: // invalid iface
2870
- return LIBUSB_ERROR_NOT_FOUND;
2871
- case ERROR_BAD_COMMAND: // The device was disconnected
2872
- return LIBUSB_ERROR_NO_DEVICE;
2873
- case ERROR_ALREADY_EXISTS: // already claimed
2874
- return LIBUSB_ERROR_BUSY;
2875
- default:
2876
- usbi_err(ctx, "could not claim interface %u: %s", iface, windows_error_str(0));
2877
- return LIBUSB_ERROR_ACCESS;
2878
- }
2879
- }
2880
- handle_priv->interface_handle[iface].dev_handle = handle_priv->interface_handle[initialized_iface].dev_handle;
2881
- }
2882
- usbi_dbg(ctx, "claimed interface %u", iface);
2883
- handle_priv->active_interface = iface;
2884
-
2885
- return LIBUSB_SUCCESS;
2886
- }
2887
-
2888
- static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
2889
- {
2890
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
2891
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2892
- HANDLE winusb_handle;
2893
-
2894
- CHECK_WINUSBX_AVAILABLE(sub_api);
2895
-
2896
- winusb_handle = handle_priv->interface_handle[iface].api_handle;
2897
- if (!HANDLE_VALID(winusb_handle))
2898
- return LIBUSB_ERROR_NOT_FOUND;
2899
-
2900
- WinUSBX[sub_api].Free(winusb_handle);
2901
- handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
2902
-
2903
- return LIBUSB_SUCCESS;
2904
- }
2905
-
2906
- /*
2907
- * Return the first valid interface (of the same API type), for control transfers
2908
- */
2909
- static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
2910
- {
2911
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
2912
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2913
- int i;
2914
-
2915
- if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2916
- usbi_dbg(HANDLE_CTX(dev_handle), "unsupported API ID");
2917
- return -1;
2918
- }
2919
-
2920
- for (i = 0; i < USB_MAXINTERFACES; i++) {
2921
- if (HANDLE_VALID(handle_priv->interface_handle[i].dev_handle)
2922
- && HANDLE_VALID(handle_priv->interface_handle[i].api_handle)
2923
- && (priv->usb_interface[i].apib->id == api_id))
2924
- return i;
2925
- }
2926
-
2927
- return -1;
2928
- }
2929
-
2930
- /*
2931
- * Check a specific interface is valid (of the same API type), for control transfers
2932
- */
2933
- static int check_valid_interface(struct libusb_device_handle *dev_handle, unsigned short interface, int api_id)
2934
- {
2935
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
2936
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
2937
-
2938
- if (interface >= USB_MAXINTERFACES)
2939
- return -1;
2940
-
2941
- if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
2942
- usbi_dbg(HANDLE_CTX(dev_handle), "unsupported API ID");
2943
- return -1;
2944
- }
2945
-
2946
- // try the requested interface
2947
- if (HANDLE_VALID(handle_priv->interface_handle[interface].dev_handle)
2948
- && HANDLE_VALID(handle_priv->interface_handle[interface].api_handle)
2949
- && (priv->usb_interface[interface].apib->id == api_id))
2950
- return interface;
2951
-
2952
- return -1;
2953
- }
2954
-
2955
- /*
2956
- * Lookup interface by endpoint address. -1 if not found
2957
- */
2958
- static int interface_by_endpoint(struct winusb_device_priv *priv,
2959
- struct winusb_device_handle_priv *handle_priv, uint8_t endpoint_address)
2960
- {
2961
- int i, j;
2962
-
2963
- for (i = 0; i < USB_MAXINTERFACES; i++) {
2964
- if (!HANDLE_VALID(handle_priv->interface_handle[i].api_handle))
2965
- continue;
2966
- if (priv->usb_interface[i].endpoint == NULL)
2967
- continue;
2968
- for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) {
2969
- if (priv->usb_interface[i].endpoint[j] == endpoint_address)
2970
- return i;
2971
- }
2972
- }
2973
-
2974
- return -1;
2975
- }
2976
-
2977
- static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
2978
- {
2979
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2980
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
2981
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
2982
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
2983
- PWINUSB_SETUP_PACKET setup = (PWINUSB_SETUP_PACKET)transfer->buffer;
2984
- ULONG size, transferred;
2985
- HANDLE winusb_handle;
2986
- OVERLAPPED *overlapped;
2987
- int current_interface;
2988
-
2989
- CHECK_WINUSBX_AVAILABLE(sub_api);
2990
-
2991
- size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
2992
-
2993
- // Windows places upper limits on the control transfer size
2994
- // See: https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-bandwidth-allocation#maximum-transfer-size
2995
- if (size > MAX_CTRL_BUFFER_LENGTH)
2996
- return LIBUSB_ERROR_INVALID_PARAM;
2997
-
2998
- if ((setup->RequestType & 0x1F) == LIBUSB_RECIPIENT_INTERFACE)
2999
- current_interface = check_valid_interface(transfer->dev_handle, setup->Index & 0xff, USB_API_WINUSBX);
3000
- else
3001
- current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX);
3002
- if (current_interface < 0) {
3003
- if (auto_claim(transfer, &current_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS)
3004
- return LIBUSB_ERROR_NOT_FOUND;
3005
- }
3006
-
3007
- usbi_dbg(ITRANSFER_CTX(itransfer), "will use interface %d", current_interface);
3008
-
3009
- transfer_priv->interface_number = (uint8_t)current_interface;
3010
- winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3011
- set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
3012
- overlapped = get_transfer_priv_overlapped(itransfer);
3013
-
3014
- // Sending of set configuration control requests from WinUSB creates issues, except when using libusb0.sys
3015
- if (sub_api != SUB_API_LIBUSB0
3016
- && (LIBUSB_REQ_TYPE(setup->RequestType) == LIBUSB_REQUEST_TYPE_STANDARD)
3017
- && (setup->Request == LIBUSB_REQUEST_SET_CONFIGURATION)) {
3018
- if (setup->Value != priv->active_config) {
3019
- usbi_warn(TRANSFER_CTX(transfer), "cannot set configuration other than the default one");
3020
- return LIBUSB_ERROR_NOT_SUPPORTED;
3021
- }
3022
- windows_force_sync_completion(itransfer, 0);
3023
- } else {
3024
- if (!WinUSBX[sub_api].ControlTransfer(winusb_handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, &transferred, overlapped)) {
3025
- if (GetLastError() != ERROR_IO_PENDING) {
3026
- usbi_warn(TRANSFER_CTX(transfer), "ControlTransfer failed: %s", windows_error_str(0));
3027
- return LIBUSB_ERROR_IO;
3028
- }
3029
- } else {
3030
- windows_force_sync_completion(itransfer, transferred);
3031
- }
3032
- }
3033
-
3034
- return LIBUSB_SUCCESS;
3035
- }
3036
-
3037
- static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
3038
- {
3039
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
3040
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
3041
- HANDLE winusb_handle;
3042
-
3043
- CHECK_WINUSBX_AVAILABLE(sub_api);
3044
-
3045
- winusb_handle = handle_priv->interface_handle[iface].api_handle;
3046
- if (!HANDLE_VALID(winusb_handle)) {
3047
- usbi_err(HANDLE_CTX(dev_handle), "interface must be claimed first");
3048
- return LIBUSB_ERROR_NOT_FOUND;
3049
- }
3050
-
3051
- if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, altsetting)) {
3052
- usbi_err(HANDLE_CTX(dev_handle), "SetCurrentAlternateSetting failed: %s", windows_error_str(0));
3053
- return LIBUSB_ERROR_IO;
3054
- }
3055
-
3056
- return LIBUSB_SUCCESS;
3057
- }
3058
-
3059
-
3060
- static void WINAPI winusbx_native_iso_transfer_continue_stream_callback(struct libusb_transfer *transfer)
3061
- {
3062
- // If this callback is invoked, this means that we attempted to set ContinueStream
3063
- // to TRUE when calling Read/WriteIsochPipeAsap in winusbx_submit_iso_transfer().
3064
- // The role of this callback is to fallback to ContinueStream = FALSE if the transfer
3065
- // did not succeed.
3066
-
3067
- struct winusb_transfer_priv *transfer_priv =
3068
- get_winusb_transfer_priv(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer));
3069
- bool fallback = (transfer->status != LIBUSB_TRANSFER_COMPLETED);
3070
- int idx;
3071
-
3072
- // Restore the user callback
3073
- transfer->callback = transfer_priv->iso_user_callback;
3074
-
3075
- for (idx = 0; idx < transfer->num_iso_packets && !fallback; idx++) {
3076
- if (transfer->iso_packet_desc[idx].status != LIBUSB_TRANSFER_COMPLETED)
3077
- fallback = true;
3078
- }
3079
-
3080
- if (!fallback) {
3081
- // If the transfer was successful, we restore the user callback and call it.
3082
- if (transfer->callback)
3083
- transfer->callback(transfer);
3084
- } else {
3085
- // If the transfer wasn't successful we reschedule the transfer while forcing it
3086
- // not to continue the stream. This might results in a 5-ms delay.
3087
- transfer_priv->iso_break_stream = TRUE;
3088
- libusb_submit_transfer(transfer);
3089
- }
3090
- }
3091
- static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer)
3092
- {
3093
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3094
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
3095
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
3096
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
3097
- HANDLE winusb_handle;
3098
- OVERLAPPED *overlapped;
3099
- BOOL ret;
3100
- int current_interface;
3101
-
3102
- CHECK_WINUSBX_AVAILABLE(sub_api);
3103
-
3104
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3105
- if (current_interface < 0) {
3106
- usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
3107
- return LIBUSB_ERROR_NOT_FOUND;
3108
- }
3109
-
3110
- usbi_dbg(TRANSFER_CTX(transfer), "matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3111
-
3112
- transfer_priv->interface_number = (uint8_t)current_interface;
3113
- winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3114
- set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
3115
- overlapped = get_transfer_priv_overlapped(itransfer);
3116
-
3117
- if ((sub_api == SUB_API_LIBUSBK) || (sub_api == SUB_API_LIBUSB0)) {
3118
- int i;
3119
- UINT offset;
3120
- size_t iso_ctx_size;
3121
- PKISO_CONTEXT iso_context;
3122
-
3123
- if (WinUSBX[sub_api].IsoReadPipe == NULL) {
3124
- usbi_warn(TRANSFER_CTX(transfer), "libusbK DLL does not support isoch transfers");
3125
- return LIBUSB_ERROR_NOT_SUPPORTED;
3126
- }
3127
-
3128
- iso_ctx_size = sizeof(KISO_CONTEXT) + (transfer->num_iso_packets * sizeof(KISO_PACKET));
3129
- transfer_priv->iso_context = iso_context = calloc(1, iso_ctx_size);
3130
- if (transfer_priv->iso_context == NULL)
3131
- return LIBUSB_ERROR_NO_MEM;
3132
-
3133
- // start ASAP
3134
- iso_context->StartFrame = 0;
3135
- iso_context->NumberOfPackets = (SHORT)transfer->num_iso_packets;
3136
-
3137
- // convert the transfer packet lengths to iso_packet offsets
3138
- offset = 0;
3139
- for (i = 0; i < transfer->num_iso_packets; i++) {
3140
- iso_context->IsoPackets[i].offset = offset;
3141
- offset += transfer->iso_packet_desc[i].length;
3142
- }
3143
-
3144
- if (IS_XFERIN(transfer)) {
3145
- usbi_dbg(TRANSFER_CTX(transfer), "reading %d iso packets", transfer->num_iso_packets);
3146
- ret = WinUSBX[sub_api].IsoReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context);
3147
- } else {
3148
- usbi_dbg(TRANSFER_CTX(transfer), "writing %d iso packets", transfer->num_iso_packets);
3149
- ret = WinUSBX[sub_api].IsoWritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context);
3150
- }
3151
-
3152
- if (!ret && GetLastError() != ERROR_IO_PENDING) {
3153
- usbi_err(TRANSFER_CTX(transfer), "IsoReadPipe/IsoWritePipe failed: %s", windows_error_str(0));
3154
- return LIBUSB_ERROR_IO;
3155
- }
3156
-
3157
- return LIBUSB_SUCCESS;
3158
- } else if (sub_api == SUB_API_WINUSB) {
3159
- WINUSB_PIPE_INFORMATION_EX pipe_info_ex = { 0 };
3160
- WINUSB_ISOCH_BUFFER_HANDLE buffer_handle;
3161
- ULONG iso_transfer_size_multiple;
3162
- int out_transfer_length = 0;
3163
- int idx;
3164
-
3165
- // Depending on the version of Microsoft WinUSB, isochronous transfers may not be supported.
3166
- if (WinUSBX[sub_api].ReadIsochPipeAsap == NULL) {
3167
- usbi_warn(TRANSFER_CTX(transfer), "WinUSB DLL does not support isoch transfers");
3168
- return LIBUSB_ERROR_NOT_SUPPORTED;
3169
- }
3170
-
3171
- if (sizeof(struct libusb_iso_packet_descriptor) != sizeof(USBD_ISO_PACKET_DESCRIPTOR)) {
3172
- usbi_err(TRANSFER_CTX(transfer), "size of WinUsb and libusb isoch packet descriptors don't match");
3173
- return LIBUSB_ERROR_NOT_SUPPORTED;
3174
- }
3175
-
3176
- // Query the pipe extended information to find the pipe index corresponding to the endpoint.
3177
- for (idx = 0; idx < priv->usb_interface[current_interface].nb_endpoints; ++idx) {
3178
- ret = WinUSBX[sub_api].QueryPipeEx(winusb_handle, (UINT8)priv->usb_interface[current_interface].current_altsetting, (UCHAR)idx, &pipe_info_ex);
3179
- if (!ret) {
3180
- usbi_err(TRANSFER_CTX(transfer), "couldn't query interface settings for USB pipe with index %d. Error: %s", idx, windows_error_str(0));
3181
- return LIBUSB_ERROR_NOT_FOUND;
3182
- }
3183
-
3184
- if (pipe_info_ex.PipeId == transfer->endpoint && pipe_info_ex.PipeType == UsbdPipeTypeIsochronous)
3185
- break;
3186
- }
3187
-
3188
- // Make sure we found the index.
3189
- if (idx == priv->usb_interface[current_interface].nb_endpoints) {
3190
- usbi_err(TRANSFER_CTX(transfer), "couldn't find isoch endpoint 0x%02x", transfer->endpoint);
3191
- return LIBUSB_ERROR_NOT_FOUND;
3192
- }
3193
-
3194
- if (IS_XFERIN(transfer)) {
3195
- int interval = pipe_info_ex.Interval;
3196
-
3197
- // For high-speed and SuperSpeed device, the interval is 2**(bInterval-1).
3198
- if (transfer->dev_handle->dev->speed >= LIBUSB_SPEED_HIGH)
3199
- interval = (1 << (pipe_info_ex.Interval - 1));
3200
-
3201
- // WinUSB only supports isoch transfers spanning a full USB frames. Later, we might be smarter about this
3202
- // and allocate a temporary buffer. However, this is harder than it seems as its destruction would depend on overlapped
3203
- // IO...
3204
- if (transfer->dev_handle->dev->speed >= LIBUSB_SPEED_HIGH) // Microframes (125us)
3205
- iso_transfer_size_multiple = (pipe_info_ex.MaximumBytesPerInterval * 8) / interval;
3206
- else // Normal Frames (1ms)
3207
- iso_transfer_size_multiple = pipe_info_ex.MaximumBytesPerInterval / interval;
3208
-
3209
- if (transfer->length % iso_transfer_size_multiple != 0) {
3210
- usbi_err(TRANSFER_CTX(transfer), "length of isoch buffer must be a multiple of the MaximumBytesPerInterval * 8 / Interval");
3211
- return LIBUSB_ERROR_INVALID_PARAM;
3212
- }
3213
- } else {
3214
- // If this is an OUT transfer, we make sure the isoch packets are contiguous as this isn't supported otherwise.
3215
- bool size_should_be_zero = false;
3216
-
3217
- for (idx = 0; idx < transfer->num_iso_packets; ++idx) {
3218
- if ((size_should_be_zero && transfer->iso_packet_desc[idx].length != 0) ||
3219
- (transfer->iso_packet_desc[idx].length != pipe_info_ex.MaximumBytesPerInterval && idx + 1 < transfer->num_iso_packets && transfer->iso_packet_desc[idx + 1].length > 0)) {
3220
- usbi_err(TRANSFER_CTX(transfer), "isoch packets for OUT transfer with WinUSB must be contiguous in memory");
3221
- return LIBUSB_ERROR_INVALID_PARAM;
3222
- }
3223
-
3224
- size_should_be_zero = (transfer->iso_packet_desc[idx].length == 0);
3225
- out_transfer_length += transfer->iso_packet_desc[idx].length;
3226
- }
3227
- }
3228
-
3229
- if (transfer_priv->isoch_buffer_handle != NULL) {
3230
- if (WinUSBX[sub_api].UnregisterIsochBuffer(transfer_priv->isoch_buffer_handle)) {
3231
- transfer_priv->isoch_buffer_handle = NULL;
3232
- } else {
3233
- usbi_err(TRANSFER_CTX(transfer), "failed to unregister WinUSB isoch buffer: %s", windows_error_str(0));
3234
- return LIBUSB_ERROR_OTHER;
3235
- }
3236
- }
3237
-
3238
- // Register the isoch buffer to the operating system.
3239
- ret = WinUSBX[sub_api].RegisterIsochBuffer(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, &buffer_handle);
3240
- if (!ret) {
3241
- usbi_err(TRANSFER_CTX(transfer), "failed to register WinUSB isoch buffer: %s", windows_error_str(0));
3242
- return LIBUSB_ERROR_NO_MEM;
3243
- }
3244
-
3245
- // Important note: the WinUSB_Read/WriteIsochPipeAsap API requires a ContinueStream parameter that tells whether the isochronous
3246
- // stream must be continued or if the WinUSB driver can schedule the transfer at its convenience. Profiling subsequent transfers
3247
- // with ContinueStream = FALSE showed that 5 frames, i.e. about 5 milliseconds, were left empty between each transfer. This
3248
- // is critical as this greatly diminish the achievable isochronous bandwidth. We solved the problem using the following strategy:
3249
- // - Transfers are first scheduled with ContinueStream = TRUE and with winusbx_iso_transfer_continue_stream_callback as user callback.
3250
- // - If the transfer succeeds, winusbx_iso_transfer_continue_stream_callback restore the user callback and calls its.
3251
- // - If the transfer fails, winusbx_iso_transfer_continue_stream_callback reschedule the transfer and force ContinueStream = FALSE.
3252
- if (!transfer_priv->iso_break_stream) {
3253
- transfer_priv->iso_user_callback = transfer->callback;
3254
- transfer->callback = winusbx_native_iso_transfer_continue_stream_callback;
3255
- }
3256
-
3257
- // Initiate the transfers.
3258
- if (IS_XFERIN(transfer))
3259
- ret = WinUSBX[sub_api].ReadIsochPipeAsap(buffer_handle, 0, transfer->length, !transfer_priv->iso_break_stream, transfer->num_iso_packets, (PUSBD_ISO_PACKET_DESCRIPTOR)transfer->iso_packet_desc, overlapped);
3260
- else
3261
- ret = WinUSBX[sub_api].WriteIsochPipeAsap(buffer_handle, 0, out_transfer_length, !transfer_priv->iso_break_stream, overlapped);
3262
-
3263
- if (!ret && GetLastError() != ERROR_IO_PENDING) {
3264
- usbi_err(TRANSFER_CTX(transfer), "ReadIsochPipeAsap/WriteIsochPipeAsap failed: %s", windows_error_str(0));
3265
- if (!WinUSBX[sub_api].UnregisterIsochBuffer(buffer_handle))
3266
- usbi_warn(TRANSFER_CTX(transfer), "failed to unregister WinUSB isoch buffer: %s", windows_error_str(0));
3267
- return LIBUSB_ERROR_IO;
3268
- }
3269
-
3270
- // Restore the ContinueStream parameter to TRUE.
3271
- transfer_priv->iso_break_stream = FALSE;
3272
-
3273
- transfer_priv->isoch_buffer_handle = buffer_handle;
3274
-
3275
- return LIBUSB_SUCCESS;
3276
- } else {
3277
- PRINT_UNSUPPORTED_API(winusbx_submit_iso_transfer);
3278
- return LIBUSB_ERROR_NOT_SUPPORTED;
3279
- }
3280
- }
3281
-
3282
- static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
3283
- {
3284
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3285
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
3286
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
3287
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
3288
- HANDLE winusb_handle;
3289
- OVERLAPPED *overlapped;
3290
- BOOL ret;
3291
- int current_interface;
3292
-
3293
- CHECK_WINUSBX_AVAILABLE(sub_api);
3294
-
3295
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
3296
- if (current_interface < 0) {
3297
- usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
3298
- return LIBUSB_ERROR_NOT_FOUND;
3299
- }
3300
-
3301
- usbi_dbg(TRANSFER_CTX(transfer), "matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
3302
-
3303
- transfer_priv->interface_number = (uint8_t)current_interface;
3304
- winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3305
- set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
3306
- overlapped = get_transfer_priv_overlapped(itransfer);
3307
-
3308
- if (IS_XFERIN(transfer)) {
3309
- usbi_dbg(TRANSFER_CTX(transfer), "reading %d bytes", transfer->length);
3310
- ret = WinUSBX[sub_api].ReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped);
3311
- } else {
3312
- // Set SHORT_PACKET_TERMINATE if ZLP requested.
3313
- // Changing this can be a problem with packets in flight, so only allow on the first transfer.
3314
- UCHAR policy = (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) != 0;
3315
- uint8_t* current_zlp = &handle_priv->interface_handle[current_interface].zlp[transfer->endpoint];
3316
- if (*current_zlp == WINUSB_ZLP_UNSET) {
3317
- if (policy &&
3318
- !WinUSBX[sub_api].SetPipePolicy(winusb_handle, transfer->endpoint,
3319
- SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) {
3320
- usbi_err(TRANSFER_CTX(transfer), "failed to set SHORT_PACKET_TERMINATE for endpoint %02X", transfer->endpoint);
3321
- return LIBUSB_ERROR_NOT_SUPPORTED;
3322
- }
3323
- *current_zlp = policy ? WINUSB_ZLP_ON : WINUSB_ZLP_OFF;
3324
- } else if (policy != (*current_zlp == WINUSB_ZLP_ON)) {
3325
- usbi_err(TRANSFER_CTX(transfer), "cannot change ZERO_PACKET for endpoint %02X on Windows", transfer->endpoint);
3326
- return LIBUSB_ERROR_NOT_SUPPORTED;
3327
- }
3328
-
3329
- usbi_dbg(TRANSFER_CTX(transfer), "writing %d bytes", transfer->length);
3330
- ret = WinUSBX[sub_api].WritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped);
3331
- }
3332
-
3333
- if (!ret && GetLastError() != ERROR_IO_PENDING) {
3334
- usbi_err(TRANSFER_CTX(transfer), "ReadPipe/WritePipe failed: %s", windows_error_str(0));
3335
- return LIBUSB_ERROR_IO;
3336
- }
3337
-
3338
- return LIBUSB_SUCCESS;
3339
- }
3340
-
3341
- static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
3342
- {
3343
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
3344
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
3345
- HANDLE winusb_handle;
3346
- int current_interface;
3347
-
3348
- CHECK_WINUSBX_AVAILABLE(sub_api);
3349
-
3350
- current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
3351
- if (current_interface < 0) {
3352
- usbi_err(HANDLE_CTX(dev_handle), "unable to match endpoint to an open interface - cannot clear");
3353
- return LIBUSB_ERROR_NOT_FOUND;
3354
- }
3355
-
3356
- usbi_dbg(HANDLE_CTX(dev_handle), "matched endpoint %02X with interface %d", endpoint, current_interface);
3357
- winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
3358
-
3359
- if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
3360
- usbi_err(HANDLE_CTX(dev_handle), "ResetPipe failed: %s", windows_error_str(0));
3361
- return LIBUSB_ERROR_NO_DEVICE;
3362
- }
3363
-
3364
- return LIBUSB_SUCCESS;
3365
- }
3366
-
3367
- static int winusbx_cancel_transfer(int sub_api, struct usbi_transfer *itransfer)
3368
- {
3369
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3370
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
3371
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
3372
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
3373
- int current_interface = transfer_priv->interface_number;
3374
- HANDLE handle;
3375
-
3376
- CHECK_WINUSBX_AVAILABLE(sub_api);
3377
-
3378
- usbi_dbg(TRANSFER_CTX(transfer), "will use interface %d", current_interface);
3379
-
3380
- handle = handle_priv->interface_handle[current_interface].api_handle;
3381
- if (!WinUSBX[sub_api].AbortPipe(handle, transfer->endpoint)) {
3382
- usbi_err(TRANSFER_CTX(transfer), "AbortPipe failed: %s", windows_error_str(0));
3383
- return LIBUSB_ERROR_NO_DEVICE;
3384
- }
3385
-
3386
- return LIBUSB_SUCCESS;
3387
- }
3388
-
3389
- /*
3390
- * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper
3391
- * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx):
3392
- * "WinUSB does not support host-initiated reset port and cycle port operations" and
3393
- * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the
3394
- * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
3395
- * cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
3396
- */
3397
- // TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
3398
- static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
3399
- {
3400
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
3401
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
3402
- HANDLE winusb_handle;
3403
- int i, j;
3404
-
3405
- CHECK_WINUSBX_AVAILABLE(sub_api);
3406
-
3407
- // Reset any available pipe (except control)
3408
- for (i = 0; i < USB_MAXINTERFACES; i++) {
3409
- winusb_handle = handle_priv->interface_handle[i].api_handle;
3410
- if (HANDLE_VALID(winusb_handle)) {
3411
- for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) {
3412
- usbi_dbg(HANDLE_CTX(dev_handle), "resetting ep %02X", priv->usb_interface[i].endpoint[j]);
3413
- if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))
3414
- usbi_err(HANDLE_CTX(dev_handle), "AbortPipe (pipe address %02X) failed: %s",
3415
- priv->usb_interface[i].endpoint[j], windows_error_str(0));
3416
-
3417
- // FlushPipe seems to fail on OUT pipes
3418
- if (IS_EPIN(priv->usb_interface[i].endpoint[j])
3419
- && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])))
3420
- usbi_err(HANDLE_CTX(dev_handle), "FlushPipe (pipe address %02X) failed: %s",
3421
- priv->usb_interface[i].endpoint[j], windows_error_str(0));
3422
-
3423
- if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))
3424
- usbi_err(HANDLE_CTX(dev_handle), "ResetPipe (pipe address %02X) failed: %s",
3425
- priv->usb_interface[i].endpoint[j], windows_error_str(0));
3426
- }
3427
- }
3428
- }
3429
-
3430
- // libusbK & libusb0 have the ability to issue an actual device reset
3431
- if ((sub_api != SUB_API_WINUSB) && (WinUSBX[sub_api].ResetDevice != NULL)) {
3432
- winusb_handle = handle_priv->interface_handle[0].api_handle;
3433
- if (HANDLE_VALID(winusb_handle))
3434
- WinUSBX[sub_api].ResetDevice(winusb_handle);
3435
- }
3436
-
3437
- return LIBUSB_SUCCESS;
3438
- }
3439
-
3440
- static enum libusb_transfer_status winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length)
3441
- {
3442
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
3443
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
3444
- int i;
3445
-
3446
- if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
3447
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
3448
-
3449
- if (sub_api == SUB_API_NOTSET)
3450
- sub_api = priv->sub_api;
3451
- if (WinUSBX[sub_api].hDll == NULL)
3452
- return LIBUSB_TRANSFER_ERROR;
3453
-
3454
- // for isochronous, need to copy the individual iso packet actual_lengths and statuses
3455
- if ((sub_api == SUB_API_LIBUSBK) || (sub_api == SUB_API_LIBUSB0)) {
3456
- // iso only supported on libusbk-based backends for now
3457
- PKISO_CONTEXT iso_context = transfer_priv->iso_context;
3458
- for (i = 0; i < transfer->num_iso_packets; i++) {
3459
- if (IS_XFERIN(transfer)) {
3460
- transfer->iso_packet_desc[i].actual_length = iso_context->IsoPackets[i].actual_length;
3461
- } else {
3462
- // On Windows the usbd Length field is not used for OUT transfers.
3463
- // Copy the requested value back for consistency with other platforms.
3464
- transfer->iso_packet_desc[i].actual_length = transfer->iso_packet_desc[i].length;
3465
- }
3466
- transfer->iso_packet_desc[i].status = usbd_status_to_libusb_transfer_status(iso_context->IsoPackets[i].status);
3467
- }
3468
- } else if (sub_api == SUB_API_WINUSB) {
3469
- if (IS_XFERIN(transfer)) {
3470
- /* Convert isochronous packet descriptor between Windows and libusb representation.
3471
- * Both representation are guaranteed to have the same length in bytes.*/
3472
- PUSBD_ISO_PACKET_DESCRIPTOR usbd_iso_packet_desc = (PUSBD_ISO_PACKET_DESCRIPTOR)transfer->iso_packet_desc;
3473
- for (i = 0; i < transfer->num_iso_packets; i++) {
3474
- unsigned int packet_length = (i < transfer->num_iso_packets - 1) ? (usbd_iso_packet_desc[i + 1].Offset - usbd_iso_packet_desc[i].Offset) : usbd_iso_packet_desc[i].Length;
3475
- unsigned int actual_length = usbd_iso_packet_desc[i].Length;
3476
- USBD_STATUS status = usbd_iso_packet_desc[i].Status;
3477
-
3478
- transfer->iso_packet_desc[i].length = packet_length;
3479
- transfer->iso_packet_desc[i].actual_length = actual_length;
3480
- transfer->iso_packet_desc[i].status = usbd_status_to_libusb_transfer_status(status);
3481
- }
3482
- } else {
3483
- for (i = 0; i < transfer->num_iso_packets; i++) {
3484
- transfer->iso_packet_desc[i].status = LIBUSB_TRANSFER_COMPLETED;
3485
- // On Windows the usbd Length field is not used for OUT transfers.
3486
- // Copy the requested value back for consistency with other platforms.
3487
- transfer->iso_packet_desc[i].actual_length = transfer->iso_packet_desc[i].length;
3488
- }
3489
- }
3490
- } else {
3491
- // This should only occur if backend is not set correctly or other backend isoc is partially implemented
3492
- PRINT_UNSUPPORTED_API(copy_transfer_data);
3493
- return LIBUSB_TRANSFER_ERROR;
3494
- }
3495
- }
3496
-
3497
- itransfer->transferred += (int)length;
3498
- return LIBUSB_TRANSFER_COMPLETED;
3499
- }
3500
-
3501
- /*
3502
- * Internal HID Support functions (from libusb-win32)
3503
- * Note that functions that complete data transfer synchronously must return
3504
- * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
3505
- */
3506
- static int _hid_get_hid_descriptor(struct hid_device_priv *dev, void *data, size_t *size);
3507
- static int _hid_get_report_descriptor(struct hid_device_priv *dev, void *data, size_t *size);
3508
-
3509
- static int _hid_wcslen(WCHAR *str)
3510
- {
3511
- int i = 0;
3512
-
3513
- while (str[i] && (str[i] != 0x409))
3514
- i++;
3515
-
3516
- return i;
3517
- }
3518
-
3519
- static int _hid_get_device_descriptor(struct libusb_device *dev, struct hid_device_priv *hid_priv, void *data, size_t *size)
3520
- {
3521
- struct libusb_device_descriptor d;
3522
-
3523
- /* Copy some values from the cached device descriptor
3524
- * because we cannot get them through HID */
3525
- d.bLength = LIBUSB_DT_DEVICE_SIZE;
3526
- d.bDescriptorType = LIBUSB_DT_DEVICE;
3527
- d.bcdUSB = dev->device_descriptor.bcdUSB;
3528
- d.bDeviceClass = dev->device_descriptor.bDeviceClass;
3529
- d.bDeviceSubClass = dev->device_descriptor.bDeviceSubClass;
3530
- d.bDeviceProtocol = dev->device_descriptor.bDeviceProtocol;
3531
- d.bMaxPacketSize0 = dev->device_descriptor.bMaxPacketSize0;
3532
- d.idVendor = (uint16_t)hid_priv->vid;
3533
- d.idProduct = (uint16_t)hid_priv->pid;
3534
- d.bcdDevice = dev->device_descriptor.bcdDevice;
3535
- d.iManufacturer = hid_priv->string_index[0];
3536
- d.iProduct = hid_priv->string_index[1];
3537
- d.iSerialNumber = hid_priv->string_index[2];
3538
- d.bNumConfigurations = dev->device_descriptor.bNumConfigurations;
3539
-
3540
- if (*size > LIBUSB_DT_DEVICE_SIZE)
3541
- *size = LIBUSB_DT_DEVICE_SIZE;
3542
- memcpy(data, &d, *size);
3543
-
3544
- return LIBUSB_COMPLETED;
3545
- }
3546
-
3547
- static int _hid_get_config_descriptor(struct hid_device_priv *hid_priv, void *data, size_t *size)
3548
- {
3549
- char num_endpoints = 0;
3550
- size_t config_total_len = 0;
3551
- char tmp[HID_MAX_CONFIG_DESC_SIZE];
3552
- struct libusb_config_descriptor *cd;
3553
- struct libusb_interface_descriptor *id;
3554
- struct libusb_hid_descriptor *hd;
3555
- struct libusb_endpoint_descriptor *ed;
3556
- size_t tmp_size;
3557
-
3558
- if (hid_priv->input_report_size)
3559
- num_endpoints++;
3560
- if (hid_priv->output_report_size)
3561
- num_endpoints++;
3562
-
3563
- config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
3564
- + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
3565
-
3566
- cd = (struct libusb_config_descriptor *)tmp;
3567
- id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
3568
- hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3569
- + LIBUSB_DT_INTERFACE_SIZE);
3570
- ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
3571
- + LIBUSB_DT_INTERFACE_SIZE
3572
- + LIBUSB_DT_HID_SIZE);
3573
-
3574
- cd->bLength = LIBUSB_DT_CONFIG_SIZE;
3575
- cd->bDescriptorType = LIBUSB_DT_CONFIG;
3576
- cd->wTotalLength = (uint16_t)config_total_len;
3577
- cd->bNumInterfaces = 1;
3578
- cd->bConfigurationValue = 1;
3579
- cd->iConfiguration = 0;
3580
- cd->bmAttributes = 1 << 7; /* bus powered */
3581
- cd->MaxPower = 50;
3582
-
3583
- id->bLength = LIBUSB_DT_INTERFACE_SIZE;
3584
- id->bDescriptorType = LIBUSB_DT_INTERFACE;
3585
- id->bInterfaceNumber = 0;
3586
- id->bAlternateSetting = 0;
3587
- id->bNumEndpoints = num_endpoints;
3588
- id->bInterfaceClass = 3;
3589
- id->bInterfaceSubClass = 0;
3590
- id->bInterfaceProtocol = 0;
3591
- id->iInterface = 0;
3592
-
3593
- tmp_size = LIBUSB_DT_HID_SIZE;
3594
- _hid_get_hid_descriptor(hid_priv, hd, &tmp_size);
3595
-
3596
- if (hid_priv->input_report_size) {
3597
- ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3598
- ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3599
- ed->bEndpointAddress = HID_IN_EP;
3600
- ed->bmAttributes = 3;
3601
- ed->wMaxPacketSize = hid_priv->input_report_size - 1;
3602
- ed->bInterval = 10;
3603
- ed = (struct libusb_endpoint_descriptor *)((char *)ed + LIBUSB_DT_ENDPOINT_SIZE);
3604
- }
3605
-
3606
- if (hid_priv->output_report_size) {
3607
- ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
3608
- ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
3609
- ed->bEndpointAddress = HID_OUT_EP;
3610
- ed->bmAttributes = 3;
3611
- ed->wMaxPacketSize = hid_priv->output_report_size - 1;
3612
- ed->bInterval = 10;
3613
- }
3614
-
3615
- if (*size > config_total_len)
3616
- *size = config_total_len;
3617
- memcpy(data, tmp, *size);
3618
-
3619
- return LIBUSB_COMPLETED;
3620
- }
3621
-
3622
- static int _hid_get_string_descriptor(struct hid_device_priv *hid_priv, int _index,
3623
- void *data, size_t *size, HANDLE hid_handle)
3624
- {
3625
- void *tmp = NULL;
3626
- WCHAR string[MAX_USB_STRING_LENGTH];
3627
- size_t tmp_size = 0;
3628
- int i;
3629
-
3630
- /* language ID, EN-US */
3631
- char string_langid[] = {0x09, 0x04};
3632
-
3633
- if (_index == 0) {
3634
- tmp = string_langid;
3635
- tmp_size = sizeof(string_langid) + 2;
3636
- } else {
3637
- for (i = 0; i < 3; i++) {
3638
- if (_index == (hid_priv->string_index[i])) {
3639
- tmp = hid_priv->string[i];
3640
- tmp_size = (_hid_wcslen(hid_priv->string[i]) + 1) * sizeof(WCHAR);
3641
- break;
3642
- }
3643
- }
3644
-
3645
- if (i == 3) {
3646
- if (!HidD_GetIndexedString(hid_handle, _index, string, sizeof(string)))
3647
- return LIBUSB_ERROR_INVALID_PARAM;
3648
- tmp = string;
3649
- tmp_size = (_hid_wcslen(string) + 1) * sizeof(WCHAR);
3650
- }
3651
- }
3652
-
3653
- if (!tmp_size)
3654
- return LIBUSB_ERROR_INVALID_PARAM;
3655
-
3656
- if (tmp_size < *size)
3657
- *size = tmp_size;
3658
-
3659
- // 2 byte header
3660
- ((uint8_t *)data)[0] = (uint8_t)*size;
3661
- ((uint8_t *)data)[1] = LIBUSB_DT_STRING;
3662
- memcpy((uint8_t *)data + 2, tmp, *size - 2);
3663
-
3664
- return LIBUSB_COMPLETED;
3665
- }
3666
-
3667
- static int _hid_get_hid_descriptor(struct hid_device_priv *hid_priv, void *data, size_t *size)
3668
- {
3669
- struct libusb_hid_descriptor d;
3670
- uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
3671
- size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
3672
-
3673
- _hid_get_report_descriptor(hid_priv, tmp, &report_len);
3674
-
3675
- d.bLength = LIBUSB_DT_HID_SIZE;
3676
- d.bDescriptorType = LIBUSB_DT_HID;
3677
- d.bcdHID = 0x0110; /* 1.10 */
3678
- d.bCountryCode = 0;
3679
- d.bNumDescriptors = 1;
3680
- d.bClassDescriptorType = LIBUSB_DT_REPORT;
3681
- d.wClassDescriptorLength = (uint16_t)report_len;
3682
-
3683
- if (*size > LIBUSB_DT_HID_SIZE)
3684
- *size = LIBUSB_DT_HID_SIZE;
3685
- memcpy(data, &d, *size);
3686
-
3687
- return LIBUSB_COMPLETED;
3688
- }
3689
-
3690
- static int _hid_get_report_descriptor(struct hid_device_priv *hid_priv, void *data, size_t *size)
3691
- {
3692
- uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
3693
- size_t i = 0;
3694
-
3695
- /* usage page */
3696
- d[i++] = 0x06; d[i++] = hid_priv->usagePage & 0xFF; d[i++] = hid_priv->usagePage >> 8;
3697
- /* usage */
3698
- d[i++] = 0x09; d[i++] = (uint8_t)hid_priv->usage;
3699
- /* start collection (application) */
3700
- d[i++] = 0xA1; d[i++] = 0x01;
3701
- /* input report */
3702
- if (hid_priv->input_report_size) {
3703
- /* usage (vendor defined) */
3704
- d[i++] = 0x09; d[i++] = 0x01;
3705
- /* logical minimum (0) */
3706
- d[i++] = 0x15; d[i++] = 0x00;
3707
- /* logical maximum (255) */
3708
- d[i++] = 0x25; d[i++] = 0xFF;
3709
- /* report size (8 bits) */
3710
- d[i++] = 0x75; d[i++] = 0x08;
3711
- /* report count */
3712
- d[i++] = 0x95; d[i++] = (uint8_t)hid_priv->input_report_size - 1;
3713
- /* input (data, variable, absolute) */
3714
- d[i++] = 0x81; d[i++] = 0x00;
3715
- }
3716
- /* output report */
3717
- if (hid_priv->output_report_size) {
3718
- /* usage (vendor defined) */
3719
- d[i++] = 0x09; d[i++] = 0x02;
3720
- /* logical minimum (0) */
3721
- d[i++] = 0x15; d[i++] = 0x00;
3722
- /* logical maximum (255) */
3723
- d[i++] = 0x25; d[i++] = 0xFF;
3724
- /* report size (8 bits) */
3725
- d[i++] = 0x75; d[i++] = 0x08;
3726
- /* report count */
3727
- d[i++] = 0x95; d[i++] = (uint8_t)hid_priv->output_report_size - 1;
3728
- /* output (data, variable, absolute) */
3729
- d[i++] = 0x91; d[i++] = 0x00;
3730
- }
3731
- /* feature report */
3732
- if (hid_priv->feature_report_size) {
3733
- /* usage (vendor defined) */
3734
- d[i++] = 0x09; d[i++] = 0x03;
3735
- /* logical minimum (0) */
3736
- d[i++] = 0x15; d[i++] = 0x00;
3737
- /* logical maximum (255) */
3738
- d[i++] = 0x25; d[i++] = 0xFF;
3739
- /* report size (8 bits) */
3740
- d[i++] = 0x75; d[i++] = 0x08;
3741
- /* report count */
3742
- d[i++] = 0x95; d[i++] = (uint8_t)hid_priv->feature_report_size - 1;
3743
- /* feature (data, variable, absolute) */
3744
- d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
3745
- }
3746
-
3747
- /* end collection */
3748
- d[i++] = 0xC0;
3749
-
3750
- if (*size > i)
3751
- *size = i;
3752
- memcpy(data, d, *size);
3753
-
3754
- return LIBUSB_COMPLETED;
3755
- }
3756
-
3757
- static int _hid_get_descriptor(struct libusb_device *dev, HANDLE hid_handle, int recipient,
3758
- int type, int _index, void *data, size_t *size)
3759
- {
3760
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
3761
- UNUSED(recipient);
3762
-
3763
- switch (type) {
3764
- case LIBUSB_DT_DEVICE:
3765
- usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_DEVICE");
3766
- return _hid_get_device_descriptor(dev, priv->hid, data, size);
3767
- case LIBUSB_DT_CONFIG:
3768
- usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_CONFIG");
3769
- if (!_index)
3770
- return _hid_get_config_descriptor(priv->hid, data, size);
3771
- return LIBUSB_ERROR_INVALID_PARAM;
3772
- case LIBUSB_DT_STRING:
3773
- usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_STRING");
3774
- return _hid_get_string_descriptor(priv->hid, _index, data, size, hid_handle);
3775
- case LIBUSB_DT_HID:
3776
- usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_HID");
3777
- if (!_index)
3778
- return _hid_get_hid_descriptor(priv->hid, data, size);
3779
- return LIBUSB_ERROR_INVALID_PARAM;
3780
- case LIBUSB_DT_REPORT:
3781
- usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_REPORT");
3782
- if (!_index)
3783
- return _hid_get_report_descriptor(priv->hid, data, size);
3784
- return LIBUSB_ERROR_INVALID_PARAM;
3785
- case LIBUSB_DT_PHYSICAL:
3786
- usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_PHYSICAL");
3787
- if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
3788
- return LIBUSB_COMPLETED;
3789
- return LIBUSB_ERROR_OTHER;
3790
- }
3791
-
3792
- usbi_warn(DEVICE_CTX(dev), "unsupported");
3793
- return LIBUSB_ERROR_NOT_SUPPORTED;
3794
- }
3795
-
3796
- static int _hid_get_report(struct libusb_device *dev, HANDLE hid_handle, int id, void *data,
3797
- struct winusb_transfer_priv *tp, size_t size, OVERLAPPED *overlapped, int report_type)
3798
- {
3799
- DWORD ioctl_code, expected_size = (DWORD)size;
3800
- uint8_t *buf;
3801
-
3802
- if (tp->hid_buffer != NULL)
3803
- usbi_err(DEVICE_CTX(dev), "program assertion failed - hid_buffer is not NULL");
3804
-
3805
- if ((size == 0) || (size > MAX_HID_REPORT_SIZE)) {
3806
- usbi_warn(DEVICE_CTX(dev), "invalid size (%"PRIuPTR")", (uintptr_t)size);
3807
- return LIBUSB_ERROR_INVALID_PARAM;
3808
- }
3809
-
3810
- switch (report_type) {
3811
- case HID_REPORT_TYPE_INPUT:
3812
- ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
3813
- break;
3814
- case HID_REPORT_TYPE_FEATURE:
3815
- ioctl_code = IOCTL_HID_GET_FEATURE;
3816
- break;
3817
- default:
3818
- usbi_warn(DEVICE_CTX(dev), "unknown HID report type %d", report_type);
3819
- return LIBUSB_ERROR_INVALID_PARAM;
3820
- }
3821
-
3822
- // Add a trailing byte to detect overflows
3823
- buf = calloc(1, expected_size + 1);
3824
- if (buf == NULL)
3825
- return LIBUSB_ERROR_NO_MEM;
3826
-
3827
- buf[0] = (uint8_t)id; // Must be set always
3828
- usbi_dbg(DEVICE_CTX(dev), "report ID: 0x%02X", buf[0]);
3829
-
3830
- // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3831
- if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size + 1,
3832
- buf, expected_size + 1, NULL, overlapped)) {
3833
- if (GetLastError() != ERROR_IO_PENDING) {
3834
- usbi_err(DEVICE_CTX(dev), "failed to read HID Report: %s", windows_error_str(0));
3835
- free(buf);
3836
- return LIBUSB_ERROR_IO;
3837
- }
3838
- }
3839
-
3840
- // Asynchronous wait
3841
- tp->hid_buffer = buf;
3842
- tp->hid_dest = data; // copy dest, as not necessarily the start of the transfer buffer
3843
- tp->hid_expected_size = expected_size;
3844
-
3845
- return LIBUSB_SUCCESS;
3846
- }
3847
-
3848
- static int _hid_set_report(struct libusb_device *dev, HANDLE hid_handle, int id, void *data,
3849
- struct winusb_transfer_priv *tp, size_t size, OVERLAPPED *overlapped, int report_type)
3850
- {
3851
- DWORD ioctl_code, write_size = (DWORD)size;
3852
- // If an id is reported, we must allow MAX_HID_REPORT_SIZE + 1
3853
- size_t max_report_size = MAX_HID_REPORT_SIZE + (id ? 1 : 0);
3854
- uint8_t *buf;
3855
-
3856
- if (tp->hid_buffer != NULL)
3857
- usbi_err(DEVICE_CTX(dev), "program assertion failed - hid_buffer is not NULL");
3858
-
3859
- if ((size == 0) || (size > max_report_size)) {
3860
- usbi_warn(DEVICE_CTX(dev), "invalid size (%"PRIuPTR")", (uintptr_t)size);
3861
- return LIBUSB_ERROR_INVALID_PARAM;
3862
- }
3863
-
3864
- switch (report_type) {
3865
- case HID_REPORT_TYPE_OUTPUT:
3866
- ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
3867
- break;
3868
- case HID_REPORT_TYPE_FEATURE:
3869
- ioctl_code = IOCTL_HID_SET_FEATURE;
3870
- break;
3871
- default:
3872
- usbi_warn(DEVICE_CTX(dev), "unknown HID report type %d", report_type);
3873
- return LIBUSB_ERROR_INVALID_PARAM;
3874
- }
3875
-
3876
- usbi_dbg(DEVICE_CTX(dev), "report ID: 0x%02X", id);
3877
- // When report IDs are not used (i.e. when id == 0), we must add
3878
- // a null report ID. Otherwise, we just use original data buffer
3879
- if (id == 0)
3880
- write_size++;
3881
-
3882
- buf = malloc(write_size);
3883
- if (buf == NULL)
3884
- return LIBUSB_ERROR_NO_MEM;
3885
-
3886
- if (id == 0) {
3887
- buf[0] = 0;
3888
- memcpy(buf + 1, data, size);
3889
- } else {
3890
- // This seems like a waste, but if we don't duplicate the
3891
- // data, we'll get issues when freeing hid_buffer
3892
- memcpy(buf, data, size);
3893
- if (buf[0] != id)
3894
- usbi_warn(DEVICE_CTX(dev), "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
3895
- }
3896
-
3897
- // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
3898
- if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
3899
- buf, write_size, NULL, overlapped)) {
3900
- if (GetLastError() != ERROR_IO_PENDING) {
3901
- usbi_err(DEVICE_CTX(dev), "failed to write HID Output Report: %s", windows_error_str(0));
3902
- free(buf);
3903
- return LIBUSB_ERROR_IO;
3904
- }
3905
- }
3906
-
3907
- tp->hid_buffer = buf;
3908
- tp->hid_dest = NULL;
3909
- return LIBUSB_SUCCESS;
3910
- }
3911
-
3912
- static int _hid_class_request(struct libusb_device *dev, HANDLE hid_handle, int request_type,
3913
- int request, int value, int _index, void *data, struct winusb_transfer_priv *tp,
3914
- size_t size, OVERLAPPED *overlapped)
3915
- {
3916
- int report_type = (value >> 8) & 0xFF;
3917
- int report_id = value & 0xFF;
3918
-
3919
- UNUSED(_index);
3920
-
3921
- if ((LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
3922
- && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE))
3923
- return LIBUSB_ERROR_INVALID_PARAM;
3924
-
3925
- if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
3926
- return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3927
-
3928
- if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
3929
- return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
3930
-
3931
- return LIBUSB_ERROR_INVALID_PARAM;
3932
- }
3933
-
3934
- /*
3935
- * HID API functions
3936
- */
3937
- static bool hid_init(struct libusb_context *ctx)
3938
- {
3939
- DLL_GET_HANDLE(ctx, hid);
3940
-
3941
- DLL_LOAD_FUNC(hid, HidD_GetAttributes, true);
3942
- DLL_LOAD_FUNC(hid, HidD_GetHidGuid, true);
3943
- DLL_LOAD_FUNC(hid, HidD_GetPreparsedData, true);
3944
- DLL_LOAD_FUNC(hid, HidD_FreePreparsedData, true);
3945
- DLL_LOAD_FUNC(hid, HidD_GetManufacturerString, true);
3946
- DLL_LOAD_FUNC(hid, HidD_GetProductString, true);
3947
- DLL_LOAD_FUNC(hid, HidD_GetSerialNumberString, true);
3948
- DLL_LOAD_FUNC(hid, HidD_GetIndexedString, true);
3949
- DLL_LOAD_FUNC(hid, HidP_GetCaps, true);
3950
- DLL_LOAD_FUNC(hid, HidD_SetNumInputBuffers, true);
3951
- DLL_LOAD_FUNC(hid, HidD_GetPhysicalDescriptor, true);
3952
- DLL_LOAD_FUNC(hid, HidD_FlushQueue, true);
3953
- DLL_LOAD_FUNC(hid, HidP_GetValueCaps, true);
3954
-
3955
- return true;
3956
- }
3957
-
3958
- static void hid_exit(void)
3959
- {
3960
- DLL_FREE_HANDLE(hid);
3961
- }
3962
-
3963
- // NB: open and close must ensure that they only handle interface of
3964
- // the right API type, as these functions can be called wholesale from
3965
- // composite_open(), with interfaces belonging to different APIs
3966
- static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
3967
- {
3968
- struct libusb_device *dev = dev_handle->dev;
3969
- struct winusb_device_priv *priv = usbi_get_device_priv(dev);
3970
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
3971
- HIDD_ATTRIBUTES hid_attributes;
3972
- PHIDP_PREPARSED_DATA preparsed_data = NULL;
3973
- HIDP_CAPS capabilities;
3974
- HIDP_VALUE_CAPS *value_caps;
3975
- HANDLE hid_handle = INVALID_HANDLE_VALUE;
3976
- int i, j;
3977
- // report IDs handling
3978
- ULONG size[3];
3979
- int nb_ids[2]; // zero and nonzero report IDs
3980
- #if defined(ENABLE_LOGGING)
3981
- const char * const type[3] = {"input", "output", "feature"};
3982
- #endif
3983
-
3984
- UNUSED(sub_api);
3985
- CHECK_HID_AVAILABLE;
3986
-
3987
- if (priv->hid == NULL) {
3988
- usbi_err(HANDLE_CTX(dev_handle), "program assertion failed - private HID structure is uninitialized");
3989
- return LIBUSB_ERROR_NOT_FOUND;
3990
- }
3991
-
3992
- for (i = 0; i < USB_MAXINTERFACES; i++) {
3993
- if ((priv->usb_interface[i].path != NULL)
3994
- && (priv->usb_interface[i].apib->id == USB_API_HID)) {
3995
- hid_handle = windows_open(dev_handle, priv->usb_interface[i].path, GENERIC_READ | GENERIC_WRITE);
3996
- /*
3997
- * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
3998
- * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
3999
- * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
4000
- * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
4001
- * HidD_GetFeature (if the device supports Feature reports)."
4002
- */
4003
- if (hid_handle == INVALID_HANDLE_VALUE) {
4004
- usbi_warn(HANDLE_CTX(dev_handle), "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
4005
- hid_handle = windows_open(dev_handle, priv->usb_interface[i].path, 0);
4006
- if (hid_handle == INVALID_HANDLE_VALUE) {
4007
- usbi_err(HANDLE_CTX(dev_handle), "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
4008
- switch (GetLastError()) {
4009
- case ERROR_FILE_NOT_FOUND: // The device was disconnected
4010
- return LIBUSB_ERROR_NO_DEVICE;
4011
- case ERROR_ACCESS_DENIED:
4012
- return LIBUSB_ERROR_ACCESS;
4013
- default:
4014
- return LIBUSB_ERROR_IO;
4015
- }
4016
- }
4017
- priv->usb_interface[i].restricted_functionality = true;
4018
- }
4019
- handle_priv->interface_handle[i].api_handle = hid_handle;
4020
- }
4021
- }
4022
-
4023
- hid_attributes.Size = sizeof(hid_attributes);
4024
- do {
4025
- if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
4026
- usbi_err(HANDLE_CTX(dev_handle), "could not gain access to HID top collection (HidD_GetAttributes)");
4027
- break;
4028
- }
4029
-
4030
- priv->hid->vid = hid_attributes.VendorID;
4031
- priv->hid->pid = hid_attributes.ProductID;
4032
-
4033
- // Set the maximum available input buffer size
4034
- for (i = 32; HidD_SetNumInputBuffers(hid_handle, i); i *= 2);
4035
- usbi_dbg(HANDLE_CTX(dev_handle), "set maximum input buffer size to %d", i / 2);
4036
-
4037
- // Get the maximum input and output report size
4038
- if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
4039
- usbi_err(HANDLE_CTX(dev_handle), "could not read HID preparsed data (HidD_GetPreparsedData)");
4040
- break;
4041
- }
4042
- if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
4043
- usbi_err(HANDLE_CTX(dev_handle), "could not parse HID capabilities (HidP_GetCaps)");
4044
- break;
4045
- }
4046
-
4047
- // Find out if interrupt will need report IDs
4048
- size[0] = capabilities.NumberInputValueCaps;
4049
- size[1] = capabilities.NumberOutputValueCaps;
4050
- size[2] = capabilities.NumberFeatureValueCaps;
4051
- for (j = HidP_Input; j <= HidP_Feature; j++) {
4052
- usbi_dbg(HANDLE_CTX(dev_handle), "%lu HID %s report value(s) found", ULONG_CAST(size[j]), type[j]);
4053
- priv->hid->uses_report_ids[j] = false;
4054
- if (size[j] > 0) {
4055
- value_caps = calloc(size[j], sizeof(HIDP_VALUE_CAPS));
4056
- if ((value_caps != NULL)
4057
- && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
4058
- && (size[j] >= 1)) {
4059
- nb_ids[0] = 0;
4060
- nb_ids[1] = 0;
4061
- for (i = 0; i < (int)size[j]; i++) {
4062
- usbi_dbg(HANDLE_CTX(dev_handle), " Report ID: 0x%02X", value_caps[i].ReportID);
4063
- if (value_caps[i].ReportID != 0)
4064
- nb_ids[1]++;
4065
- else
4066
- nb_ids[0]++;
4067
- }
4068
- if (nb_ids[1] != 0) {
4069
- if (nb_ids[0] != 0)
4070
- usbi_warn(HANDLE_CTX(dev_handle), "program assertion failed - zero and nonzero report IDs used for %s",
4071
- type[j]);
4072
- priv->hid->uses_report_ids[j] = true;
4073
- }
4074
- } else {
4075
- usbi_warn(HANDLE_CTX(dev_handle), " could not process %s report IDs", type[j]);
4076
- }
4077
- free(value_caps);
4078
- }
4079
- }
4080
-
4081
- // Set the report sizes
4082
- priv->hid->input_report_size = capabilities.InputReportByteLength;
4083
- priv->hid->output_report_size = capabilities.OutputReportByteLength;
4084
- priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
4085
-
4086
- // Store usage and usagePage values
4087
- priv->hid->usage = capabilities.Usage;
4088
- priv->hid->usagePage = capabilities.UsagePage;
4089
-
4090
- // Fetch string descriptors
4091
- priv->hid->string_index[0] = dev->device_descriptor.iManufacturer;
4092
- if (priv->hid->string_index[0] != 0)
4093
- HidD_GetManufacturerString(hid_handle, priv->hid->string[0], sizeof(priv->hid->string[0]));
4094
- else
4095
- priv->hid->string[0][0] = 0;
4096
-
4097
- priv->hid->string_index[1] = dev->device_descriptor.iProduct;
4098
- if (priv->hid->string_index[1] != 0)
4099
- // Using HidD_GetIndexedString() instead of HidD_GetProductString(), as the latter would otherwise return the name
4100
- // of the interface instead of the iProduct string whenever the iInterface member of the USB_INTERFACE_DESCRIPTOR
4101
- // structure for the interface is nonzero (see Remarks section in the documentation of the HID API routines)
4102
- HidD_GetIndexedString(hid_handle, priv->hid->string_index[1], priv->hid->string[1], sizeof(priv->hid->string[1]));
4103
- else
4104
- priv->hid->string[1][0] = 0;
4105
-
4106
- priv->hid->string_index[2] = dev->device_descriptor.iSerialNumber;
4107
- if (priv->hid->string_index[2] != 0)
4108
- HidD_GetSerialNumberString(hid_handle, priv->hid->string[2], sizeof(priv->hid->string[2]));
4109
- else
4110
- priv->hid->string[2][0] = 0;
4111
- } while (0);
4112
-
4113
- if (preparsed_data)
4114
- HidD_FreePreparsedData(preparsed_data);
4115
-
4116
- return LIBUSB_SUCCESS;
4117
- }
4118
-
4119
- static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
4120
- {
4121
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4122
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
4123
- HANDLE file_handle;
4124
- int i;
4125
-
4126
- UNUSED(sub_api);
4127
-
4128
- if (DLL_HANDLE_NAME(hid) == NULL)
4129
- return;
4130
-
4131
- for (i = 0; i < USB_MAXINTERFACES; i++) {
4132
- if (priv->usb_interface[i].apib->id == USB_API_HID) {
4133
- file_handle = handle_priv->interface_handle[i].api_handle;
4134
- if (HANDLE_VALID(file_handle))
4135
- CloseHandle(file_handle);
4136
- }
4137
- }
4138
- }
4139
-
4140
- static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
4141
- {
4142
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
4143
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4144
-
4145
- UNUSED(sub_api);
4146
- CHECK_HID_AVAILABLE;
4147
-
4148
- // NB: Disconnection detection is not possible in this function
4149
- if (priv->usb_interface[iface].path == NULL)
4150
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
4151
-
4152
- // We use dev_handle as a flag for interface claimed
4153
- if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED)
4154
- return LIBUSB_ERROR_BUSY; // already claimed
4155
-
4156
- handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
4157
-
4158
- usbi_dbg(HANDLE_CTX(dev_handle), "claimed interface %u", iface);
4159
- handle_priv->active_interface = iface;
4160
-
4161
- return LIBUSB_SUCCESS;
4162
- }
4163
-
4164
- static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
4165
- {
4166
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
4167
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4168
-
4169
- UNUSED(sub_api);
4170
- CHECK_HID_AVAILABLE;
4171
-
4172
- if (priv->usb_interface[iface].path == NULL)
4173
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
4174
-
4175
- if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED)
4176
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
4177
-
4178
- handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
4179
-
4180
- return LIBUSB_SUCCESS;
4181
- }
4182
-
4183
- static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
4184
- {
4185
- UNUSED(sub_api);
4186
- UNUSED(iface);
4187
-
4188
- CHECK_HID_AVAILABLE;
4189
-
4190
- if (altsetting != 0) {
4191
- usbi_err(HANDLE_CTX(dev_handle), "set interface altsetting not supported for altsetting >0");
4192
- return LIBUSB_ERROR_NOT_SUPPORTED;
4193
- }
4194
-
4195
- return LIBUSB_SUCCESS;
4196
- }
4197
-
4198
- static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4199
- {
4200
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4201
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
4202
- struct libusb_device_handle *dev_handle = transfer->dev_handle;
4203
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
4204
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
4205
- WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer;
4206
- HANDLE hid_handle;
4207
- OVERLAPPED *overlapped;
4208
- int current_interface;
4209
- uint8_t config;
4210
- size_t size;
4211
- int r;
4212
-
4213
- UNUSED(sub_api);
4214
- CHECK_HID_AVAILABLE;
4215
-
4216
- safe_free(transfer_priv->hid_buffer);
4217
- transfer_priv->hid_dest = NULL;
4218
- size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
4219
-
4220
- if (size > MAX_CTRL_BUFFER_LENGTH)
4221
- return LIBUSB_ERROR_INVALID_PARAM;
4222
-
4223
- current_interface = get_valid_interface(dev_handle, USB_API_HID);
4224
- if (current_interface < 0) {
4225
- if (auto_claim(transfer, &current_interface, USB_API_HID) != LIBUSB_SUCCESS)
4226
- return LIBUSB_ERROR_NOT_FOUND;
4227
- }
4228
-
4229
- usbi_dbg(ITRANSFER_CTX(itransfer), "will use interface %d", current_interface);
4230
-
4231
- transfer_priv->interface_number = (uint8_t)current_interface;
4232
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4233
- set_transfer_priv_handle(itransfer, hid_handle);
4234
- overlapped = get_transfer_priv_overlapped(itransfer);
4235
-
4236
- switch (LIBUSB_REQ_TYPE(setup->RequestType)) {
4237
- case LIBUSB_REQUEST_TYPE_STANDARD:
4238
- switch (setup->Request) {
4239
- case LIBUSB_REQUEST_GET_DESCRIPTOR:
4240
- r = _hid_get_descriptor(dev_handle->dev, hid_handle, LIBUSB_REQ_RECIPIENT(setup->RequestType),
4241
- (setup->Value >> 8) & 0xFF, setup->Value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
4242
- break;
4243
- case LIBUSB_REQUEST_GET_CONFIGURATION:
4244
- r = winusb_get_configuration(dev_handle, &config);
4245
- if (r == LIBUSB_SUCCESS) {
4246
- size = 1;
4247
- ((uint8_t *)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = config;
4248
- r = LIBUSB_COMPLETED;
4249
- }
4250
- break;
4251
- case LIBUSB_REQUEST_SET_CONFIGURATION:
4252
- if (setup->Value == priv->active_config) {
4253
- r = LIBUSB_COMPLETED;
4254
- } else {
4255
- usbi_warn(TRANSFER_CTX(transfer), "cannot set configuration other than the default one");
4256
- r = LIBUSB_ERROR_NOT_SUPPORTED;
4257
- }
4258
- break;
4259
- case LIBUSB_REQUEST_GET_INTERFACE:
4260
- size = 1;
4261
- ((uint8_t *)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
4262
- r = LIBUSB_COMPLETED;
4263
- break;
4264
- case LIBUSB_REQUEST_SET_INTERFACE:
4265
- r = hid_set_interface_altsetting(0, dev_handle, (uint8_t)setup->Index, (uint8_t)setup->Value);
4266
- if (r == LIBUSB_SUCCESS)
4267
- r = LIBUSB_COMPLETED;
4268
- break;
4269
- default:
4270
- usbi_warn(TRANSFER_CTX(transfer), "unsupported HID control request");
4271
- return LIBUSB_ERROR_NOT_SUPPORTED;
4272
- }
4273
- break;
4274
- case LIBUSB_REQUEST_TYPE_CLASS:
4275
- r = _hid_class_request(dev_handle->dev, hid_handle, setup->RequestType, setup->Request, setup->Value,
4276
- setup->Index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
4277
- size, overlapped);
4278
- break;
4279
- default:
4280
- usbi_warn(TRANSFER_CTX(transfer), "unsupported HID control request");
4281
- return LIBUSB_ERROR_NOT_SUPPORTED;
4282
- }
4283
-
4284
- if (r < 0)
4285
- return r;
4286
-
4287
- if (r == LIBUSB_COMPLETED) {
4288
- // Force request to be completed synchronously. Transferred size has been set by previous call
4289
- windows_force_sync_completion(itransfer, (ULONG)size);
4290
- r = LIBUSB_SUCCESS;
4291
- }
4292
-
4293
- return LIBUSB_SUCCESS;
4294
- }
4295
-
4296
- static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
4297
- {
4298
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4299
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
4300
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
4301
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
4302
- HANDLE hid_handle;
4303
- OVERLAPPED *overlapped;
4304
- bool direction_in;
4305
- BOOL ret;
4306
- int current_interface, length;
4307
-
4308
- UNUSED(sub_api);
4309
- CHECK_HID_AVAILABLE;
4310
-
4311
- if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET))
4312
- return LIBUSB_ERROR_NOT_SUPPORTED;
4313
-
4314
- transfer_priv->hid_dest = NULL;
4315
- safe_free(transfer_priv->hid_buffer);
4316
-
4317
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4318
- if (current_interface < 0) {
4319
- usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
4320
- return LIBUSB_ERROR_NOT_FOUND;
4321
- }
4322
-
4323
- usbi_dbg(TRANSFER_CTX(transfer), "matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
4324
-
4325
- transfer_priv->interface_number = (uint8_t)current_interface;
4326
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4327
- set_transfer_priv_handle(itransfer, hid_handle);
4328
- overlapped = get_transfer_priv_overlapped(itransfer);
4329
- direction_in = IS_XFERIN(transfer);
4330
-
4331
- // If report IDs are not in use, an extra prefix byte must be added
4332
- if (((direction_in) && (!priv->hid->uses_report_ids[0]))
4333
- || ((!direction_in) && (!priv->hid->uses_report_ids[1])))
4334
- length = transfer->length + 1;
4335
- else
4336
- length = transfer->length;
4337
-
4338
- // Add a trailing byte to detect overflows on input
4339
- transfer_priv->hid_buffer = calloc(1, length + 1);
4340
- if (transfer_priv->hid_buffer == NULL)
4341
- return LIBUSB_ERROR_NO_MEM;
4342
-
4343
- transfer_priv->hid_expected_size = length;
4344
-
4345
- if (direction_in) {
4346
- transfer_priv->hid_dest = transfer->buffer;
4347
- usbi_dbg(TRANSFER_CTX(transfer), "reading %d bytes (report ID: 0x00)", length);
4348
- ret = ReadFile(hid_handle, transfer_priv->hid_buffer, length + 1, NULL, overlapped);
4349
- } else {
4350
- if (!priv->hid->uses_report_ids[1])
4351
- memcpy(transfer_priv->hid_buffer + 1, transfer->buffer, transfer->length);
4352
- else
4353
- // We could actually do without the calloc and memcpy in this case
4354
- memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
4355
-
4356
- usbi_dbg(TRANSFER_CTX(transfer), "writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
4357
- ret = WriteFile(hid_handle, transfer_priv->hid_buffer, length, NULL, overlapped);
4358
- }
4359
-
4360
- if (!ret && GetLastError() != ERROR_IO_PENDING) {
4361
- usbi_err(TRANSFER_CTX(transfer), "HID transfer failed: %s", windows_error_str(0));
4362
- safe_free(transfer_priv->hid_buffer);
4363
- return LIBUSB_ERROR_IO;
4364
- }
4365
-
4366
- return LIBUSB_SUCCESS;
4367
- }
4368
-
4369
- static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4370
- {
4371
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
4372
- HANDLE hid_handle;
4373
- int current_interface;
4374
-
4375
- UNUSED(sub_api);
4376
- CHECK_HID_AVAILABLE;
4377
-
4378
- // Flushing the queues on all interfaces is the best we can achieve
4379
- for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
4380
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4381
- if (HANDLE_VALID(hid_handle))
4382
- HidD_FlushQueue(hid_handle);
4383
- }
4384
-
4385
- return LIBUSB_SUCCESS;
4386
- }
4387
-
4388
- static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4389
- {
4390
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
4391
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4392
- HANDLE hid_handle;
4393
- int current_interface;
4394
-
4395
- UNUSED(sub_api);
4396
- CHECK_HID_AVAILABLE;
4397
-
4398
- current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4399
- if (current_interface < 0) {
4400
- usbi_err(HANDLE_CTX(dev_handle), "unable to match endpoint to an open interface - cannot clear");
4401
- return LIBUSB_ERROR_NOT_FOUND;
4402
- }
4403
-
4404
- usbi_dbg(HANDLE_CTX(dev_handle), "matched endpoint %02X with interface %d", endpoint, current_interface);
4405
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
4406
-
4407
- // No endpoint selection with Microsoft's implementation, so we try to flush the
4408
- // whole interface. Should be OK for most case scenarios
4409
- if (!HidD_FlushQueue(hid_handle)) {
4410
- usbi_err(HANDLE_CTX(dev_handle), "Flushing of HID queue failed: %s", windows_error_str(0));
4411
- // Device was probably disconnected
4412
- return LIBUSB_ERROR_NO_DEVICE;
4413
- }
4414
-
4415
- return LIBUSB_SUCCESS;
4416
- }
4417
-
4418
- // This extra function is only needed for HID
4419
- static enum libusb_transfer_status hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length)
4420
- {
4421
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4422
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
4423
- enum libusb_transfer_status r = LIBUSB_TRANSFER_COMPLETED;
4424
-
4425
- UNUSED(sub_api);
4426
-
4427
- if (transfer_priv->hid_buffer != NULL) {
4428
- // If we have a valid hid_buffer, it means the transfer was async
4429
- if (transfer_priv->hid_dest != NULL) { // Data readout
4430
- if (length > 0) {
4431
- // First, check for overflow
4432
- if ((size_t)length > transfer_priv->hid_expected_size) {
4433
- usbi_err(TRANSFER_CTX(transfer), "OVERFLOW!");
4434
- length = (DWORD)transfer_priv->hid_expected_size;
4435
- r = LIBUSB_TRANSFER_OVERFLOW;
4436
- }
4437
-
4438
- if (transfer_priv->hid_buffer[0] == 0) {
4439
- memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer + 1, length);
4440
- } else {
4441
- memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, length);
4442
- }
4443
- }
4444
- transfer_priv->hid_dest = NULL;
4445
- }
4446
- // For write, we just need to free the hid buffer
4447
- safe_free(transfer_priv->hid_buffer);
4448
- }
4449
-
4450
- itransfer->transferred += (int)length;
4451
- return r;
4452
- }
4453
-
4454
-
4455
- /*
4456
- * Composite API functions
4457
- */
4458
- static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
4459
- {
4460
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4461
- int i, r = LIBUSB_ERROR_NOT_FOUND;
4462
- // SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID
4463
- bool available[SUB_API_MAX + 1];
4464
-
4465
- UNUSED(sub_api);
4466
-
4467
- for (i = 0; i < SUB_API_MAX + 1; i++)
4468
- available[i] = false;
4469
-
4470
- for (i = 0; i < USB_MAXINTERFACES; i++) {
4471
- switch (priv->usb_interface[i].apib->id) {
4472
- case USB_API_WINUSBX:
4473
- if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4474
- available[priv->usb_interface[i].sub_api] = true;
4475
- break;
4476
- case USB_API_HID:
4477
- available[SUB_API_MAX] = true;
4478
- break;
4479
- default:
4480
- break;
4481
- }
4482
- }
4483
-
4484
- for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers
4485
- if (available[i]) {
4486
- r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
4487
- if (r != LIBUSB_SUCCESS)
4488
- return r;
4489
- }
4490
- }
4491
-
4492
- if (available[SUB_API_MAX]) { // HID driver
4493
- r = hid_open(SUB_API_NOTSET, dev_handle);
4494
-
4495
- // On Windows 10 version 1903 (OS Build 18362) and later Windows blocks attempts to
4496
- // open HID devices with a U2F usage unless running as administrator. We ignore this
4497
- // failure and proceed without the HID device opened.
4498
- if (r == LIBUSB_ERROR_ACCESS) {
4499
- usbi_dbg(HANDLE_CTX(dev_handle), "ignoring access denied error while opening HID interface of composite device");
4500
- r = LIBUSB_SUCCESS;
4501
- }
4502
- }
4503
-
4504
- return r;
4505
- }
4506
-
4507
- static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
4508
- {
4509
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4510
- int i;
4511
- // SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID
4512
- bool available[SUB_API_MAX + 1];
4513
-
4514
- UNUSED(sub_api);
4515
-
4516
- for (i = 0; i < SUB_API_MAX + 1; i++)
4517
- available[i] = false;
4518
-
4519
- for (i = 0; i < USB_MAXINTERFACES; i++) {
4520
- switch (priv->usb_interface[i].apib->id) {
4521
- case USB_API_WINUSBX:
4522
- if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
4523
- available[priv->usb_interface[i].sub_api] = true;
4524
- break;
4525
- case USB_API_HID:
4526
- available[SUB_API_MAX] = true;
4527
- break;
4528
- default:
4529
- break;
4530
- }
4531
- }
4532
-
4533
- for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers
4534
- if (available[i])
4535
- usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
4536
- }
4537
-
4538
- if (available[SUB_API_MAX]) // HID driver
4539
- hid_close(SUB_API_NOTSET, dev_handle);
4540
- }
4541
-
4542
- static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
4543
- {
4544
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4545
-
4546
- UNUSED(sub_api);
4547
- CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, claim_interface);
4548
-
4549
- return priv->usb_interface[iface].apib->
4550
- claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4551
- }
4552
-
4553
- static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
4554
- {
4555
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4556
-
4557
- UNUSED(sub_api);
4558
- CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, set_interface_altsetting);
4559
-
4560
- return priv->usb_interface[iface].apib->
4561
- set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting);
4562
- }
4563
-
4564
- static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
4565
- {
4566
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4567
-
4568
- UNUSED(sub_api);
4569
- CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, release_interface);
4570
-
4571
- return priv->usb_interface[iface].apib->
4572
- release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface);
4573
- }
4574
-
4575
- static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer)
4576
- {
4577
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4578
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
4579
- struct libusb_config_descriptor *conf_desc;
4580
- WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer;
4581
- int iface, pass, r;
4582
-
4583
- UNUSED(sub_api);
4584
-
4585
- // Interface shouldn't matter for control, but it does in practice, with Windows'
4586
- // restrictions with regards to accessing HID keyboards and mice. Try to target
4587
- // a specific interface first, if possible.
4588
- switch (LIBUSB_REQ_RECIPIENT(setup->RequestType)) {
4589
- case LIBUSB_RECIPIENT_INTERFACE:
4590
- iface = setup->Index & 0xFF;
4591
- break;
4592
- case LIBUSB_RECIPIENT_ENDPOINT:
4593
- r = libusb_get_active_config_descriptor(transfer->dev_handle->dev, &conf_desc);
4594
- if (r == LIBUSB_SUCCESS) {
4595
- iface = get_interface_by_endpoint(conf_desc, (setup->Index & 0xFF));
4596
- libusb_free_config_descriptor(conf_desc);
4597
- break;
4598
- }
4599
- // No break if not able to determine interface
4600
- // Fall through
4601
- default:
4602
- iface = -1;
4603
- break;
4604
- }
4605
-
4606
- // Try and target a specific interface if the control setup indicates such
4607
- if ((iface >= 0) && (iface < USB_MAXINTERFACES)) {
4608
- usbi_dbg(TRANSFER_CTX(transfer), "attempting control transfer targeted to interface %d", iface);
4609
- if ((priv->usb_interface[iface].path != NULL)
4610
- && (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) {
4611
- r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
4612
- if (r == LIBUSB_SUCCESS)
4613
- return r;
4614
- }
4615
- }
4616
-
4617
- // Either not targeted to a specific interface or no luck in doing so.
4618
- // Try a 2 pass approach with all interfaces.
4619
- for (pass = 0; pass < 2; pass++) {
4620
- for (iface = 0; iface < USB_MAXINTERFACES; iface++) {
4621
- if ((priv->usb_interface[iface].path != NULL)
4622
- && (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) {
4623
- if ((pass == 0) && (priv->usb_interface[iface].restricted_functionality)) {
4624
- usbi_dbg(TRANSFER_CTX(transfer), "trying to skip restricted interface #%d (HID keyboard or mouse?)", iface);
4625
- continue;
4626
- }
4627
- usbi_dbg(TRANSFER_CTX(transfer), "using interface %d", iface);
4628
- r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
4629
- // If not supported on this API, it may be supported on another, so don't give up yet!!
4630
- if (r == LIBUSB_ERROR_NOT_SUPPORTED)
4631
- continue;
4632
- return r;
4633
- }
4634
- }
4635
- }
4636
-
4637
- usbi_err(TRANSFER_CTX(transfer), "no libusb supported interfaces to complete request");
4638
- return LIBUSB_ERROR_NOT_FOUND;
4639
- }
4640
-
4641
- static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
4642
- {
4643
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4644
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
4645
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
4646
- int current_interface;
4647
-
4648
- UNUSED(sub_api);
4649
-
4650
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4651
- if (current_interface < 0) {
4652
- usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
4653
- return LIBUSB_ERROR_NOT_FOUND;
4654
- }
4655
-
4656
- CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, submit_bulk_transfer);
4657
-
4658
- return priv->usb_interface[current_interface].apib->
4659
- submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer);
4660
- }
4661
-
4662
- static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer)
4663
- {
4664
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4665
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
4666
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
4667
- int current_interface;
4668
-
4669
- UNUSED(sub_api);
4670
-
4671
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
4672
- if (current_interface < 0) {
4673
- usbi_err(TRANSFER_CTX(transfer), "unable to match endpoint to an open interface - cancelling transfer");
4674
- return LIBUSB_ERROR_NOT_FOUND;
4675
- }
4676
-
4677
- CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, submit_iso_transfer);
4678
-
4679
- return priv->usb_interface[current_interface].apib->
4680
- submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer);
4681
- }
4682
-
4683
- static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
4684
- {
4685
- struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
4686
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4687
- int current_interface;
4688
-
4689
- UNUSED(sub_api);
4690
-
4691
- current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
4692
- if (current_interface < 0) {
4693
- usbi_err(HANDLE_CTX(dev_handle), "unable to match endpoint to an open interface - cannot clear");
4694
- return LIBUSB_ERROR_NOT_FOUND;
4695
- }
4696
-
4697
- CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, clear_halt);
4698
-
4699
- return priv->usb_interface[current_interface].apib->
4700
- clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint);
4701
- }
4702
-
4703
- static int composite_cancel_transfer(int sub_api, struct usbi_transfer *itransfer)
4704
- {
4705
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4706
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
4707
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
4708
- int current_interface = transfer_priv->interface_number;
4709
-
4710
- UNUSED(sub_api);
4711
-
4712
- if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) {
4713
- usbi_err(TRANSFER_CTX(transfer), "program assertion failed - invalid interface_number");
4714
- return LIBUSB_ERROR_NOT_FOUND;
4715
- }
4716
-
4717
- CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, cancel_transfer);
4718
-
4719
- return priv->usb_interface[current_interface].apib->
4720
- cancel_transfer(priv->usb_interface[current_interface].sub_api, itransfer);
4721
- }
4722
-
4723
- static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
4724
- {
4725
- struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
4726
- int i, r;
4727
- bool available[SUB_API_MAX];
4728
-
4729
- UNUSED(sub_api);
4730
-
4731
- for (i = 0; i < SUB_API_MAX; i++)
4732
- available[i] = false;
4733
-
4734
- for (i = 0; i < USB_MAXINTERFACES; i++) {
4735
- if ((priv->usb_interface[i].apib->id == USB_API_WINUSBX)
4736
- && (priv->usb_interface[i].sub_api != SUB_API_NOTSET))
4737
- available[priv->usb_interface[i].sub_api] = true;
4738
- }
4739
-
4740
- for (i = 0; i < SUB_API_MAX; i++) {
4741
- if (available[i]) {
4742
- r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle);
4743
- if (r != LIBUSB_SUCCESS)
4744
- return r;
4745
- }
4746
- }
4747
-
4748
- return LIBUSB_SUCCESS;
4749
- }
4750
-
4751
- static enum libusb_transfer_status composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, DWORD length)
4752
- {
4753
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
4754
- struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
4755
- struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
4756
- int current_interface = transfer_priv->interface_number;
4757
-
4758
- UNUSED(sub_api);
4759
- if (priv->usb_interface[current_interface].apib->copy_transfer_data == NULL) {
4760
- usbi_err(TRANSFER_CTX(transfer), "program assertion failed - no function to copy transfer data");
4761
- return LIBUSB_TRANSFER_ERROR;
4762
- }
4763
-
4764
- return priv->usb_interface[current_interface].apib->
4765
- copy_transfer_data(priv->usb_interface[current_interface].sub_api, itransfer, length);
4766
- }