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