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