1 /*
2 * Windows backend for libusb 1.0
3 * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4 * With contributions from Michael Plante, Orin Eman et al.
5 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
6 * 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 #ifndef LIBUSB_WINDOWS_WINUSB_H
24 #define LIBUSB_WINDOWS_WINUSB_H
25
26 #include "windows_common.h"
27
28 #if defined(_MSC_VER)
29 // disable /W4 MSVC warnings that are benign
30 #pragma warning(disable:4214) // bit field types other than int
31 #endif
32
33 // Missing from MSVC6 setupapi.h
34 #ifndef SPDRP_ADDRESS
35 #define SPDRP_ADDRESS 28
36 #endif
37 #ifndef SPDRP_INSTALL_STATE
38 #define SPDRP_INSTALL_STATE 34
39 #endif
40
41 #define MAX_CTRL_BUFFER_LENGTH 4096
42 #define MAX_USB_STRING_LENGTH 128
43 #define MAX_HID_REPORT_SIZE 1024
44 #define MAX_HID_DESCRIPTOR_SIZE 256
45 #define MAX_GUID_STRING_LENGTH 40
46 #define MAX_PATH_LENGTH 256
47 #define MAX_KEY_LENGTH 256
48 #define LIST_SEPARATOR ';'
49
50 // Handle code for HID interface that have been claimed ("dibs")
51 #define INTERFACE_CLAIMED ((HANDLE)(intptr_t)0xD1B5)
52 // Additional return code for HID operations that completed synchronously
53 #define LIBUSB_COMPLETED (LIBUSB_SUCCESS + 1)
54
55 // http://msdn.microsoft.com/en-us/library/ff545978.aspx
56 // http://msdn.microsoft.com/en-us/library/ff545972.aspx
57 // http://msdn.microsoft.com/en-us/library/ff545982.aspx
58 #ifndef GUID_DEVINTERFACE_USB_HOST_CONTROLLER
59 const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = {0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27}};
60 #endif
61 #ifndef GUID_DEVINTERFACE_USB_DEVICE
62 const GUID GUID_DEVINTERFACE_USB_DEVICE = {0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}};
63 #endif
64 #ifndef GUID_DEVINTERFACE_USB_HUB
65 const GUID GUID_DEVINTERFACE_USB_HUB = {0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8}};
66 #endif
67 #ifndef GUID_DEVINTERFACE_LIBUSB0_FILTER
68 const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = {0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9}};
69 #endif
70
71 // The following define MUST be == sizeof(USB_DESCRIPTOR_REQUEST)
72 #define USB_DESCRIPTOR_REQUEST_SIZE 12U
73
74 /*
75 * Multiple USB API backend support
76 */
77 #define USB_API_UNSUPPORTED 0
78 #define USB_API_HUB 1
79 #define USB_API_COMPOSITE 2
80 #define USB_API_WINUSBX 3
81 #define USB_API_HID 4
82 #define USB_API_MAX 5
83
84 // Sub-APIs for WinUSB-like driver APIs (WinUSB, libusbK, libusb-win32 through the libusbK DLL)
85 // Must have the same values as the KUSB_DRVID enum from libusbk.h
86 #define SUB_API_NOTSET -1
87 #define SUB_API_LIBUSBK 0
88 #define SUB_API_LIBUSB0 1
89 #define SUB_API_WINUSB 2
90 #define SUB_API_MAX 3
91
92 struct windows_usb_api_backend {
93 const uint8_t id;
94 const char * const designation;
95 const char * const * const driver_name_list; // Driver name, without .sys, e.g. "usbccgp"
96 const uint8_t nb_driver_names;
97 bool (*init)(struct libusb_context *ctx);
98 void (*exit)(void);
99 int (*open)(int sub_api, struct libusb_device_handle *dev_handle);
100 void (*close)(int sub_api, struct libusb_device_handle *dev_handle);
101 int (*configure_endpoints)(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
102 int (*claim_interface)(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
103 int (*set_interface_altsetting)(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting);
104 int (*release_interface)(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface);
105 int (*clear_halt)(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
106 int (*reset_device)(int sub_api, struct libusb_device_handle *dev_handle);
107 int (*submit_bulk_transfer)(int sub_api, struct usbi_transfer *itransfer);
108 int (*submit_iso_transfer)(int sub_api, struct usbi_transfer *itransfer);
109 int (*submit_control_transfer)(int sub_api, struct usbi_transfer *itransfer);
110 int (*cancel_transfer)(int sub_api, struct usbi_transfer *itransfer);
111 enum libusb_transfer_status (*copy_transfer_data)(int sub_api, struct usbi_transfer *itransfer, DWORD length);
112 };
113
114 extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX];
115
116 #define PRINT_UNSUPPORTED_API(fname) \
117 usbi_dbg("unsupported API call for '%s' " \
118 "(unrecognized device driver)", #fname)
119
120 #define CHECK_SUPPORTED_API(apip, fname) \
121 do { \
122 if ((apip)->fname == NULL) { \
123 PRINT_UNSUPPORTED_API(fname); \
124 return LIBUSB_ERROR_NOT_SUPPORTED; \
125 } \
126 } while (0)
127
128 /*
129 * private structures definition
130 * with inline pseudo constructors/destructors
131 */
132
133 // TODO (v2+): move hid desc to libusb.h?
134 struct libusb_hid_descriptor {
135 uint8_t bLength;
136 uint8_t bDescriptorType;
137 uint16_t bcdHID;
138 uint8_t bCountryCode;
139 uint8_t bNumDescriptors;
140 uint8_t bClassDescriptorType;
141 uint16_t wClassDescriptorLength;
142 };
143
144 #define LIBUSB_DT_HID_SIZE 9
145 #define HID_MAX_CONFIG_DESC_SIZE (LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE \
146 + LIBUSB_DT_HID_SIZE + 2 * LIBUSB_DT_ENDPOINT_SIZE)
147 #define HID_MAX_REPORT_SIZE 1024
148 #define HID_IN_EP 0x81
149 #define HID_OUT_EP 0x02
150 #define LIBUSB_REQ_RECIPIENT(request_type) ((request_type) & 0x1F)
151 #define LIBUSB_REQ_TYPE(request_type) ((request_type) & (0x03 << 5))
152 #define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN)
153 #define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type))
154
155 #ifndef CTL_CODE
156 #define CTL_CODE(DeviceType, Function, Method, Access) \
157 (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
158 #endif
159
160 // The following are used for HID reports IOCTLs
161 #define HID_IN_CTL_CODE(id) \
162 CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS)
163 #define HID_OUT_CTL_CODE(id) \
164 CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
165
166 #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
167 #define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
168 #define IOCTL_HID_SET_FEATURE HID_IN_CTL_CODE(100)
169 #define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101)
170
171 enum libusb_hid_request_type {
172 HID_REQ_GET_REPORT = 0x01,
173 HID_REQ_GET_IDLE = 0x02,
174 HID_REQ_GET_PROTOCOL = 0x03,
175 HID_REQ_SET_REPORT = 0x09,
176 HID_REQ_SET_IDLE = 0x0A,
177 HID_REQ_SET_PROTOCOL = 0x0B
178 };
179
180 enum libusb_hid_report_type {
181 HID_REPORT_TYPE_INPUT = 0x01,
182 HID_REPORT_TYPE_OUTPUT = 0x02,
183 HID_REPORT_TYPE_FEATURE = 0x03
184 };
185
186 struct hid_device_priv {
187 uint16_t vid;
188 uint16_t pid;
189 uint8_t config;
190 uint8_t nb_interfaces;
191 bool uses_report_ids[3]; // input, ouptput, feature
192 uint16_t input_report_size;
193 uint16_t output_report_size;
194 uint16_t feature_report_size;
195 uint16_t usage;
196 uint16_t usagePage;
197 WCHAR string[3][MAX_USB_STRING_LENGTH];
198 uint8_t string_index[3]; // man, prod, ser
199 };
200
winusb_device_priv_init(struct libusb_device * dev)201 static inline struct winusb_device_priv *winusb_device_priv_init(struct libusb_device *dev)
202 {
203 struct winusb_device_priv *priv = usbi_get_device_priv(dev);
204 int i;
205
206 priv->apib = &usb_api_backend[USB_API_UNSUPPORTED];
207 priv->sub_api = SUB_API_NOTSET;
208 for (i = 0; i < USB_MAXINTERFACES; i++) {
209 priv->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED];
210 priv->usb_interface[i].sub_api = SUB_API_NOTSET;
211 }
212
213 return priv;
214 }
215
winusb_device_priv_release(struct libusb_device * dev)216 static inline void winusb_device_priv_release(struct libusb_device *dev)
217 {
218 struct winusb_device_priv *priv = usbi_get_device_priv(dev);
219 int i;
220
221 free(priv->dev_id);
222 free(priv->path);
223 if ((dev->device_descriptor.bNumConfigurations > 0) && (priv->config_descriptor != NULL)) {
224 for (i = 0; i < dev->device_descriptor.bNumConfigurations; i++) {
225 if (priv->config_descriptor[i] == NULL)
226 continue;
227 free((UCHAR *)priv->config_descriptor[i] - USB_DESCRIPTOR_REQUEST_SIZE);
228 }
229 }
230 free(priv->config_descriptor);
231 free(priv->hid);
232 for (i = 0; i < USB_MAXINTERFACES; i++) {
233 free(priv->usb_interface[i].path);
234 free(priv->usb_interface[i].endpoint);
235 }
236 }
237
238 // used to match a device driver (including filter drivers) against a supported API
239 struct driver_lookup {
240 char list[MAX_KEY_LENGTH + 1]; // REG_MULTI_SZ list of services (driver) names
241 const DWORD reg_prop; // SPDRP registry key to use to retrieve list
242 const char *designation; // internal designation (for debug output)
243 };
244
245 /*
246 * Windows DDK API definitions. Most of it copied from MinGW's includes
247 */
248 typedef DWORD DEVNODE, DEVINST;
249 typedef DEVNODE *PDEVNODE, *PDEVINST;
250 typedef DWORD RETURN_TYPE;
251 typedef RETURN_TYPE CONFIGRET;
252
253 #define CR_SUCCESS 0x00000000
254
255 /* Cfgmgr32 dependencies */
256 DLL_DECLARE_HANDLE(Cfgmgr32);
257 DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
258 DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
259
260 /* AdvAPI32 dependencies */
261 DLL_DECLARE_HANDLE(AdvAPI32);
262 DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
263 DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
264
265 /* OLE32 dependency */
266 DLL_DECLARE_HANDLE(OLE32);
267 DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, IIDFromString, (LPCOLESTR, LPIID));
268
269 /* SetupAPI dependencies */
270 DLL_DECLARE_HANDLE(SetupAPI);
271 DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (LPCGUID, PCSTR, HWND, DWORD));
272 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
273 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
274 LPCGUID, DWORD, PSP_DEVICE_INTERFACE_DATA));
275 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInstanceIdA, (HDEVINFO, PSP_DEVINFO_DATA,
276 PCSTR, DWORD, PDWORD));
277 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
278 PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA));
279 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
280 PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
281 DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
282 DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
283 DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD));
284
285
286 #ifndef USB_GET_NODE_INFORMATION
287 #define USB_GET_NODE_INFORMATION 258
288 #endif
289 #ifndef USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION
290 #define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
291 #endif
292 #ifndef USB_GET_NODE_CONNECTION_INFORMATION_EX
293 #define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
294 #endif
295 #ifndef USB_GET_NODE_CONNECTION_INFORMATION_EX_V2
296 #define USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 279
297 #endif
298
299 #ifndef FILE_DEVICE_USB
300 #define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
301 #endif
302
303 #define USB_CTL_CODE(id) \
304 CTL_CODE(FILE_DEVICE_USB, (id), METHOD_BUFFERED, FILE_ANY_ACCESS)
305
306 #define IOCTL_USB_GET_NODE_INFORMATION \
307 USB_CTL_CODE(USB_GET_NODE_INFORMATION)
308
309 #define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \
310 USB_CTL_CODE(USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION)
311
312 #define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
313 USB_CTL_CODE(USB_GET_NODE_CONNECTION_INFORMATION_EX)
314
315 #define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \
316 USB_CTL_CODE(USB_GET_NODE_CONNECTION_INFORMATION_EX_V2)
317
318 typedef enum _USB_CONNECTION_STATUS {
319 NoDeviceConnected,
320 DeviceConnected,
321 DeviceFailedEnumeration,
322 DeviceGeneralFailure,
323 DeviceCausedOvercurrent,
324 DeviceNotEnoughPower,
325 DeviceNotEnoughBandwidth,
326 DeviceHubNestedTooDeeply,
327 DeviceInLegacyHub,
328 DeviceEnumerating,
329 DeviceReset
330 } USB_CONNECTION_STATUS;
331
332 typedef enum _USB_DEVICE_SPEED {
333 UsbLowSpeed = 0,
334 UsbFullSpeed,
335 UsbHighSpeed,
336 UsbSuperSpeed,
337 UsbSuperSpeedPlus // Not in Microsoft headers
338 } USB_DEVICE_SPEED;
339
340 typedef enum _USB_HUB_NODE {
341 UsbHub,
342 UsbMIParent
343 } USB_HUB_NODE;
344
345 // Most of the structures below need to be packed
346 #include <pshpack1.h>
347
348 typedef struct _USB_HUB_DESCRIPTOR {
349 UCHAR bDescriptorLength;
350 UCHAR bDescriptorType;
351 UCHAR bNumberOfPorts;
352 USHORT wHubCharacteristics;
353 UCHAR bPowerOnToPowerGood;
354 UCHAR bHubControlCurrent;
355 UCHAR bRemoveAndPowerMask[64];
356 } USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
357
358 typedef struct _USB_HUB_INFORMATION {
359 USB_HUB_DESCRIPTOR HubDescriptor;
360 BOOLEAN HubIsBusPowered;
361 } USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;
362
363 typedef struct _USB_NODE_INFORMATION {
364 USB_HUB_NODE NodeType;
365 union {
366 USB_HUB_INFORMATION HubInformation;
367 // USB_MI_PARENT_INFORMATION MiParentInformation;
368 } u;
369 } USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;
370
371 typedef struct _USB_DESCRIPTOR_REQUEST {
372 ULONG ConnectionIndex;
373 struct {
374 UCHAR bmRequest;
375 UCHAR bRequest;
376 USHORT wValue;
377 USHORT wIndex;
378 USHORT wLength;
379 } SetupPacket;
380 // UCHAR Data[0];
381 } USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST;
382
383 typedef struct _USB_CONFIGURATION_DESCRIPTOR_SHORT {
384 USB_DESCRIPTOR_REQUEST req;
385 USB_CONFIGURATION_DESCRIPTOR desc;
386 } USB_CONFIGURATION_DESCRIPTOR_SHORT;
387
388 typedef struct USB_INTERFACE_DESCRIPTOR {
389 UCHAR bLength;
390 UCHAR bDescriptorType;
391 UCHAR bInterfaceNumber;
392 UCHAR bAlternateSetting;
393 UCHAR bNumEndpoints;
394 UCHAR bInterfaceClass;
395 UCHAR bInterfaceSubClass;
396 UCHAR bInterfaceProtocol;
397 UCHAR iInterface;
398 } USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
399
400 typedef struct _USB_NODE_CONNECTION_INFORMATION_EX {
401 ULONG ConnectionIndex;
402 USB_DEVICE_DESCRIPTOR DeviceDescriptor;
403 UCHAR CurrentConfigurationValue;
404 UCHAR Speed;
405 BOOLEAN DeviceIsHub;
406 USHORT DeviceAddress;
407 ULONG NumberOfOpenPipes;
408 USB_CONNECTION_STATUS ConnectionStatus;
409 // USB_PIPE_INFO PipeList[0];
410 } USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX;
411
412 typedef union _USB_PROTOCOLS {
413 ULONG ul;
414 struct {
415 ULONG Usb110:1;
416 ULONG Usb200:1;
417 ULONG Usb300:1;
418 ULONG ReservedMBZ:29;
419 };
420 } USB_PROTOCOLS, *PUSB_PROTOCOLS;
421
422 typedef union _USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS {
423 ULONG ul;
424 struct {
425 ULONG DeviceIsOperatingAtSuperSpeedOrHigher:1;
426 ULONG DeviceIsSuperSpeedCapableOrHigher:1;
427 ULONG DeviceIsOperatingAtSuperSpeedPlusOrHigher:1;
428 ULONG DeviceIsSuperSpeedPlusCapableOrHigher:1;
429 ULONG ReservedMBZ:28;
430 };
431 } USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS;
432
433 typedef struct _USB_NODE_CONNECTION_INFORMATION_EX_V2 {
434 ULONG ConnectionIndex;
435 ULONG Length;
436 USB_PROTOCOLS SupportedUsbProtocols;
437 USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
438 } USB_NODE_CONNECTION_INFORMATION_EX_V2, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2;
439
440 #include <poppack.h>
441
442 /* winusb.dll interface */
443
444 /* pipe policies */
445 #define SHORT_PACKET_TERMINATE 0x01
446 #define AUTO_CLEAR_STALL 0x02
447 #define PIPE_TRANSFER_TIMEOUT 0x03
448 #define IGNORE_SHORT_PACKETS 0x04
449 #define ALLOW_PARTIAL_READS 0x05
450 #define AUTO_FLUSH 0x06
451 #define RAW_IO 0x07
452 #define MAXIMUM_TRANSFER_SIZE 0x08
453 /* libusbK */
454 #define ISO_ALWAYS_START_ASAP 0x21
455
456 typedef struct _USBD_ISO_PACKET_DESCRIPTOR {
457 ULONG Offset;
458 ULONG Length;
459 USBD_STATUS Status;
460 } USBD_ISO_PACKET_DESCRIPTOR, *PUSBD_ISO_PACKET_DESCRIPTOR;
461
462 typedef enum _USBD_PIPE_TYPE {
463 UsbdPipeTypeControl,
464 UsbdPipeTypeIsochronous,
465 UsbdPipeTypeBulk,
466 UsbdPipeTypeInterrupt
467 } USBD_PIPE_TYPE;
468
469 typedef struct {
470 USBD_PIPE_TYPE PipeType;
471 UCHAR PipeId;
472 USHORT MaximumPacketSize;
473 UCHAR Interval;
474 ULONG MaximumBytesPerInterval;
475 } WINUSB_PIPE_INFORMATION_EX, *PWINUSB_PIPE_INFORMATION_EX;
476
477 #include <pshpack1.h>
478
479 typedef struct _WINUSB_SETUP_PACKET {
480 UCHAR RequestType;
481 UCHAR Request;
482 USHORT Value;
483 USHORT Index;
484 USHORT Length;
485 } WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET;
486
487 #include <poppack.h>
488
489 typedef PVOID WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE;
490 typedef PVOID WINUSB_ISOCH_BUFFER_HANDLE, *PWINUSB_ISOCH_BUFFER_HANDLE;
491
492 typedef BOOL (WINAPI *WinUsb_AbortPipe_t)(
493 WINUSB_INTERFACE_HANDLE InterfaceHandle,
494 UCHAR PipeID
495 );
496 typedef BOOL (WINAPI *WinUsb_ControlTransfer_t)(
497 WINUSB_INTERFACE_HANDLE InterfaceHandle,
498 WINUSB_SETUP_PACKET SetupPacket,
499 PUCHAR Buffer,
500 ULONG BufferLength,
501 PULONG LengthTransferred,
502 LPOVERLAPPED Overlapped
503 );
504 typedef BOOL (WINAPI *WinUsb_FlushPipe_t)(
505 WINUSB_INTERFACE_HANDLE InterfaceHandle,
506 UCHAR PipeID
507 );
508 typedef BOOL (WINAPI *WinUsb_Free_t)(
509 WINUSB_INTERFACE_HANDLE InterfaceHandle
510 );
511 typedef BOOL (WINAPI *WinUsb_GetAssociatedInterface_t)(
512 WINUSB_INTERFACE_HANDLE InterfaceHandle,
513 UCHAR AssociatedInterfaceIndex,
514 PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle
515 );
516 typedef BOOL (WINAPI *WinUsb_Initialize_t)(
517 HANDLE DeviceHandle,
518 PWINUSB_INTERFACE_HANDLE InterfaceHandle
519 );
520 typedef BOOL (WINAPI *WinUsb_QueryPipeEx_t)(
521 WINUSB_INTERFACE_HANDLE InterfaceHandle,
522 UCHAR AlternateInterfaceHandle,
523 UCHAR PipeIndex,
524 PWINUSB_PIPE_INFORMATION_EX PipeInformationEx
525 );
526 typedef BOOL (WINAPI *WinUsb_ReadIsochPipeAsap_t)(
527 PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
528 ULONG Offset,
529 ULONG Length,
530 BOOL ContinueStream,
531 ULONG NumberOfPackets,
532 PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors,
533 LPOVERLAPPED Overlapped
534 );
535 typedef BOOL (WINAPI *WinUsb_ReadPipe_t)(
536 WINUSB_INTERFACE_HANDLE InterfaceHandle,
537 UCHAR PipeID,
538 PUCHAR Buffer,
539 ULONG BufferLength,
540 PULONG LengthTransferred,
541 LPOVERLAPPED Overlapped
542 );
543 typedef BOOL (WINAPI *WinUsb_RegisterIsochBuffer_t)(
544 WINUSB_INTERFACE_HANDLE InterfaceHandle,
545 UCHAR PipeID,
546 PVOID Buffer,
547 ULONG BufferLength,
548 PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle
549 );
550 typedef BOOL (WINAPI *WinUsb_ResetPipe_t)(
551 WINUSB_INTERFACE_HANDLE InterfaceHandle,
552 UCHAR PipeID
553 );
554 typedef BOOL (WINAPI *WinUsb_SetCurrentAlternateSetting_t)(
555 WINUSB_INTERFACE_HANDLE InterfaceHandle,
556 UCHAR AlternateSetting
557 );
558 typedef BOOL (WINAPI *WinUsb_SetPipePolicy_t)(
559 WINUSB_INTERFACE_HANDLE InterfaceHandle,
560 UCHAR PipeID,
561 ULONG PolicyType,
562 ULONG ValueLength,
563 PVOID Value
564 );
565 typedef BOOL (WINAPI *WinUsb_UnregisterIsochBuffer_t)(
566 WINUSB_ISOCH_BUFFER_HANDLE BufferHandle
567 );
568 typedef BOOL (WINAPI *WinUsb_WriteIsochPipeAsap_t)(
569 WINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
570 ULONG Offset,
571 ULONG Length,
572 BOOL ContinueStream,
573 LPOVERLAPPED Overlapped
574 );
575 typedef BOOL (WINAPI *WinUsb_WritePipe_t)(
576 WINUSB_INTERFACE_HANDLE InterfaceHandle,
577 UCHAR PipeID,
578 PUCHAR Buffer,
579 ULONG BufferLength,
580 PULONG LengthTransferred,
581 LPOVERLAPPED Overlapped
582 );
583
584 /* /!\ These must match the ones from the official libusbk.h */
585 typedef enum _KUSB_FNID {
586 KUSB_FNID_Init,
587 KUSB_FNID_Free,
588 KUSB_FNID_ClaimInterface,
589 KUSB_FNID_ReleaseInterface,
590 KUSB_FNID_SetAltInterface,
591 KUSB_FNID_GetAltInterface,
592 KUSB_FNID_GetDescriptor,
593 KUSB_FNID_ControlTransfer,
594 KUSB_FNID_SetPowerPolicy,
595 KUSB_FNID_GetPowerPolicy,
596 KUSB_FNID_SetConfiguration,
597 KUSB_FNID_GetConfiguration,
598 KUSB_FNID_ResetDevice,
599 KUSB_FNID_Initialize,
600 KUSB_FNID_SelectInterface,
601 KUSB_FNID_GetAssociatedInterface,
602 KUSB_FNID_Clone,
603 KUSB_FNID_QueryInterfaceSettings,
604 KUSB_FNID_QueryDeviceInformation,
605 KUSB_FNID_SetCurrentAlternateSetting,
606 KUSB_FNID_GetCurrentAlternateSetting,
607 KUSB_FNID_QueryPipe,
608 KUSB_FNID_SetPipePolicy,
609 KUSB_FNID_GetPipePolicy,
610 KUSB_FNID_ReadPipe,
611 KUSB_FNID_WritePipe,
612 KUSB_FNID_ResetPipe,
613 KUSB_FNID_AbortPipe,
614 KUSB_FNID_FlushPipe,
615 KUSB_FNID_IsoReadPipe,
616 KUSB_FNID_IsoWritePipe,
617 KUSB_FNID_GetCurrentFrameNumber,
618 KUSB_FNID_GetOverlappedResult,
619 KUSB_FNID_GetProperty,
620 KUSB_FNID_COUNT,
621 } KUSB_FNID;
622
623 typedef struct _KLIB_VERSION {
624 INT Major;
625 INT Minor;
626 INT Micro;
627 INT Nano;
628 } KLIB_VERSION, *PKLIB_VERSION;
629
630 typedef BOOL (WINAPI *LibK_GetProcAddress_t)(
631 PVOID ProcAddress,
632 INT DriverID,
633 INT FunctionID
634 );
635
636 typedef VOID (WINAPI *LibK_GetVersion_t)(
637 PKLIB_VERSION Version
638 );
639
640 typedef BOOL (WINAPI *LibK_ResetDevice_t)(
641 WINUSB_INTERFACE_HANDLE InterfaceHandle
642 );
643
644 //KISO_PACKET is equivalent of libusb_iso_packet_descriptor except uses absolute "offset" field instead of sequential Lengths
645 typedef struct _KISO_PACKET {
646 UINT offset;
647 USHORT actual_length; //changed from libusbk_shared.h "Length" for clarity
648 USHORT status;
649 } KISO_PACKET, *PKISO_PACKET;
650
651 typedef enum _KISO_FLAG {
652 KISO_FLAG_NONE = 0,
653 KISO_FLAG_SET_START_FRAME = 0x00000001,
654 } KISO_FLAG;
655
656 //KISO_CONTEXT is the conceptual equivalent of libusb_transfer except is isochronous-specific and must match libusbk's version
657 typedef struct _KISO_CONTEXT {
658 KISO_FLAG Flags;
659 UINT StartFrame;
660 SHORT ErrorCount;
661 SHORT NumberOfPackets;
662 UINT UrbHdrStatus;
663 KISO_PACKET IsoPackets[0];
664 } KISO_CONTEXT, *PKISO_CONTEXT;
665
666 typedef BOOL(WINAPI *LibK_IsoReadPipe_t)(
667 WINUSB_INTERFACE_HANDLE InterfaceHandle,
668 UCHAR PipeID,
669 PUCHAR Buffer,
670 ULONG BufferLength,
671 LPOVERLAPPED Overlapped,
672 PKISO_CONTEXT IsoContext
673 );
674
675 typedef BOOL(WINAPI *LibK_IsoWritePipe_t)(
676 WINUSB_INTERFACE_HANDLE InterfaceHandle,
677 UCHAR PipeID,
678 PUCHAR Buffer,
679 ULONG BufferLength,
680 LPOVERLAPPED Overlapped,
681 PKISO_CONTEXT IsoContext
682 );
683
684 struct winusb_interface {
685 HMODULE hDll;
686 WinUsb_AbortPipe_t AbortPipe;
687 WinUsb_ControlTransfer_t ControlTransfer;
688 WinUsb_FlushPipe_t FlushPipe;
689 WinUsb_Free_t Free;
690 WinUsb_GetAssociatedInterface_t GetAssociatedInterface;
691 WinUsb_Initialize_t Initialize;
692 WinUsb_ReadPipe_t ReadPipe;
693 WinUsb_ResetPipe_t ResetPipe;
694 WinUsb_SetCurrentAlternateSetting_t SetCurrentAlternateSetting;
695 WinUsb_SetPipePolicy_t SetPipePolicy;
696 WinUsb_WritePipe_t WritePipe;
697 union {
698 struct {
699 // Isochoronous functions for libusbK sub api:
700 LibK_IsoReadPipe_t IsoReadPipe;
701 LibK_IsoWritePipe_t IsoWritePipe;
702 // Reset device function for libusbK sub api:
703 LibK_ResetDevice_t ResetDevice;
704 };
705 struct {
706 // Isochronous functions for WinUSB sub api:
707 WinUsb_QueryPipeEx_t QueryPipeEx;
708 WinUsb_ReadIsochPipeAsap_t ReadIsochPipeAsap;
709 WinUsb_RegisterIsochBuffer_t RegisterIsochBuffer;
710 WinUsb_UnregisterIsochBuffer_t UnregisterIsochBuffer;
711 WinUsb_WriteIsochPipeAsap_t WriteIsochPipeAsap;
712 };
713 };
714 };
715
716 /* hid.dll interface */
717
718 #define HIDP_STATUS_SUCCESS 0x110000
719 typedef void * PHIDP_PREPARSED_DATA;
720
721 #include <pshpack1.h>
722
723 typedef struct _HIDD_ATTIRBUTES {
724 ULONG Size;
725 USHORT VendorID;
726 USHORT ProductID;
727 USHORT VersionNumber;
728 } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
729
730 #include <poppack.h>
731
732 typedef USHORT USAGE;
733 typedef struct _HIDP_CAPS {
734 USAGE Usage;
735 USAGE UsagePage;
736 USHORT InputReportByteLength;
737 USHORT OutputReportByteLength;
738 USHORT FeatureReportByteLength;
739 USHORT Reserved[17];
740 USHORT NumberLinkCollectionNodes;
741 USHORT NumberInputButtonCaps;
742 USHORT NumberInputValueCaps;
743 USHORT NumberInputDataIndices;
744 USHORT NumberOutputButtonCaps;
745 USHORT NumberOutputValueCaps;
746 USHORT NumberOutputDataIndices;
747 USHORT NumberFeatureButtonCaps;
748 USHORT NumberFeatureValueCaps;
749 USHORT NumberFeatureDataIndices;
750 } HIDP_CAPS, *PHIDP_CAPS;
751
752 typedef enum _HIDP_REPORT_TYPE {
753 HidP_Input,
754 HidP_Output,
755 HidP_Feature
756 } HIDP_REPORT_TYPE;
757
758 typedef struct _HIDP_VALUE_CAPS {
759 USAGE UsagePage;
760 UCHAR ReportID;
761 BOOLEAN IsAlias;
762 USHORT BitField;
763 USHORT LinkCollection;
764 USAGE LinkUsage;
765 USAGE LinkUsagePage;
766 BOOLEAN IsRange;
767 BOOLEAN IsStringRange;
768 BOOLEAN IsDesignatorRange;
769 BOOLEAN IsAbsolute;
770 BOOLEAN HasNull;
771 UCHAR Reserved;
772 USHORT BitSize;
773 USHORT ReportCount;
774 USHORT Reserved2[5];
775 ULONG UnitsExp;
776 ULONG Units;
777 LONG LogicalMin, LogicalMax;
778 LONG PhysicalMin, PhysicalMax;
779 union {
780 struct {
781 USAGE UsageMin, UsageMax;
782 USHORT StringMin, StringMax;
783 USHORT DesignatorMin, DesignatorMax;
784 USHORT DataIndexMin, DataIndexMax;
785 } Range;
786 struct {
787 USAGE Usage, Reserved1;
788 USHORT StringIndex, Reserved2;
789 USHORT DesignatorIndex, Reserved3;
790 USHORT DataIndex, Reserved4;
791 } NotRange;
792 } u;
793 } HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
794
795 DLL_DECLARE_HANDLE(hid);
796 DLL_DECLARE_FUNC(WINAPI, VOID, HidD_GetHidGuid, (LPGUID));
797 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
798 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *));
799 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA));
800 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG));
801 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetProductString, (HANDLE, PVOID, ULONG));
802 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetSerialNumberString, (HANDLE, PVOID, ULONG));
803 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetIndexedString, (HANDLE, ULONG, PVOID, ULONG));
804 DLL_DECLARE_FUNC(WINAPI, LONG, HidP_GetCaps, (PHIDP_PREPARSED_DATA, PHIDP_CAPS));
805 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_SetNumInputBuffers, (HANDLE, ULONG));
806 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG));
807 DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_FlushQueue, (HANDLE));
808 DLL_DECLARE_FUNC(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA));
809
810 #endif
811