libusb 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/.gitignore +8 -0
  2. data/.travis.yml +10 -0
  3. data/.yardopts +6 -1
  4. data/Gemfile +16 -0
  5. data/{History.txt → History.md} +28 -16
  6. data/README.md +144 -0
  7. data/Rakefile +28 -24
  8. data/ext/extconf.rb +33 -0
  9. data/ext/libusbx-1.0.14/AUTHORS +50 -0
  10. data/ext/libusbx-1.0.14/COPYING +504 -0
  11. data/ext/libusbx-1.0.14/ChangeLog +139 -0
  12. data/ext/libusbx-1.0.14/INSTALL +234 -0
  13. data/ext/libusbx-1.0.14/Makefile.am +23 -0
  14. data/ext/libusbx-1.0.14/Makefile.in +803 -0
  15. data/ext/libusbx-1.0.14/NEWS +2 -0
  16. data/ext/libusbx-1.0.14/PORTING +94 -0
  17. data/ext/libusbx-1.0.14/README +28 -0
  18. data/ext/libusbx-1.0.14/THANKS +7 -0
  19. data/ext/libusbx-1.0.14/TODO +2 -0
  20. data/ext/libusbx-1.0.14/aclocal.m4 +9480 -0
  21. data/ext/libusbx-1.0.14/compile +143 -0
  22. data/ext/libusbx-1.0.14/config.guess +1501 -0
  23. data/ext/libusbx-1.0.14/config.h.in +116 -0
  24. data/ext/libusbx-1.0.14/config.sub +1705 -0
  25. data/ext/libusbx-1.0.14/configure +14818 -0
  26. data/ext/libusbx-1.0.14/configure.ac +230 -0
  27. data/ext/libusbx-1.0.14/depcomp +630 -0
  28. data/ext/libusbx-1.0.14/doc/Makefile.am +9 -0
  29. data/ext/libusbx-1.0.14/doc/Makefile.in +380 -0
  30. data/ext/libusbx-1.0.14/doc/doxygen.cfg.in +1288 -0
  31. data/ext/libusbx-1.0.14/examples/Makefile.am +18 -0
  32. data/ext/libusbx-1.0.14/examples/Makefile.in +596 -0
  33. data/ext/libusbx-1.0.14/examples/dpfp.c +506 -0
  34. data/ext/libusbx-1.0.14/examples/dpfp_threaded.c +544 -0
  35. data/ext/libusbx-1.0.14/examples/ezusb.c +616 -0
  36. data/ext/libusbx-1.0.14/examples/ezusb.h +107 -0
  37. data/ext/libusbx-1.0.14/examples/fxload.c +261 -0
  38. data/ext/libusbx-1.0.14/examples/getopt/getopt.c +1060 -0
  39. data/ext/libusbx-1.0.14/examples/getopt/getopt.h +180 -0
  40. data/ext/libusbx-1.0.14/examples/getopt/getopt1.c +188 -0
  41. data/ext/libusbx-1.0.14/examples/listdevs.c +63 -0
  42. data/ext/libusbx-1.0.14/examples/xusb.c +1036 -0
  43. data/ext/libusbx-1.0.14/install-sh +520 -0
  44. data/ext/libusbx-1.0.14/libusb-1.0.pc.in +11 -0
  45. data/ext/libusbx-1.0.14/libusb/Makefile.am +56 -0
  46. data/ext/libusbx-1.0.14/libusb/Makefile.in +721 -0
  47. data/ext/libusbx-1.0.14/libusb/core.c +1951 -0
  48. data/ext/libusbx-1.0.14/libusb/descriptor.c +731 -0
  49. data/ext/libusbx-1.0.14/libusb/io.c +2450 -0
  50. data/ext/libusbx-1.0.14/libusb/libusb-1.0.def +126 -0
  51. data/ext/libusbx-1.0.14/libusb/libusb-1.0.rc +59 -0
  52. data/ext/libusbx-1.0.14/libusb/libusb.h +1506 -0
  53. data/ext/libusbx-1.0.14/libusb/libusbi.h +910 -0
  54. data/ext/libusbx-1.0.14/libusb/os/darwin_usb.c +1807 -0
  55. data/ext/libusbx-1.0.14/libusb/os/darwin_usb.h +169 -0
  56. data/ext/libusbx-1.0.14/libusb/os/linux_usbfs.c +2569 -0
  57. data/ext/libusbx-1.0.14/libusb/os/linux_usbfs.h +149 -0
  58. data/ext/libusbx-1.0.14/libusb/os/openbsd_usb.c +727 -0
  59. data/ext/libusbx-1.0.14/libusb/os/poll_posix.h +10 -0
  60. data/ext/libusbx-1.0.14/libusb/os/poll_windows.c +747 -0
  61. data/ext/libusbx-1.0.14/libusb/os/poll_windows.h +114 -0
  62. data/ext/libusbx-1.0.14/libusb/os/threads_posix.c +80 -0
  63. data/ext/libusbx-1.0.14/libusb/os/threads_posix.h +50 -0
  64. data/ext/libusbx-1.0.14/libusb/os/threads_windows.c +211 -0
  65. data/ext/libusbx-1.0.14/libusb/os/threads_windows.h +87 -0
  66. data/ext/libusbx-1.0.14/libusb/os/windows_usb.c +4369 -0
  67. data/ext/libusbx-1.0.14/libusb/os/windows_usb.h +979 -0
  68. data/ext/libusbx-1.0.14/libusb/sync.c +321 -0
  69. data/ext/libusbx-1.0.14/libusb/version.h +18 -0
  70. data/ext/libusbx-1.0.14/libusb/version_nano.h +1 -0
  71. data/ext/libusbx-1.0.14/ltmain.sh +9636 -0
  72. data/ext/libusbx-1.0.14/missing +376 -0
  73. data/lib/libusb.rb +2 -3
  74. data/lib/libusb/call.rb +49 -7
  75. data/lib/libusb/compat.rb +15 -9
  76. data/lib/libusb/configuration.rb +15 -3
  77. data/lib/libusb/constants.rb +19 -6
  78. data/lib/libusb/context.rb +181 -3
  79. data/lib/libusb/dev_handle.rb +91 -40
  80. data/lib/libusb/endpoint.rb +41 -14
  81. data/lib/libusb/eventmachine.rb +183 -0
  82. data/lib/libusb/transfer.rb +21 -8
  83. data/lib/libusb/version_gem.rb +19 -0
  84. data/lib/libusb/{version.rb → version_struct.rb} +0 -0
  85. data/libusb.gemspec +31 -0
  86. data/test/test_libusb_compat.rb +1 -1
  87. data/test/test_libusb_compat_mass_storage.rb +2 -2
  88. data/test/test_libusb_descriptors.rb +1 -1
  89. data/test/test_libusb_event_machine.rb +118 -0
  90. data/test/test_libusb_iso_transfer.rb +6 -1
  91. data/test/test_libusb_mass_storage.rb +9 -3
  92. data/test/test_libusb_mass_storage2.rb +1 -1
  93. data/test/test_libusb_structs.rb +45 -0
  94. data/test/test_libusb_threads.rb +89 -0
  95. data/test/test_libusb_version.rb +4 -0
  96. metadata +109 -44
  97. data/.autotest +0 -23
  98. data/.gemtest +0 -0
  99. data/Manifest.txt +0 -3
  100. data/README.rdoc +0 -115
  101. data/test/test_libusb_keyboard.rb +0 -50
