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