1 /* 2 * Windows backend for libusb 1.0 3 * Copyright (C) 2009-2010 Pete Batard <pbatard (at) gmail.com> 4 * With contributions from Michael Plante, Orin Eman et al. 5 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer 6 * Major code testing contribution by Xiaofan Chen 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #pragma once 24 25 #if defined(_MSC_VER) 26 // disable /W4 MSVC warnings that are benign 27 #pragma warning(disable:4127) // conditional expression is constant 28 #pragma warning(disable:4100) // unreferenced formal parameter 29 #pragma warning(disable:4214) // bit field types other than int 30 #pragma warning(disable:4201) // nameless struct/union 31 #endif 32 33 // Windows API default is uppercase - ugh! 34 #if !defined(bool) 35 #define bool BOOL 36 #endif 37 #if !defined(true) 38 #define true TRUE 39 #endif 40 #if !defined(false) 41 #define false FALSE 42 #endif 43 44 // Missing from MSVC6 setupapi.h 45 #if !defined(SPDRP_ADDRESS) 46 #define SPDRP_ADDRESS 28 47 #endif 48 #if !defined(SPDRP_INSTALL_STATE) 49 #define SPDRP_INSTALL_STATE 34 50 #endif 51 52 #if defined(__CYGWIN__ ) 53 // cygwin produces a warning unless these prototypes are defined 54 extern int _snprintf(char *buffer, size_t count, const char *format, ...); 55 extern char *_strdup(const char *strSource); 56 // _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread 57 #define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, f) 58 #endif 59 #define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0) 60 #define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0) 61 #define safe_min(a, b) min((size_t)(a), (size_t)(b)) 62 #define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \ 63 ((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0) 64 #define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1) 65 #define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1)) 66 #define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1) 67 #define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2)) 68 #define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count) 69 #define safe_strlen(str) ((str==NULL)?0:strlen(str)) 70 #define safe_sprintf _snprintf 71 #define safe_unref_device(dev) do {if (dev != NULL) {libusb_unref_device(dev); dev = NULL;}} while(0) 72 #define wchar_to_utf8_ms(wstr, str, strlen) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, strlen, NULL, NULL) 73 static inline void upperize(char* str) { 74 size_t i; 75 if (str == NULL) return; 76 for (i=0; i<safe_strlen(str); i++) 77 str[i] = (char)toupper((int)str[i]); 78 } 79 80 #define MAX_CTRL_BUFFER_LENGTH 4096 81 #define MAX_USB_DEVICES 256 82 #define MAX_USB_STRING_LENGTH 128 83 #define MAX_GUID_STRING_LENGTH 40 84 #define MAX_PATH_LENGTH 128 85 #define MAX_KEY_LENGTH 256 86 #define MAX_TIMER_SEMAPHORES 128 87 #define TIMER_REQUEST_RETRY_MS 100 88 #define ERR_BUFFER_SIZE 256 89 #define LIST_SEPARATOR ';' 90 #define HTAB_SIZE 1021 91 92 // http://msdn.microsoft.com/en-us/library/ff545978.aspx 93 // http://msdn.microsoft.com/en-us/library/ff545972.aspx 94 // http://msdn.microsoft.com/en-us/library/ff545982.aspx 95 #if !defined(GUID_DEVINTERFACE_USB_HOST_CONTROLLER) 96 const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} }; 97 #endif 98 #if !defined(GUID_DEVINTERFACE_USB_DEVICE) 99 const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} }; 100 #endif 101 #if !defined(GUID_DEVINTERFACE_USB_HUB) 102 const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} }; 103 #endif 104 const GUID GUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; 105 106 107 /* 108 * Multiple USB API backend support 109 */ 110 #define USB_API_UNSUPPORTED 0 111 #define USB_API_HUB 1 112 #define USB_API_COMPOSITE 2 113 #define USB_API_WINUSB 3 114 #define USB_API_MAX 4 115 116 #define CLASS_GUID_UNSUPPORTED GUID_NULL 117 const GUID CLASS_GUID_LIBUSB_WINUSB = { 0x78A1C341, 0x4539, 0x11D3, {0xB8, 0x8D, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71} }; 118 const GUID CLASS_GUID_COMPOSITE = { 0x36FC9E60, 0xC465, 0x11cF, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} }; 119 120 struct windows_usb_api_backend { 121 const uint8_t id; 122 const char* designation; 123 const GUID *class_guid; // The Class GUID (for fallback in case the driver name cannot be read) 124 const char **driver_name_list; // Driver name, without .sys, e.g. "usbccgp" 125 const uint8_t nb_driver_names; 126 int (*init)(struct libusb_context *ctx); 127 int (*exit)(void); 128 int (*open)(struct libusb_device_handle *dev_handle); 129 void (*close)(struct libusb_device_handle *dev_handle); 130 int (*claim_interface)(struct libusb_device_handle *dev_handle, int iface); 131 int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle, int iface, int altsetting); 132 int (*release_interface)(struct libusb_device_handle *dev_handle, int iface); 133 int (*clear_halt)(struct libusb_device_handle *dev_handle, unsigned char endpoint); 134 int (*reset_device)(struct libusb_device_handle *dev_handle); 135 int (*submit_bulk_transfer)(struct usbi_transfer *itransfer); 136 int (*submit_iso_transfer)(struct usbi_transfer *itransfer); 137 int (*submit_control_transfer)(struct usbi_transfer *itransfer); 138 int (*abort_control)(struct usbi_transfer *itransfer); 139 int (*abort_transfers)(struct usbi_transfer *itransfer); 140 int (*copy_transfer_data)(struct usbi_transfer *itransfer, uint32_t io_size); 141 }; 142 143 extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX]; 144 145 #define PRINT_UNSUPPORTED_API(fname) \ 146 usbi_dbg("unsupported API call for '" \ 147 #fname "' (unrecognized device driver)"); \ 148 return LIBUSB_ERROR_NOT_SUPPORTED; 149 150 /* 151 * private structures definition 152 * with inline pseudo constructors/destructors 153 */ 154 typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; 155 struct windows_device_priv { 156 uint8_t depth; // distance to HCD 157 uint8_t port; // port number on the hub 158 struct libusb_device *parent_dev; // access to parent is required for usermode ops 159 char *path; // device interface path 160 struct windows_usb_api_backend const *apib; 161 struct { 162 char *path; // each interface needs a device interface path, 163 struct windows_usb_api_backend const *apib; // an API backend (multiple drivers support), 164 int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS) 165 uint8_t *endpoint; 166 } usb_interface[USB_MAXINTERFACES]; 167 uint8_t composite_api_flags; // composite devices require additional data 168 uint8_t active_config; 169 USB_DEVICE_DESCRIPTOR dev_descriptor; 170 unsigned char **config_descriptor; // list of pointers to the cached config descriptors 171 }; 172 173 static inline struct windows_device_priv *_device_priv(struct libusb_device *dev) { 174 return (struct windows_device_priv *)dev->os_priv; 175 } 176 177 static inline void windows_device_priv_init(libusb_device* dev) { 178 struct windows_device_priv* p = _device_priv(dev); 179 int i; 180 p->depth = 0; 181 p->port = 0; 182 p->parent_dev = NULL; 183 p->path = NULL; 184 p->apib = &usb_api_backend[USB_API_UNSUPPORTED]; 185 p->composite_api_flags = 0; 186 p->active_config = 0; 187 p->config_descriptor = NULL; 188 memset(&(p->dev_descriptor), 0, sizeof(USB_DEVICE_DESCRIPTOR)); 189 for (i=0; i<USB_MAXINTERFACES; i++) { 190 p->usb_interface[i].path = NULL; 191 p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED]; 192 p->usb_interface[i].nb_endpoints = 0; 193 p->usb_interface[i].endpoint = NULL; 194 } 195 } 196 197 static inline void windows_device_priv_release(libusb_device* dev) { 198 struct windows_device_priv* p = _device_priv(dev); 199 int i; 200 safe_free(p->path); 201 if ((dev->num_configurations > 0) && (p->config_descriptor != NULL)) { 202 for (i=0; i < dev->num_configurations; i++) 203 safe_free(p->config_descriptor[i]); 204 } 205 safe_free(p->config_descriptor); 206 for (i=0; i<USB_MAXINTERFACES; i++) { 207 safe_free(p->usb_interface[i].path); 208 safe_free(p->usb_interface[i].endpoint); 209 } 210 } 211 212 struct interface_handle_t { 213 HANDLE dev_handle; // WinUSB needs an extra handle for the file 214 HANDLE api_handle; // used by the API to communicate with the device 215 }; 216 217 struct windows_device_handle_priv { 218 int active_interface; 219 struct interface_handle_t interface_handle[USB_MAXINTERFACES]; 220 int autoclaim_count[USB_MAXINTERFACES]; // For auto-release 221 }; 222 223 static inline struct windows_device_handle_priv *_device_handle_priv( 224 struct libusb_device_handle *handle) 225 { 226 return (struct windows_device_handle_priv *) handle->os_priv; 227 } 228 229 // used for async polling functions 230 struct windows_transfer_priv { 231 struct winfd pollable_fd; 232 uint8_t interface_number; 233 }; 234 235 // used to match a device driver (including filter drivers) against a supported API 236 struct driver_lookup { 237 char list[MAX_KEY_LENGTH+1];// REG_MULTI_SZ list of services (driver) names 238 const DWORD reg_prop; // SPDRP registry key to use to retreive list 239 const char* designation; // internal designation (for debug output) 240 }; 241 242 /* 243 * API macros - from libusb-win32 1.x 244 */ 245 #define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \ 246 typedef ret (api * __dll_##name##_t)args; \ 247 static __dll_##name##_t prefixname = NULL 248 249 #define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \ 250 do { \ 251 HMODULE h = GetModuleHandleA(#dll); \ 252 if (!h) \ 253 h = LoadLibraryA(#dll); \ 254 if (!h) { \ 255 if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; }\ 256 else { break; } \ 257 } \ 258 prefixname = (__dll_##name##_t)GetProcAddress(h, #name); \ 259 if (prefixname) break; \ 260 prefixname = (__dll_##name##_t)GetProcAddress(h, #name "A"); \ 261 if (prefixname) break; \ 262 prefixname = (__dll_##name##_t)GetProcAddress(h, #name "W"); \ 263 if (prefixname) break; \ 264 if(ret_on_failure) \ 265 return LIBUSB_ERROR_NOT_FOUND; \ 266 } while(0) 267 268 #define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args) 269 #define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure) 270 #define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args) 271 #define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure) 272 273 /* OLE32 dependency */ 274 DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID)); 275 276 /* SetupAPI dependencies */ 277 DLL_DECLARE_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD)); 278 DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA)); 279 DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA, 280 const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA)); 281 DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, 282 PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA)); 283 DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO)); 284 DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM)); 285 DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO, 286 PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD)); 287 DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD)); 288 DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY)); 289 290 /* 291 * Windows DDK API definitions. Most of it copied from MinGW's includes 292 */ 293 typedef DWORD DEVNODE, DEVINST; 294 typedef DEVNODE *PDEVNODE, *PDEVINST; 295 typedef DWORD RETURN_TYPE; 296 typedef RETURN_TYPE CONFIGRET; 297 298 #define CR_SUCCESS 0x00000000 299 #define CR_NO_SUCH_DEVNODE 0x0000000D 300 301 #define USB_DEVICE_DESCRIPTOR_TYPE LIBUSB_DT_DEVICE 302 #define USB_CONFIGURATION_DESCRIPTOR_TYPE LIBUSB_DT_CONFIG 303 #define USB_STRING_DESCRIPTOR_TYPE LIBUSB_DT_STRING 304 #define USB_INTERFACE_DESCRIPTOR_TYPE LIBUSB_DT_INTERFACE 305 #define USB_ENDPOINT_DESCRIPTOR_TYPE LIBUSB_DT_ENDPOINT 306 307 #define USB_REQUEST_GET_STATUS LIBUSB_REQUEST_GET_STATUS 308 #define USB_REQUEST_CLEAR_FEATURE LIBUSB_REQUEST_CLEAR_FEATURE 309 #define USB_REQUEST_SET_FEATURE LIBUSB_REQUEST_SET_FEATURE 310 #define USB_REQUEST_SET_ADDRESS LIBUSB_REQUEST_SET_ADDRESS 311 #define USB_REQUEST_GET_DESCRIPTOR LIBUSB_REQUEST_GET_DESCRIPTOR 312 #define USB_REQUEST_SET_DESCRIPTOR LIBUSB_REQUEST_SET_DESCRIPTOR 313 #define USB_REQUEST_GET_CONFIGURATION LIBUSB_REQUEST_GET_CONFIGURATION 314 #define USB_REQUEST_SET_CONFIGURATION LIBUSB_REQUEST_SET_CONFIGURATION 315 #define USB_REQUEST_GET_INTERFACE LIBUSB_REQUEST_GET_INTERFACE 316 #define USB_REQUEST_SET_INTERFACE LIBUSB_REQUEST_SET_INTERFACE 317 #define USB_REQUEST_SYNC_FRAME LIBUSB_REQUEST_SYNCH_FRAME 318 319 #define USB_GET_NODE_INFORMATION 258 320 #define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260 321 #define USB_GET_NODE_CONNECTION_NAME 261 322 #define USB_GET_HUB_CAPABILITIES 271 323 #if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX) 324 #define USB_GET_NODE_CONNECTION_INFORMATION_EX 274 325 #endif 326 #if !defined(USB_GET_HUB_CAPABILITIES_EX) 327 #define USB_GET_HUB_CAPABILITIES_EX 276 328 #endif 329 330 #ifndef METHOD_BUFFERED 331 #define METHOD_BUFFERED 0 332 #endif 333 #ifndef FILE_ANY_ACCESS 334 #define FILE_ANY_ACCESS 0x00000000 335 #endif 336 #ifndef FILE_DEVICE_UNKNOWN 337 #define FILE_DEVICE_UNKNOWN 0x00000022 338 #endif 339 #ifndef FILE_DEVICE_USB 340 #define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN 341 #endif 342 343 #ifndef CTL_CODE 344 #define CTL_CODE(DeviceType, Function, Method, Access)( \ 345 ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) 346 #endif 347 348 typedef enum USB_CONNECTION_STATUS { 349 NoDeviceConnected, 350 DeviceConnected, 351 DeviceFailedEnumeration, 352 DeviceGeneralFailure, 353 DeviceCausedOvercurrent, 354 DeviceNotEnoughPower, 355 DeviceNotEnoughBandwidth, 356 DeviceHubNestedTooDeeply, 357 DeviceInLegacyHub 358 } USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS; 359 360 typedef enum USB_HUB_NODE { 361 UsbHub, 362 UsbMIParent 363 } USB_HUB_NODE; 364 365 /* Cfgmgr32.dll interface */ 366 DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG)); 367 DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG)); 368 DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG)); 369 DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG)); 370 371 #define IOCTL_USB_GET_HUB_CAPABILITIES_EX \ 372 CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS) 373 374 #define IOCTL_USB_GET_HUB_CAPABILITIES \ 375 CTL_CODE(FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES, METHOD_BUFFERED, FILE_ANY_ACCESS) 376 377 #define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \ 378 CTL_CODE(FILE_DEVICE_USB, USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, METHOD_BUFFERED, FILE_ANY_ACCESS) 379 380 #define IOCTL_USB_GET_ROOT_HUB_NAME \ 381 CTL_CODE(FILE_DEVICE_USB, HCD_GET_ROOT_HUB_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS) 382 383 #define IOCTL_USB_GET_NODE_INFORMATION \ 384 CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS) 385 386 #define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \ 387 CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS) 388 389 #define IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES \ 390 CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_ATTRIBUTES, METHOD_BUFFERED, FILE_ANY_ACCESS) 391 392 #define IOCTL_USB_GET_NODE_CONNECTION_NAME \ 393 CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS) 394 395 // Most of the structures below need to be packed 396 #pragma pack(push, 1) 397 398 typedef struct USB_INTERFACE_DESCRIPTOR { 399 UCHAR bLength; 400 UCHAR bDescriptorType; 401 UCHAR bInterfaceNumber; 402 UCHAR bAlternateSetting; 403 UCHAR bNumEndpoints; 404 UCHAR bInterfaceClass; 405 UCHAR bInterfaceSubClass; 406 UCHAR bInterfaceProtocol; 407 UCHAR iInterface; 408 } USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR; 409 410 typedef struct USB_CONFIGURATION_DESCRIPTOR { 411 UCHAR bLength; 412 UCHAR bDescriptorType; 413 USHORT wTotalLength; 414 UCHAR bNumInterfaces; 415 UCHAR bConfigurationValue; 416 UCHAR iConfiguration; 417 UCHAR bmAttributes; 418 UCHAR MaxPower; 419 } USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR; 420 421 typedef struct USB_CONFIGURATION_DESCRIPTOR_SHORT { 422 struct { 423 ULONG ConnectionIndex; 424 struct { 425 UCHAR bmRequest; 426 UCHAR bRequest; 427 USHORT wValue; 428 USHORT wIndex; 429 USHORT wLength; 430 } SetupPacket; 431 } req; 432 USB_CONFIGURATION_DESCRIPTOR data; 433 } USB_CONFIGURATION_DESCRIPTOR_SHORT; 434 435 typedef struct USB_ENDPOINT_DESCRIPTOR { 436 UCHAR bLength; 437 UCHAR bDescriptorType; 438 UCHAR bEndpointAddress; 439 UCHAR bmAttributes; 440 USHORT wMaxPacketSize; 441 UCHAR bInterval; 442 } USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR; 443 444 typedef struct USB_DESCRIPTOR_REQUEST { 445 ULONG ConnectionIndex; 446 struct { 447 UCHAR bmRequest; 448 UCHAR bRequest; 449 USHORT wValue; 450 USHORT wIndex; 451 USHORT wLength; 452 } SetupPacket; 453 // UCHAR Data[0]; 454 } USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST; 455 456 typedef struct USB_HUB_DESCRIPTOR { 457 UCHAR bDescriptorLength; 458 UCHAR bDescriptorType; 459 UCHAR bNumberOfPorts; 460 USHORT wHubCharacteristics; 461 UCHAR bPowerOnToPowerGood; 462 UCHAR bHubControlCurrent; 463 UCHAR bRemoveAndPowerMask[64]; 464 } USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR; 465 466 typedef struct USB_ROOT_HUB_NAME { 467 ULONG ActualLength; 468 WCHAR RootHubName[1]; 469 } USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME; 470 471 typedef struct USB_ROOT_HUB_NAME_FIXED { 472 ULONG ActualLength; 473 WCHAR RootHubName[MAX_PATH_LENGTH]; 474 } USB_ROOT_HUB_NAME_FIXED; 475 476 typedef struct USB_NODE_CONNECTION_NAME { 477 ULONG ConnectionIndex; 478 ULONG ActualLength; 479 WCHAR NodeName[1]; 480 } USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME; 481 482 typedef struct USB_NODE_CONNECTION_NAME_FIXED { 483 ULONG ConnectionIndex; 484 ULONG ActualLength; 485 WCHAR NodeName[MAX_PATH_LENGTH]; 486 } USB_NODE_CONNECTION_NAME_FIXED; 487 488 typedef struct USB_HUB_NAME_FIXED { 489 union { 490 USB_ROOT_HUB_NAME_FIXED root; 491 USB_NODE_CONNECTION_NAME_FIXED node; 492 } u; 493 } USB_HUB_NAME_FIXED; 494 495 typedef struct USB_HUB_INFORMATION { 496 USB_HUB_DESCRIPTOR HubDescriptor; 497 BOOLEAN HubIsBusPowered; 498 } USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION; 499 500 typedef struct USB_MI_PARENT_INFORMATION { 501 ULONG NumberOfInterfaces; 502 } USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION; 503 504 typedef struct USB_NODE_INFORMATION { 505 USB_HUB_NODE NodeType; 506 union { 507 USB_HUB_INFORMATION HubInformation; 508 USB_MI_PARENT_INFORMATION MiParentInformation; 509 } u; 510 } USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION; 511 512 typedef struct USB_PIPE_INFO { 513 USB_ENDPOINT_DESCRIPTOR EndpointDescriptor; 514 ULONG ScheduleOffset; 515 } USB_PIPE_INFO, *PUSB_PIPE_INFO; 516 517 typedef struct USB_NODE_CONNECTION_INFORMATION_EX { 518 ULONG ConnectionIndex; 519 USB_DEVICE_DESCRIPTOR DeviceDescriptor; 520 UCHAR CurrentConfigurationValue; 521 UCHAR Speed; 522 BOOLEAN DeviceIsHub; 523 USHORT DeviceAddress; 524 ULONG NumberOfOpenPipes; 525 USB_CONNECTION_STATUS ConnectionStatus; 526 // USB_PIPE_INFO PipeList[0]; 527 } USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX; 528 529 typedef struct USB_HUB_CAP_FLAGS { 530 ULONG HubIsHighSpeedCapable:1; 531 ULONG HubIsHighSpeed:1; 532 ULONG HubIsMultiTtCapable:1; 533 ULONG HubIsMultiTt:1; 534 ULONG HubIsRoot:1; 535 ULONG HubIsArmedWakeOnConnect:1; 536 ULONG ReservedMBZ:26; 537 } USB_HUB_CAP_FLAGS, *PUSB_HUB_CAP_FLAGS; 538 539 typedef struct USB_HUB_CAPABILITIES { 540 ULONG HubIs2xCapable : 1; 541 } USB_HUB_CAPABILITIES, *PUSB_HUB_CAPABILITIES; 542 543 typedef struct USB_HUB_CAPABILITIES_EX { 544 USB_HUB_CAP_FLAGS CapabilityFlags; 545 } USB_HUB_CAPABILITIES_EX, *PUSB_HUB_CAPABILITIES_EX; 546 547 #pragma pack(pop) 548 549 /* winusb.dll interface */ 550 551 #define SHORT_PACKET_TERMINATE 0x01 552 #define AUTO_CLEAR_STALL 0x02 553 #define PIPE_TRANSFER_TIMEOUT 0x03 554 #define IGNORE_SHORT_PACKETS 0x04 555 #define ALLOW_PARTIAL_READS 0x05 556 #define AUTO_FLUSH 0x06 557 #define RAW_IO 0x07 558 #define MAXIMUM_TRANSFER_SIZE 0x08 559 #define AUTO_SUSPEND 0x81 560 #define SUSPEND_DELAY 0x83 561 #define DEVICE_SPEED 0x01 562 #define LowSpeed 0x01 563 #define FullSpeed 0x02 564 #define HighSpeed 0x03 565 566 typedef enum USBD_PIPE_TYPE { 567 UsbdPipeTypeControl, 568 UsbdPipeTypeIsochronous, 569 UsbdPipeTypeBulk, 570 UsbdPipeTypeInterrupt 571 } USBD_PIPE_TYPE; 572 573 typedef struct { 574 USBD_PIPE_TYPE PipeType; 575 UCHAR PipeId; 576 USHORT MaximumPacketSize; 577 UCHAR Interval; 578 } WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION; 579 580 #pragma pack(1) 581 typedef struct { 582 UCHAR request_type; 583 UCHAR request; 584 USHORT value; 585 USHORT index; 586 USHORT length; 587 } WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET; 588 #pragma pack() 589 590 typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE; 591 592 DLL_DECLARE(WINAPI, BOOL, WinUsb_Initialize, (HANDLE, PWINUSB_INTERFACE_HANDLE)); 593 DLL_DECLARE(WINAPI, BOOL, WinUsb_Free, (WINUSB_INTERFACE_HANDLE)); 594 DLL_DECLARE(WINAPI, BOOL, WinUsb_GetAssociatedInterface, (WINUSB_INTERFACE_HANDLE, UCHAR, PWINUSB_INTERFACE_HANDLE)); 595 DLL_DECLARE(WINAPI, BOOL, WinUsb_GetDescriptor, (WINUSB_INTERFACE_HANDLE, UCHAR, UCHAR, USHORT, PUCHAR, ULONG, PULONG)); 596 DLL_DECLARE(WINAPI, BOOL, WinUsb_QueryInterfaceSettings, (WINUSB_INTERFACE_HANDLE, UCHAR, PUSB_INTERFACE_DESCRIPTOR)); 597 DLL_DECLARE(WINAPI, BOOL, WinUsb_QueryDeviceInformation, (WINUSB_INTERFACE_HANDLE, ULONG, PULONG, PVOID)); 598 DLL_DECLARE(WINAPI, BOOL, WinUsb_SetCurrentAlternateSetting, (WINUSB_INTERFACE_HANDLE, UCHAR)); 599 DLL_DECLARE(WINAPI, BOOL, WinUsb_GetCurrentAlternateSetting, (WINUSB_INTERFACE_HANDLE, PUCHAR)); 600 DLL_DECLARE(WINAPI, BOOL, WinUsb_QueryPipe, (WINUSB_INTERFACE_HANDLE, UCHAR, UCHAR, PWINUSB_PIPE_INFORMATION)); 601 DLL_DECLARE(WINAPI, BOOL, WinUsb_SetPipePolicy, (WINUSB_INTERFACE_HANDLE, UCHAR, ULONG, ULONG, PVOID)); 602 DLL_DECLARE(WINAPI, BOOL, WinUsb_GetPipePolicy, (WINUSB_INTERFACE_HANDLE, UCHAR, ULONG, PULONG, PVOID)); 603 DLL_DECLARE(WINAPI, BOOL, WinUsb_ReadPipe, (WINUSB_INTERFACE_HANDLE, UCHAR, PUCHAR, ULONG, PULONG, LPOVERLAPPED)); 604 DLL_DECLARE(WINAPI, BOOL, WinUsb_WritePipe, (WINUSB_INTERFACE_HANDLE, UCHAR, PUCHAR, ULONG, PULONG, LPOVERLAPPED)); 605 DLL_DECLARE(WINAPI, BOOL, WinUsb_ControlTransfer, (WINUSB_INTERFACE_HANDLE, WINUSB_SETUP_PACKET, PUCHAR, ULONG, PULONG, LPOVERLAPPED)); 606 DLL_DECLARE(WINAPI, BOOL, WinUsb_ResetPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); 607 DLL_DECLARE(WINAPI, BOOL, WinUsb_AbortPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); 608 DLL_DECLARE(WINAPI, BOOL, WinUsb_FlushPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); 609