@@ -0,0 +1,979 @@
1
+ /*
2
+ * Windows backend for libusbx 1.0
3
+ * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4
+ * With contributions from Michael Plante, Orin Eman et al.
5
+ * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
6
+ * Major code testing contribution by Xiaofan Chen
7
+ *
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Lesser General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2.1 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
+ * Lesser General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Lesser General Public
19
+ * License along with this library; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
+ */
22
+
23
+ #pragma once
24
+
25
+ #if defined(_MSC_VER)
26
+ // disable /W4 MSVC warnings that are benign
27
+ #pragma warning(disable:4127) // conditional expression is constant
28
+ #pragma warning(disable:4100) // unreferenced formal parameter
29
+ #pragma warning(disable:4214) // bit field types other than int
30
+ #pragma warning(disable:4201) // nameless struct/union
31
+ #endif
32
+
33
+ // Windows API default is uppercase - ugh!
34
+ #if !defined(bool)
35
+ #define bool BOOL
36
+ #endif
37
+ #if !defined(true)
38
+ #define true TRUE
39
+ #endif
40
+ #if !defined(false)
41
+ #define false FALSE
42
+ #endif
43
+
44
+ // Missing from MSVC6 setupapi.h
45
+ #if !defined(SPDRP_ADDRESS)
46
+ #define SPDRP_ADDRESS 28
47
+ #endif
48
+ #if !defined(SPDRP_INSTALL_STATE)
49
+ #define SPDRP_INSTALL_STATE 34
50
+ #endif
51
+
52
+ #if defined(__CYGWIN__ )
53
+ #define _stricmp stricmp
54
+ // cygwin produces a warning unless these prototypes are defined
55
+ extern int _snprintf(char *buffer, size_t count, const char *format, ...);
56
+ extern char *_strdup(const char *strSource);
57
+ // _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
58
+ #define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, f)
59
+ #endif
60
+ #define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
61
+ #define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
62
+ #define safe_min(a, b) min((size_t)(a), (size_t)(b))
63
+ #define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
64
+ ((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
65
+ #define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
66
+ #define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
67
+ #define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
68
+ #define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
69
+ #define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
70
+ #define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
71
+ #define safe_strlen(str) ((str==NULL)?0:strlen(str))
72
+ #define safe_sprintf _snprintf
73
+ #define safe_unref_device(dev) do {if (dev != NULL) {libusb_unref_device(dev); dev = NULL;}} while(0)
74
+ #define wchar_to_utf8_ms(wstr, str, strlen) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, strlen, NULL, NULL)
75
+ #ifndef ARRAYSIZE
76
+ #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
77
+ #endif
78
+
79
+ #define MAX_CTRL_BUFFER_LENGTH 4096
80
+ #define MAX_USB_DEVICES 256
81
+ #define MAX_USB_STRING_LENGTH 128
82
+ #define MAX_HID_REPORT_SIZE 1024
83
+ #define MAX_HID_DESCRIPTOR_SIZE 256
84
+ #define MAX_GUID_STRING_LENGTH 40
85
+ #define MAX_PATH_LENGTH 128
86
+ #define MAX_KEY_LENGTH 256
87
+ #define MAX_TIMER_SEMAPHORES 128
88
+ #define TIMER_REQUEST_RETRY_MS 100
89
+ #define ERR_BUFFER_SIZE 256
90
+ #define LIST_SEPARATOR ';'
91
+ #define HTAB_SIZE 1021
92
+
93
+ // Handle code for HID interface that have been claimed ("dibs")
94
+ #define INTERFACE_CLAIMED ((HANDLE)(intptr_t)0xD1B5)
95
+ // Additional return code for HID operations that completed synchronously
96
+ #define LIBUSB_COMPLETED (LIBUSB_SUCCESS + 1)
97
+
98
+ // http://msdn.microsoft.com/en-us/library/ff545978.aspx
99
+ // http://msdn.microsoft.com/en-us/library/ff545972.aspx
100
+ // http://msdn.microsoft.com/en-us/library/ff545982.aspx
101
+ #if !defined(GUID_DEVINTERFACE_USB_HOST_CONTROLLER)
102
+ const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} };
103
+ #endif
104
+ #if !defined(GUID_DEVINTERFACE_USB_DEVICE)
105
+ const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} };
106
+ #endif
107
+ #if !defined(GUID_DEVINTERFACE_USB_HUB)
108
+ const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} };
109
+ #endif
110
+ #if !defined(GUID_DEVINTERFACE_LIBUSB0_FILTER)
111
+ const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = { 0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9} };
112
+ #endif
113
+
114
+
115
+ /*
116
+ * Multiple USB API backend support
117
+ */
118
+ #define USB_API_UNSUPPORTED 0
119
+ #define USB_API_HUB 1
120
+ #define USB_API_COMPOSITE 2
121
+ #define USB_API_WINUSBX 3
122
+ #define USB_API_HID 4
123
+ #define USB_API_MAX 5
124
+ // The following is used to indicate if the HID or composite extra props have already been set.
125
+ #define USB_API_SET (1<<USB_API_MAX)
126
+
127
+ // Sub-APIs for WinUSB-like driver APIs (WinUSB, libusbK, libusb-win32 through the libusbK DLL)
128
+ // Must have the same values as the KUSB_DRVID enum from libusbk.h
129
+ #define SUB_API_NOTSET -1
130
+ #define SUB_API_LIBUSBK 0
131
+ #define SUB_API_LIBUSB0 1
132
+ #define SUB_API_WINUSB 2
133
+ #define SUB_API_MAX 3
134
+
135
+ #define WINUSBX_DRV_NAMES { "libusbK", "libusb0", "WinUSB"}
136
+
137
+ struct windows_usb_api_backend {
138
+ const uint8_t id;
139
+ const char* designation;
140
+ const char **driver_name_list; // Driver name, without .sys, e.g. "usbccgp"
141
+ const uint8_t nb_driver_names;
142
+ int (*init)(int sub_api, struct libusb_context *ctx);
143
+ int (*exit)(int sub_api);
144
+ int (*open)(int sub_api, struct libusb_device_handle *dev_handle);
145
+ void (*close)(int sub_api, struct libusb_device_handle *dev_handle);
146
+ int (*configure_endpoints)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
147
+ int (*claim_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
148
+ int (*set_interface_altsetting)(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
149
+ int (*release_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
150
+ int (*clear_halt)(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
151
+ int (*reset_device)(int sub_api, struct libusb_device_handle *dev_handle);
152
+ int (*submit_bulk_transfer)(int sub_api, struct usbi_transfer *itransfer);
153
+ int (*submit_iso_transfer)(int sub_api, struct usbi_transfer *itransfer);
154
+ int (*submit_control_transfer)(int sub_api, struct usbi_transfer *itransfer);
155
+ int (*abort_control)(int sub_api, struct usbi_transfer *itransfer);
156
+ int (*abort_transfers)(int sub_api, struct usbi_transfer *itransfer);
157
+ int (*copy_transfer_data)(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
158
+ };
159
+
160
+ extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX];
161
+
162
+ #define PRINT_UNSUPPORTED_API(fname) \
163
+ usbi_dbg("unsupported API call for '" \
164
+ #fname "' (unrecognized device driver)"); \
165
+ return LIBUSB_ERROR_NOT_SUPPORTED;
166
+
167
+ /*
168
+ * private structures definition
169
+ * with inline pseudo constructors/destructors
170
+ */
171
+
172
+ // TODO (v2+): move hid desc to libusb.h?
173
+ struct libusb_hid_descriptor {
174
+ uint8_t bLength;
175
+ uint8_t bDescriptorType;
176
+ uint16_t bcdHID;
177
+ uint8_t bCountryCode;
178
+ uint8_t bNumDescriptors;
179
+ uint8_t bClassDescriptorType;
180
+ uint16_t wClassDescriptorLength;
181
+ };
182
+ #define LIBUSB_DT_HID_SIZE 9
183
+ #define HID_MAX_CONFIG_DESC_SIZE (LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE \
184
+ + LIBUSB_DT_HID_SIZE + 2 * LIBUSB_DT_ENDPOINT_SIZE)
185
+ #define HID_MAX_REPORT_SIZE 1024
186
+ #define HID_IN_EP 0x81
187
+ #define HID_OUT_EP 0x02
188
+ #define LIBUSB_REQ_RECIPIENT(request_type) ((request_type) & 0x1F)
189
+ #define LIBUSB_REQ_TYPE(request_type) ((request_type) & (0x03 << 5))
190
+ #define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN)
191
+ #define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type))
192
+
193
+ // The following are used for HID reports IOCTLs
194
+ #define HID_CTL_CODE(id) \
195
+ CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS)
196
+ #define HID_BUFFER_CTL_CODE(id) \
197
+ CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_BUFFERED, FILE_ANY_ACCESS)
198
+ #define HID_IN_CTL_CODE(id) \
199
+ CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS)
200
+ #define HID_OUT_CTL_CODE(id) \
201
+ CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
202
+
203
+ #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
204
+ #define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
205
+ #define IOCTL_HID_SET_FEATURE HID_IN_CTL_CODE(100)
206
+ #define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101)
207
+
208
+ enum libusb_hid_request_type {
209
+ HID_REQ_GET_REPORT = 0x01,
210
+ HID_REQ_GET_IDLE = 0x02,
211
+ HID_REQ_GET_PROTOCOL = 0x03,
212
+ HID_REQ_SET_REPORT = 0x09,
213
+ HID_REQ_SET_IDLE = 0x0A,
214
+ HID_REQ_SET_PROTOCOL = 0x0B
215
+ };
216
+
217
+ enum libusb_hid_report_type {
218
+ HID_REPORT_TYPE_INPUT = 0x01,
219
+ HID_REPORT_TYPE_OUTPUT = 0x02,
220
+ HID_REPORT_TYPE_FEATURE = 0x03
221
+ };
222
+
223
+ struct hid_device_priv {
224
+ uint16_t vid;
225
+ uint16_t pid;
226
+ uint8_t config;
227
+ uint8_t nb_interfaces;
228
+ bool uses_report_ids[3]; // input, ouptput, feature
229
+ uint16_t input_report_size;
230
+ uint16_t output_report_size;
231
+ uint16_t feature_report_size;
232
+ WCHAR string[3][MAX_USB_STRING_LENGTH];
233
+ uint8_t string_index[3]; // man, prod, ser
234
+ };
235
+
236
+ typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
237
+ struct windows_device_priv {
238
+ uint8_t depth; // distance to HCD
239
+ uint8_t port; // port number on the hub
240
+ uint8_t active_config;
241
+ struct libusb_device *parent_dev; // access to parent is required for usermode ops
242
+ struct windows_usb_api_backend const *apib;
243
+ char *path; // device interface path
244
+ int sub_api; // for WinUSB-like APIs
245
+ struct {
246
+ char *path; // each interface needs a device interface path,
247
+ struct windows_usb_api_backend const *apib; // an API backend (multiple drivers support),
248
+ int sub_api;
249
+ int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
250
+ uint8_t *endpoint;
251
+ bool restricted_functionality; // indicates if the interface functionality is restricted
252
+ // by Windows (eg. HID keyboards or mice cannot do R/W)
253
+ } usb_interface[USB_MAXINTERFACES];
254
+ struct hid_device_priv *hid;
255
+ USB_DEVICE_DESCRIPTOR dev_descriptor;
256
+ unsigned char **config_descriptor; // list of pointers to the cached config descriptors
257
+ };
258
+
259
+ static inline struct windows_device_priv *_device_priv(struct libusb_device *dev) {
260
+ return (struct windows_device_priv *)dev->os_priv;
261
+ }
262
+
263
+ static inline void windows_device_priv_init(libusb_device* dev) {
264
+ struct windows_device_priv* p = _device_priv(dev);
265
+ int i;
266
+ p->depth = 0;
267
+ p->port = 0;
268
+ p->parent_dev = NULL;
269
+ p->path = NULL;
270
+ p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
271
+ p->sub_api = SUB_API_NOTSET;
272
+ p->hid = NULL;
273
+ p->active_config = 0;
274
+ p->config_descriptor = NULL;
275
+ memset(&(p->dev_descriptor), 0, sizeof(USB_DEVICE_DESCRIPTOR));
276
+ for (i=0; i<USB_MAXINTERFACES; i++) {
277
+ p->usb_interface[i].path = NULL;
278
+ p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED];
279
+ p->usb_interface[i].sub_api = SUB_API_NOTSET;
280
+ p->usb_interface[i].nb_endpoints = 0;
281
+ p->usb_interface[i].endpoint = NULL;
282
+ p->usb_interface[i].restricted_functionality = false;
283
+ }
284
+ }
285
+
286
+ static inline void windows_device_priv_release(libusb_device* dev) {
287
+ struct windows_device_priv* p = _device_priv(dev);
288
+ int i;
289
+ safe_free(p->path);
290
+ if ((dev->num_configurations > 0) && (p->config_descriptor != NULL)) {
291
+ for (i=0; i < dev->num_configurations; i++)
292
+ safe_free(p->config_descriptor[i]);
293
+ }
294
+ safe_free(p->config_descriptor);
295
+ safe_free(p->hid);
296
+ for (i=0; i<USB_MAXINTERFACES; i++) {
297
+ safe_free(p->usb_interface[i].path);
298
+ safe_free(p->usb_interface[i].endpoint);
299
+ }
300
+ }
301
+
302
+ struct interface_handle_t {
303
+ HANDLE dev_handle; // WinUSB needs an extra handle for the file
304
+ HANDLE api_handle; // used by the API to communicate with the device
305
+ };
306
+
307
+ struct windows_device_handle_priv {
308
+ int active_interface;
309
+ struct interface_handle_t interface_handle[USB_MAXINTERFACES];
310
+ int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
311
+ };
312
+
313
+ static inline struct windows_device_handle_priv *_device_handle_priv(
314
+ struct libusb_device_handle *handle)
315
+ {
316
+ return (struct windows_device_handle_priv *) handle->os_priv;
317
+ }
318
+
319
+ // used for async polling functions
320
+ struct windows_transfer_priv {
321
+ struct winfd pollable_fd;
322
+ uint8_t interface_number;
323
+ uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
324
+ uint8_t *hid_dest; // transfer buffer destination, required for HID
325
+ size_t hid_expected_size;
326
+ };
327
+
328
+ // used to match a device driver (including filter drivers) against a supported API
329
+ struct driver_lookup {
330
+ char list[MAX_KEY_LENGTH+1];// REG_MULTI_SZ list of services (driver) names
331
+ const DWORD reg_prop; // SPDRP registry key to use to retreive list
332
+ const char* designation; // internal designation (for debug output)
333
+ };
334
+
335
+ /*
336
+ * API macros - from libusb-win32 1.x
337
+ */
338
+ #define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \
339
+ typedef ret (api * __dll_##name##_t)args; \
340
+ static __dll_##name##_t prefixname = NULL
341
+
342
+ #define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
343
+ do { \
344
+ HMODULE h = GetModuleHandleA(#dll); \
345
+ if (!h) \
346
+ h = LoadLibraryA(#dll); \
347
+ if (!h) { \
348
+ if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
349
+ else { break; } \
350
+ } \
351
+ prefixname = (__dll_##name##_t)GetProcAddress(h, #name); \
352
+ if (prefixname) break; \
353
+ prefixname = (__dll_##name##_t)GetProcAddress(h, #name "A"); \
354
+ if (prefixname) break; \
355
+ prefixname = (__dll_##name##_t)GetProcAddress(h, #name "W"); \
356
+ if (prefixname) break; \
357
+ if(ret_on_failure) \
358
+ return LIBUSB_ERROR_NOT_FOUND; \
359
+ } while(0)
360
+
361
+ #define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args)
362
+ #define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure)
363
+ #define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args)
364
+ #define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
365
+
366
+ /* OLE32 dependency */
367
+ DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
368
+
369
+ /* SetupAPI dependencies */
370
+ DLL_DECLARE_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD));
371
+ DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
372
+ DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
373
+ const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA));
374
+ DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
375
+ PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA));
376
+ DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
377
+ DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
378
+ DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
379
+ PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
380
+ DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD));
381
+ DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
382
+ DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
383
+
384
+ /*
385
+ * Windows DDK API definitions. Most of it copied from MinGW's includes
386
+ */
387
+ typedef DWORD DEVNODE, DEVINST;
388
+ typedef DEVNODE *PDEVNODE, *PDEVINST;
389
+ typedef DWORD RETURN_TYPE;
390
+ typedef RETURN_TYPE CONFIGRET;
391
+
392
+ #define CR_SUCCESS 0x00000000
393
+ #define CR_NO_SUCH_DEVNODE 0x0000000D
394
+
395
+ #define USB_DEVICE_DESCRIPTOR_TYPE LIBUSB_DT_DEVICE
396
+ #define USB_CONFIGURATION_DESCRIPTOR_TYPE LIBUSB_DT_CONFIG
397
+ #define USB_STRING_DESCRIPTOR_TYPE LIBUSB_DT_STRING
398
+ #define USB_INTERFACE_DESCRIPTOR_TYPE LIBUSB_DT_INTERFACE
399
+ #define USB_ENDPOINT_DESCRIPTOR_TYPE LIBUSB_DT_ENDPOINT
400
+
401
+ #define USB_REQUEST_GET_STATUS LIBUSB_REQUEST_GET_STATUS
402
+ #define USB_REQUEST_CLEAR_FEATURE LIBUSB_REQUEST_CLEAR_FEATURE
403
+ #define USB_REQUEST_SET_FEATURE LIBUSB_REQUEST_SET_FEATURE
404
+ #define USB_REQUEST_SET_ADDRESS LIBUSB_REQUEST_SET_ADDRESS
405
+ #define USB_REQUEST_GET_DESCRIPTOR LIBUSB_REQUEST_GET_DESCRIPTOR
406
+ #define USB_REQUEST_SET_DESCRIPTOR LIBUSB_REQUEST_SET_DESCRIPTOR
407
+ #define USB_REQUEST_GET_CONFIGURATION LIBUSB_REQUEST_GET_CONFIGURATION
408
+ #define USB_REQUEST_SET_CONFIGURATION LIBUSB_REQUEST_SET_CONFIGURATION
409
+ #define USB_REQUEST_GET_INTERFACE LIBUSB_REQUEST_GET_INTERFACE
410
+ #define USB_REQUEST_SET_INTERFACE LIBUSB_REQUEST_SET_INTERFACE
411
+ #define USB_REQUEST_SYNC_FRAME LIBUSB_REQUEST_SYNCH_FRAME
412
+
413
+ #define USB_GET_NODE_INFORMATION 258
414
+ #define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
415
+ #define USB_GET_NODE_CONNECTION_NAME 261
416
+ #define USB_GET_HUB_CAPABILITIES 271
417
+ #if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX)
418
+ #define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
419
+ #endif
420
+ #if !defined(USB_GET_HUB_CAPABILITIES_EX)
421
+ #define USB_GET_HUB_CAPABILITIES_EX 276
422
+ #endif
423
+
424
+ #ifndef METHOD_BUFFERED
425
+ #define METHOD_BUFFERED 0
426
+ #endif
427
+ #ifndef FILE_ANY_ACCESS
428
+ #define FILE_ANY_ACCESS 0x00000000
429
+ #endif
430
+ #ifndef FILE_DEVICE_UNKNOWN
431
+ #define FILE_DEVICE_UNKNOWN 0x00000022
432
+ #endif
433
+ #ifndef FILE_DEVICE_USB
434
+ #define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
435
+ #endif
436
+
437
+ #ifndef CTL_CODE
438
+ #define CTL_CODE(DeviceType, Function, Method, Access)( \
439
+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
440
+ #endif
441
+
442
+ typedef enum USB_CONNECTION_STATUS {
443
+ NoDeviceConnected,
444
+ DeviceConnected,
445
+ DeviceFailedEnumeration,
446
+ DeviceGeneralFailure,
447
+ DeviceCausedOvercurrent,
448
+ DeviceNotEnoughPower,
449
+ DeviceNotEnoughBandwidth,
450
+ DeviceHubNestedTooDeeply,
451
+ DeviceInLegacyHub
452
+ } USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
453
+
454
+ typedef enum USB_HUB_NODE {
455
+ UsbHub,
456
+ UsbMIParent
457
+ } USB_HUB_NODE;
458
+
459
+ /* Cfgmgr32.dll interface */
460
+ DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
461
+ DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
462
+ DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
463
+ DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
464
+
465
+ #define IOCTL_USB_GET_HUB_CAPABILITIES_EX \
466
+ CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
467
+
468
+ #define IOCTL_USB_GET_HUB_CAPABILITIES \
469
+ CTL_CODE(FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES, METHOD_BUFFERED, FILE_ANY_ACCESS)
470
+
471
+ #define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \
472
+ CTL_CODE(FILE_DEVICE_USB, USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
473
+
474
+ #define IOCTL_USB_GET_ROOT_HUB_NAME \
475
+ CTL_CODE(FILE_DEVICE_USB, HCD_GET_ROOT_HUB_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
476
+
477
+ #define IOCTL_USB_GET_NODE_INFORMATION \
478
+ CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
479
+
480
+ #define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
481
+ CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
482
+
483
+ #define IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES \
484
+ CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_ATTRIBUTES, METHOD_BUFFERED, FILE_ANY_ACCESS)
485
+
486
+ #define IOCTL_USB_GET_NODE_CONNECTION_NAME \
487
+ CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
488
+
489
+ // Most of the structures below need to be packed
490
+ #pragma pack(push, 1)
491
+
492
+ typedef struct USB_INTERFACE_DESCRIPTOR {
493
+ UCHAR bLength;
494
+ UCHAR bDescriptorType;
495
+ UCHAR bInterfaceNumber;
496
+ UCHAR bAlternateSetting;
497
+ UCHAR bNumEndpoints;
498
+ UCHAR bInterfaceClass;
499
+ UCHAR bInterfaceSubClass;
500
+ UCHAR bInterfaceProtocol;
501
+ UCHAR iInterface;
502
+ } USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
503
+
504
+ typedef struct USB_CONFIGURATION_DESCRIPTOR {
505
+ UCHAR bLength;
506
+ UCHAR bDescriptorType;
507
+ USHORT wTotalLength;
508
+ UCHAR bNumInterfaces;
509
+ UCHAR bConfigurationValue;
510
+ UCHAR iConfiguration;
511
+ UCHAR bmAttributes;
512
+ UCHAR MaxPower;
513
+ } USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
514
+
515
+ typedef struct USB_CONFIGURATION_DESCRIPTOR_SHORT {
516
+ struct {
517
+ ULONG ConnectionIndex;
518
+ struct {
519
+ UCHAR bmRequest;
520
+ UCHAR bRequest;
521
+ USHORT wValue;
522
+ USHORT wIndex;
523
+ USHORT wLength;
524
+ } SetupPacket;
525
+ } req;
526
+ USB_CONFIGURATION_DESCRIPTOR data;
527
+ } USB_CONFIGURATION_DESCRIPTOR_SHORT;
528
+
529
+ typedef struct USB_ENDPOINT_DESCRIPTOR {
530
+ UCHAR bLength;
531
+ UCHAR bDescriptorType;
532
+ UCHAR bEndpointAddress;
533
+ UCHAR bmAttributes;
534
+ USHORT wMaxPacketSize;
535
+ UCHAR bInterval;
536
+ } USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
537
+
538
+ typedef struct USB_DESCRIPTOR_REQUEST {
539
+ ULONG ConnectionIndex;
540
+ struct {
541
+ UCHAR bmRequest;
542
+ UCHAR bRequest;
543
+ USHORT wValue;
544
+ USHORT wIndex;
545
+ USHORT wLength;
546
+ } SetupPacket;
547
+ // UCHAR Data[0];
548
+ } USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST;
549
+
550
+ typedef struct USB_HUB_DESCRIPTOR {
551
+ UCHAR bDescriptorLength;
552
+ UCHAR bDescriptorType;
553
+ UCHAR bNumberOfPorts;
554
+ USHORT wHubCharacteristics;
555
+ UCHAR bPowerOnToPowerGood;
556
+ UCHAR bHubControlCurrent;
557
+ UCHAR bRemoveAndPowerMask[64];
558
+ } USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
559
+
560
+ typedef struct USB_ROOT_HUB_NAME {
561
+ ULONG ActualLength;
562
+ WCHAR RootHubName[1];
563
+ } USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;
564
+
565
+ typedef struct USB_ROOT_HUB_NAME_FIXED {
566
+ ULONG ActualLength;
567
+ WCHAR RootHubName[MAX_PATH_LENGTH];
568
+ } USB_ROOT_HUB_NAME_FIXED;
569
+
570
+ typedef struct USB_NODE_CONNECTION_NAME {
571
+ ULONG ConnectionIndex;
572
+ ULONG ActualLength;
573
+ WCHAR NodeName[1];
574
+ } USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME;
575
+
576
+ typedef struct USB_NODE_CONNECTION_NAME_FIXED {
577
+ ULONG ConnectionIndex;
578
+ ULONG ActualLength;
579
+ WCHAR NodeName[MAX_PATH_LENGTH];
580
+ } USB_NODE_CONNECTION_NAME_FIXED;
581
+
582
+ typedef struct USB_HUB_NAME_FIXED {
583
+ union {
584
+ USB_ROOT_HUB_NAME_FIXED root;
585
+ USB_NODE_CONNECTION_NAME_FIXED node;
586
+ } u;
587
+ } USB_HUB_NAME_FIXED;
588
+
589
+ typedef struct USB_HUB_INFORMATION {
590
+ USB_HUB_DESCRIPTOR HubDescriptor;
591
+ BOOLEAN HubIsBusPowered;
592
+ } USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;
593
+
594
+ typedef struct USB_MI_PARENT_INFORMATION {
595
+ ULONG NumberOfInterfaces;
596
+ } USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION;
597
+
598
+ typedef struct USB_NODE_INFORMATION {
599
+ USB_HUB_NODE NodeType;
600
+ union {
601
+ USB_HUB_INFORMATION HubInformation;
602
+ USB_MI_PARENT_INFORMATION MiParentInformation;
603
+ } u;
604
+ } USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;
605
+
606
+ typedef struct USB_PIPE_INFO {
607
+ USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
608
+ ULONG ScheduleOffset;
609
+ } USB_PIPE_INFO, *PUSB_PIPE_INFO;
610
+
611
+ typedef struct USB_NODE_CONNECTION_INFORMATION_EX {
612
+ ULONG ConnectionIndex;
613
+ USB_DEVICE_DESCRIPTOR DeviceDescriptor;
614
+ UCHAR CurrentConfigurationValue;
615
+ UCHAR Speed;
616
+ BOOLEAN DeviceIsHub;
617
+ USHORT DeviceAddress;
618
+ ULONG NumberOfOpenPipes;
619
+ USB_CONNECTION_STATUS ConnectionStatus;
620
+ // USB_PIPE_INFO PipeList[0];
621
+ } USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX;
622
+
623
+ typedef struct USB_HUB_CAP_FLAGS {
624
+ ULONG HubIsHighSpeedCapable:1;
625
+ ULONG HubIsHighSpeed:1;
626
+ ULONG HubIsMultiTtCapable:1;
627
+ ULONG HubIsMultiTt:1;
628
+ ULONG HubIsRoot:1;
629
+ ULONG HubIsArmedWakeOnConnect:1;
630
+ ULONG ReservedMBZ:26;
631
+ } USB_HUB_CAP_FLAGS, *PUSB_HUB_CAP_FLAGS;
632
+
633
+ typedef struct USB_HUB_CAPABILITIES {
634
+ ULONG HubIs2xCapable : 1;
635
+ } USB_HUB_CAPABILITIES, *PUSB_HUB_CAPABILITIES;
636
+
637
+ typedef struct USB_HUB_CAPABILITIES_EX {
638
+ USB_HUB_CAP_FLAGS CapabilityFlags;
639
+ } USB_HUB_CAPABILITIES_EX, *PUSB_HUB_CAPABILITIES_EX;
640
+
641
+ #pragma pack(pop)
642
+
643
+ /* winusb.dll interface */
644
+
645
+ #define SHORT_PACKET_TERMINATE 0x01
646
+ #define AUTO_CLEAR_STALL 0x02
647
+ #define PIPE_TRANSFER_TIMEOUT 0x03
648
+ #define IGNORE_SHORT_PACKETS 0x04
649
+ #define ALLOW_PARTIAL_READS 0x05
650
+ #define AUTO_FLUSH 0x06
651
+ #define RAW_IO 0x07
652
+ #define MAXIMUM_TRANSFER_SIZE 0x08
653
+ #define AUTO_SUSPEND 0x81
654
+ #define SUSPEND_DELAY 0x83
655
+ #define DEVICE_SPEED 0x01
656
+ #define LowSpeed 0x01
657
+ #define FullSpeed 0x02
658
+ #define HighSpeed 0x03
659
+
660
+ typedef enum USBD_PIPE_TYPE {
661
+ UsbdPipeTypeControl,
662
+ UsbdPipeTypeIsochronous,
663
+ UsbdPipeTypeBulk,
664
+ UsbdPipeTypeInterrupt
665
+ } USBD_PIPE_TYPE;
666
+
667
+ typedef struct {
668
+ USBD_PIPE_TYPE PipeType;
669
+ UCHAR PipeId;
670
+ USHORT MaximumPacketSize;
671
+ UCHAR Interval;
672
+ } WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION;
673
+
674
+ #pragma pack(1)
675
+ typedef struct {
676
+ UCHAR request_type;
677
+ UCHAR request;
678
+ USHORT value;
679
+ USHORT index;
680
+ USHORT length;
681
+ } WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET;
682
+ #pragma pack()
683
+
684
+ typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE;
685
+
686
+ typedef BOOL (WINAPI *WinUsb_AbortPipe_t)(
687
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
688
+ UCHAR PipeID
689
+ );
690
+ typedef BOOL (WINAPI *WinUsb_ControlTransfer_t)(
691
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
692
+ WINUSB_SETUP_PACKET SetupPacket,
693
+ PUCHAR Buffer,
694
+ ULONG BufferLength,
695
+ PULONG LengthTransferred,
696
+ LPOVERLAPPED Overlapped
697
+ );
698
+ typedef BOOL (WINAPI *WinUsb_FlushPipe_t)(
699
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
700
+ UCHAR PipeID
701
+ );
702
+ typedef BOOL (WINAPI *WinUsb_Free_t)(
703
+ WINUSB_INTERFACE_HANDLE InterfaceHandle
704
+ );
705
+ typedef BOOL (WINAPI *WinUsb_GetAssociatedInterface_t)(
706
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
707
+ UCHAR AssociatedInterfaceIndex,
708
+ PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle
709
+ );
710
+ typedef BOOL (WINAPI *WinUsb_GetCurrentAlternateSetting_t)(
711
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
712
+ PUCHAR AlternateSetting
713
+ );
714
+ typedef BOOL (WINAPI *WinUsb_GetDescriptor_t)(
715
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
716
+ UCHAR DescriptorType,
717
+ UCHAR Index,
718
+ USHORT LanguageID,
719
+ PUCHAR Buffer,
720
+ ULONG BufferLength,
721
+ PULONG LengthTransferred
722
+ );
723
+ typedef BOOL (WINAPI *WinUsb_GetOverlappedResult_t)(
724
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
725
+ LPOVERLAPPED lpOverlapped,
726
+ LPDWORD lpNumberOfBytesTransferred,
727
+ BOOL bWait
728
+ );
729
+ typedef BOOL (WINAPI *WinUsb_GetPipePolicy_t)(
730
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
731
+ UCHAR PipeID,
732
+ ULONG PolicyType,
733
+ PULONG ValueLength,
734
+ PVOID Value
735
+ );
736
+ typedef BOOL (WINAPI *WinUsb_GetPowerPolicy_t)(
737
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
738
+ ULONG PolicyType,
739
+ PULONG ValueLength,
740
+ PVOID Value
741
+ );
742
+ typedef BOOL (WINAPI *WinUsb_Initialize_t)(
743
+ HANDLE DeviceHandle,
744
+ PWINUSB_INTERFACE_HANDLE InterfaceHandle
745
+ );
746
+ typedef BOOL (WINAPI *WinUsb_QueryDeviceInformation_t)(
747
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
748
+ ULONG InformationType,
749
+ PULONG BufferLength,
750
+ PVOID Buffer
751
+ );
752
+ typedef BOOL (WINAPI *WinUsb_QueryInterfaceSettings_t)(
753
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
754
+ UCHAR AlternateSettingNumber,
755
+ PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
756
+ );
757
+ typedef BOOL (WINAPI *WinUsb_QueryPipe_t)(
758
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
759
+ UCHAR AlternateInterfaceNumber,
760
+ UCHAR PipeIndex,
761
+ PWINUSB_PIPE_INFORMATION PipeInformation
762
+ );
763
+ typedef BOOL (WINAPI *WinUsb_ReadPipe_t)(
764
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
765
+ UCHAR PipeID,
766
+ PUCHAR Buffer,
767
+ ULONG BufferLength,
768
+ PULONG LengthTransferred,
769
+ LPOVERLAPPED Overlapped
770
+ );
771
+ typedef BOOL (WINAPI *WinUsb_ResetPipe_t)(
772
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
773
+ UCHAR PipeID
774
+ );
775
+ typedef BOOL (WINAPI *WinUsb_SetCurrentAlternateSetting_t)(
776
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
777
+ UCHAR AlternateSetting
778
+ );
779
+ typedef BOOL (WINAPI *WinUsb_SetPipePolicy_t)(
780
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
781
+ UCHAR PipeID,
782
+ ULONG PolicyType,
783
+ ULONG ValueLength,
784
+ PVOID Value
785
+ );
786
+ typedef BOOL (WINAPI *WinUsb_SetPowerPolicy_t)(
787
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
788
+ ULONG PolicyType,
789
+ ULONG ValueLength,
790
+ PVOID Value
791
+ );
792
+ typedef BOOL (WINAPI *WinUsb_WritePipe_t)(
793
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
794
+ UCHAR PipeID,
795
+ PUCHAR Buffer,
796
+ ULONG BufferLength,
797
+ PULONG LengthTransferred,
798
+ LPOVERLAPPED Overlapped
799
+ );
800
+ typedef BOOL (WINAPI *WinUsb_ResetDevice_t)(
801
+ WINUSB_INTERFACE_HANDLE InterfaceHandle
802
+ );
803
+
804
+ /* /!\ These must match the ones from the official libusbk.h */
805
+ typedef enum _KUSB_FNID
806
+ {
807
+ KUSB_FNID_Init,
808
+ KUSB_FNID_Free,
809
+ KUSB_FNID_ClaimInterface,
810
+ KUSB_FNID_ReleaseInterface,
811
+ KUSB_FNID_SetAltInterface,
812
+ KUSB_FNID_GetAltInterface,
813
+ KUSB_FNID_GetDescriptor,
814
+ KUSB_FNID_ControlTransfer,
815
+ KUSB_FNID_SetPowerPolicy,
816
+ KUSB_FNID_GetPowerPolicy,
817
+ KUSB_FNID_SetConfiguration,
818
+ KUSB_FNID_GetConfiguration,
819
+ KUSB_FNID_ResetDevice,
820
+ KUSB_FNID_Initialize,
821
+ KUSB_FNID_SelectInterface,
822
+ KUSB_FNID_GetAssociatedInterface,
823
+ KUSB_FNID_Clone,
824
+ KUSB_FNID_QueryInterfaceSettings,
825
+ KUSB_FNID_QueryDeviceInformation,
826
+ KUSB_FNID_SetCurrentAlternateSetting,
827
+ KUSB_FNID_GetCurrentAlternateSetting,
828
+ KUSB_FNID_QueryPipe,
829
+ KUSB_FNID_SetPipePolicy,
830
+ KUSB_FNID_GetPipePolicy,
831
+ KUSB_FNID_ReadPipe,
832
+ KUSB_FNID_WritePipe,
833
+ KUSB_FNID_ResetPipe,
834
+ KUSB_FNID_AbortPipe,
835
+ KUSB_FNID_FlushPipe,
836
+ KUSB_FNID_IsoReadPipe,
837
+ KUSB_FNID_IsoWritePipe,
838
+ KUSB_FNID_GetCurrentFrameNumber,
839
+ KUSB_FNID_GetOverlappedResult,
840
+ KUSB_FNID_GetProperty,
841
+ KUSB_FNID_COUNT,
842
+ } KUSB_FNID;
843
+
844
+ typedef struct _KLIB_VERSION {
845
+ INT Major;
846
+ INT Minor;
847
+ INT Micro;
848
+ INT Nano;
849
+ } KLIB_VERSION;
850
+ typedef KLIB_VERSION* PKLIB_VERSION;
851
+
852
+ typedef BOOL (WINAPI *LibK_GetProcAddress_t)(
853
+ PVOID* ProcAddress,
854
+ ULONG DriverID,
855
+ ULONG FunctionID
856
+ );
857
+
858
+ typedef VOID (WINAPI *LibK_GetVersion_t)(
859
+ PKLIB_VERSION Version
860
+ );
861
+
862
+ struct winusb_interface {
863
+ bool initialized;
864
+ WinUsb_AbortPipe_t AbortPipe;
865
+ WinUsb_ControlTransfer_t ControlTransfer;
866
+ WinUsb_FlushPipe_t FlushPipe;
867
+ WinUsb_Free_t Free;
868
+ WinUsb_GetAssociatedInterface_t GetAssociatedInterface;
869
+ WinUsb_GetCurrentAlternateSetting_t GetCurrentAlternateSetting;
870
+ WinUsb_GetDescriptor_t GetDescriptor;
871
+ WinUsb_GetOverlappedResult_t GetOverlappedResult;
872
+ WinUsb_GetPipePolicy_t GetPipePolicy;
873
+ WinUsb_GetPowerPolicy_t GetPowerPolicy;
874
+ WinUsb_Initialize_t Initialize;
875
+ WinUsb_QueryDeviceInformation_t QueryDeviceInformation;
876
+ WinUsb_QueryInterfaceSettings_t QueryInterfaceSettings;
877
+ WinUsb_QueryPipe_t QueryPipe;
878
+ WinUsb_ReadPipe_t ReadPipe;
879
+ WinUsb_ResetPipe_t ResetPipe;
880
+ WinUsb_SetCurrentAlternateSetting_t SetCurrentAlternateSetting;
881
+ WinUsb_SetPipePolicy_t SetPipePolicy;
882
+ WinUsb_SetPowerPolicy_t SetPowerPolicy;
883
+ WinUsb_WritePipe_t WritePipe;
884
+ WinUsb_ResetDevice_t ResetDevice;
885
+ };
886
+
887
+ /* hid.dll interface */
888
+
889
+ #define HIDP_STATUS_SUCCESS 0x110000
890
+ typedef void* PHIDP_PREPARSED_DATA;
891
+
892
+ #pragma pack(1)
893
+ typedef struct {
894
+ ULONG Size;
895
+ USHORT VendorID;
896
+ USHORT ProductID;
897
+ USHORT VersionNumber;
898
+ } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
899
+ #pragma pack()
900
+
901
+ typedef USHORT USAGE;
902
+ typedef struct {
903
+ USAGE Usage;
904
+ USAGE UsagePage;
905
+ USHORT InputReportByteLength;
906
+ USHORT OutputReportByteLength;
907
+ USHORT FeatureReportByteLength;
908
+ USHORT Reserved[17];
909
+ USHORT NumberLinkCollectionNodes;
910
+ USHORT NumberInputButtonCaps;
911
+ USHORT NumberInputValueCaps;
912
+ USHORT NumberInputDataIndices;
913
+ USHORT NumberOutputButtonCaps;
914
+ USHORT NumberOutputValueCaps;
915
+ USHORT NumberOutputDataIndices;
916
+ USHORT NumberFeatureButtonCaps;
917
+ USHORT NumberFeatureValueCaps;
918
+ USHORT NumberFeatureDataIndices;
919
+ } HIDP_CAPS, *PHIDP_CAPS;
920
+
921
+ typedef enum _HIDP_REPORT_TYPE {
922
+ HidP_Input,
923
+ HidP_Output,
924
+ HidP_Feature
925
+ } HIDP_REPORT_TYPE;
926
+
927
+ typedef struct _HIDP_VALUE_CAPS {
928
+ USAGE UsagePage;
929
+ UCHAR ReportID;
930
+ BOOLEAN IsAlias;
931
+ USHORT BitField;
932
+ USHORT LinkCollection;
933
+ USAGE LinkUsage;
934
+ USAGE LinkUsagePage;
935
+ BOOLEAN IsRange;
936
+ BOOLEAN IsStringRange;
937
+ BOOLEAN IsDesignatorRange;
938
+ BOOLEAN IsAbsolute;
939
+ BOOLEAN HasNull;
940
+ UCHAR Reserved;
941
+ USHORT BitSize;
942
+ USHORT ReportCount;
943
+ USHORT Reserved2[5];
944
+ ULONG UnitsExp;
945
+ ULONG Units;
946
+ LONG LogicalMin, LogicalMax;
947
+ LONG PhysicalMin, PhysicalMax;
948
+ union {
949
+ struct {
950
+ USAGE UsageMin, UsageMax;
951
+ USHORT StringMin, StringMax;
952
+ USHORT DesignatorMin, DesignatorMax;
953
+ USHORT DataIndexMin, DataIndexMax;
954
+ } Range;
955
+ struct {
956
+ USAGE Usage, Reserved1;
957
+ USHORT StringIndex, Reserved2;
958
+ USHORT DesignatorIndex, Reserved3;
959
+ USHORT DataIndex, Reserved4;
960
+ } NotRange;
961
+ } u;
962
+ } HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
963
+
964
+ DLL_DECLARE(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
965
+ DLL_DECLARE(WINAPI, VOID, HidD_GetHidGuid, (LPGUID));
966
+ DLL_DECLARE(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *));
967
+ DLL_DECLARE(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA));
968
+ DLL_DECLARE(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG));
969
+ DLL_DECLARE(WINAPI, BOOL, HidD_GetProductString, (HANDLE, PVOID, ULONG));
970
+ DLL_DECLARE(WINAPI, BOOL, HidD_GetSerialNumberString, (HANDLE, PVOID, ULONG));
971
+ DLL_DECLARE(WINAPI, LONG, HidP_GetCaps, (PHIDP_PREPARSED_DATA, PHIDP_CAPS));
972
+ DLL_DECLARE(WINAPI, BOOL, HidD_SetNumInputBuffers, (HANDLE, ULONG));
973
+ DLL_DECLARE(WINAPI, BOOL, HidD_SetFeature, (HANDLE, PVOID, ULONG));
974
+ DLL_DECLARE(WINAPI, BOOL, HidD_GetFeature, (HANDLE, PVOID, ULONG));
975
+ DLL_DECLARE(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG));
976
+ DLL_DECLARE(WINAPI, BOOL, HidD_GetInputReport, (HANDLE, PVOID, ULONG));
977
+ DLL_DECLARE(WINAPI, BOOL, HidD_SetOutputReport, (HANDLE, PVOID, ULONG));
978
+ DLL_DECLARE(WINAPI, BOOL, HidD_FlushQueue, (HANDLE));
979
+ DLL_DECLARE(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA));