windows_common.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. * Windows backend common header for libusb 1.0
  3. *
  4. * This file brings together header code common between
  5. * the desktop Windows backends.
  6. * Copyright © 2012-2013 RealVNC Ltd.
  7. * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
  8. * Copyright © 2014-2020 Chris Dickens <christopher.a.dickens@gmail.com>
  9. * With contributions from Michael Plante, Orin Eman et al.
  10. * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
  11. * Major code testing contribution by Xiaofan Chen
  12. *
  13. * This library is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU Lesser General Public
  15. * License as published by the Free Software Foundation; either
  16. * version 2.1 of the License, or (at your option) any later version.
  17. *
  18. * This library is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21. * Lesser General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Lesser General Public
  24. * License along with this library; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. */
  27. #ifndef LIBUSB_WINDOWS_COMMON_H
  28. #define LIBUSB_WINDOWS_COMMON_H
  29. #include <stdbool.h>
  30. /*
  31. * Workaround for the mess that exists with the DWORD and ULONG types.
  32. * Visual Studio unconditionally defines these types as 'unsigned long'
  33. * and a long is always 32-bits, even on 64-bit builds. GCC on the other
  34. * hand varies the width of a long, matching it to the build. To make
  35. * matters worse, the platform headers for these GCC builds define a
  36. * DWORD/ULONG to be 'unsigned long' on 32-bit builds and 'unsigned int'
  37. * on 64-bit builds. This creates a great deal of warnings for compilers
  38. * that support printf format checking since it will never actually be
  39. * an unsigned long.
  40. */
  41. #if defined(_MSC_VER)
  42. #define ULONG_CAST(x) (x)
  43. #else
  44. #define ULONG_CAST(x) ((unsigned long)(x))
  45. #endif
  46. #if defined(__CYGWIN__)
  47. #define _stricmp strcasecmp
  48. #define _strdup strdup
  49. // _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
  50. #define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, (LPDWORD)f)
  51. #else
  52. #include <process.h>
  53. #endif
  54. #define safe_free(p) do {if (p != NULL) {free((void *)p); p = NULL;}} while (0)
  55. /*
  56. * API macros - leveraged from libusb-win32 1.x
  57. */
  58. #define DLL_STRINGIFY(s) #s
  59. /*
  60. * Macros for handling DLL themselves
  61. */
  62. #define DLL_HANDLE_NAME(name) __dll_##name##_handle
  63. #define DLL_DECLARE_HANDLE(name) \
  64. static HMODULE DLL_HANDLE_NAME(name)
  65. #define DLL_GET_HANDLE(ctx, name) \
  66. do { \
  67. DLL_HANDLE_NAME(name) = load_system_library(ctx, \
  68. DLL_STRINGIFY(name)); \
  69. if (!DLL_HANDLE_NAME(name)) \
  70. return false; \
  71. } while (0)
  72. #define DLL_FREE_HANDLE(name) \
  73. do { \
  74. if (DLL_HANDLE_NAME(name)) { \
  75. FreeLibrary(DLL_HANDLE_NAME(name)); \
  76. DLL_HANDLE_NAME(name) = NULL; \
  77. } \
  78. } while (0)
  79. /*
  80. * Macros for handling functions within a DLL
  81. */
  82. #define DLL_FUNC_NAME(name) __dll_##name##_func_t
  83. #define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args) \
  84. typedef ret (api * DLL_FUNC_NAME(name))args; \
  85. static DLL_FUNC_NAME(name) prefixname
  86. #define DLL_DECLARE_FUNC(api, ret, name, args) \
  87. DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
  88. #define DLL_DECLARE_FUNC_PREFIXED(api, ret, prefix, name, args) \
  89. DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefix##name, name, args)
  90. #define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
  91. do { \
  92. HMODULE h = DLL_HANDLE_NAME(dll); \
  93. prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
  94. DLL_STRINGIFY(name)); \
  95. if (prefixname) \
  96. break; \
  97. prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
  98. DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
  99. if (prefixname) \
  100. break; \
  101. prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
  102. DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
  103. if (prefixname) \
  104. break; \
  105. if (ret_on_failure) \
  106. return false; \
  107. } while (0)
  108. #define DLL_LOAD_FUNC(dll, name, ret_on_failure) \
  109. DLL_LOAD_FUNC_PREFIXNAME(dll, name, name, ret_on_failure)
  110. #define DLL_LOAD_FUNC_PREFIXED(dll, prefix, name, ret_on_failure) \
  111. DLL_LOAD_FUNC_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
  112. // https://msdn.microsoft.com/en-us/library/windows/hardware/ff539136(v=vs.85).aspx
  113. #if !defined(USBD_SUCCESS)
  114. typedef LONG USBD_STATUS;
  115. #define USBD_SUCCESS(Status) ((USBD_STATUS)(Status) >= 0)
  116. #define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS)0xC0000030L)
  117. #define USBD_STATUS_TIMEOUT ((USBD_STATUS)0xC0006000L)
  118. #define USBD_STATUS_DEVICE_GONE ((USBD_STATUS)0xC0007000L)
  119. #define USBD_STATUS_CANCELED ((USBD_STATUS)0xC0010000L)
  120. #endif
  121. // error code added with Windows SDK 10.0.18362
  122. #ifndef ERROR_NO_SUCH_DEVICE
  123. #define ERROR_NO_SUCH_DEVICE 433L
  124. #endif
  125. /* Windows versions */
  126. enum windows_version {
  127. WINDOWS_UNDEFINED,
  128. WINDOWS_2000,
  129. WINDOWS_XP,
  130. WINDOWS_2003, // Also XP x64
  131. WINDOWS_VISTA,
  132. WINDOWS_7,
  133. WINDOWS_8,
  134. WINDOWS_8_1,
  135. WINDOWS_10,
  136. WINDOWS_11,
  137. WINDOWS_12_OR_LATER
  138. };
  139. extern enum windows_version windows_version;
  140. #include <pshpack1.h>
  141. typedef struct USB_DEVICE_DESCRIPTOR {
  142. UCHAR bLength;
  143. UCHAR bDescriptorType;
  144. USHORT bcdUSB;
  145. UCHAR bDeviceClass;
  146. UCHAR bDeviceSubClass;
  147. UCHAR bDeviceProtocol;
  148. UCHAR bMaxPacketSize0;
  149. USHORT idVendor;
  150. USHORT idProduct;
  151. USHORT bcdDevice;
  152. UCHAR iManufacturer;
  153. UCHAR iProduct;
  154. UCHAR iSerialNumber;
  155. UCHAR bNumConfigurations;
  156. } USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
  157. typedef struct USB_CONFIGURATION_DESCRIPTOR {
  158. UCHAR bLength;
  159. UCHAR bDescriptorType;
  160. USHORT wTotalLength;
  161. UCHAR bNumInterfaces;
  162. UCHAR bConfigurationValue;
  163. UCHAR iConfiguration;
  164. UCHAR bmAttributes;
  165. UCHAR MaxPower;
  166. } USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
  167. #include <poppack.h>
  168. #define MAX_DEVICE_ID_LEN 200
  169. typedef struct USB_DK_DEVICE_ID {
  170. WCHAR DeviceID[MAX_DEVICE_ID_LEN];
  171. WCHAR InstanceID[MAX_DEVICE_ID_LEN];
  172. } USB_DK_DEVICE_ID, *PUSB_DK_DEVICE_ID;
  173. typedef struct USB_DK_DEVICE_INFO {
  174. USB_DK_DEVICE_ID ID;
  175. ULONG64 FilterID;
  176. ULONG64 Port;
  177. ULONG64 Speed;
  178. USB_DEVICE_DESCRIPTOR DeviceDescriptor;
  179. } USB_DK_DEVICE_INFO, *PUSB_DK_DEVICE_INFO;
  180. typedef struct USB_DK_ISO_TRANSFER_RESULT {
  181. ULONG64 ActualLength;
  182. ULONG64 TransferResult;
  183. } USB_DK_ISO_TRANSFER_RESULT, *PUSB_DK_ISO_TRANSFER_RESULT;
  184. typedef struct USB_DK_GEN_TRANSFER_RESULT {
  185. ULONG64 BytesTransferred;
  186. ULONG64 UsbdStatus; // USBD_STATUS code
  187. } USB_DK_GEN_TRANSFER_RESULT, *PUSB_DK_GEN_TRANSFER_RESULT;
  188. typedef struct USB_DK_TRANSFER_RESULT {
  189. USB_DK_GEN_TRANSFER_RESULT GenResult;
  190. PVOID64 IsochronousResultsArray; // array of USB_DK_ISO_TRANSFER_RESULT
  191. } USB_DK_TRANSFER_RESULT, *PUSB_DK_TRANSFER_RESULT;
  192. typedef struct USB_DK_TRANSFER_REQUEST {
  193. ULONG64 EndpointAddress;
  194. PVOID64 Buffer;
  195. ULONG64 BufferLength;
  196. ULONG64 TransferType;
  197. ULONG64 IsochronousPacketsArraySize;
  198. PVOID64 IsochronousPacketsArray;
  199. USB_DK_TRANSFER_RESULT Result;
  200. } USB_DK_TRANSFER_REQUEST, *PUSB_DK_TRANSFER_REQUEST;
  201. struct usbdk_device_priv {
  202. USB_DK_DEVICE_ID ID;
  203. PUSB_CONFIGURATION_DESCRIPTOR *config_descriptors;
  204. HANDLE redirector_handle;
  205. HANDLE system_handle;
  206. uint8_t active_configuration;
  207. };
  208. struct winusb_device_priv {
  209. bool initialized;
  210. bool root_hub;
  211. uint8_t active_config;
  212. uint8_t depth; // distance to HCD
  213. const struct windows_usb_api_backend *apib;
  214. char *dev_id;
  215. char *path; // device interface path
  216. int sub_api; // for WinUSB-like APIs
  217. struct {
  218. char *path; // each interface needs a device interface path,
  219. const struct windows_usb_api_backend *apib; // an API backend (multiple drivers support),
  220. int sub_api;
  221. int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
  222. uint8_t *endpoint;
  223. int current_altsetting;
  224. bool restricted_functionality; // indicates if the interface functionality is restricted
  225. // by Windows (eg. HID keyboards or mice cannot do R/W)
  226. } usb_interface[USB_MAXINTERFACES];
  227. struct hid_device_priv *hid;
  228. PUSB_CONFIGURATION_DESCRIPTOR *config_descriptor; // list of pointers to the cached config descriptors
  229. GUID class_guid; // checked for change during re-enumeration
  230. };
  231. struct usbdk_device_handle_priv {
  232. // Not currently used
  233. char dummy;
  234. };
  235. enum WINUSB_ZLP {
  236. WINUSB_ZLP_UNSET = 0,
  237. WINUSB_ZLP_OFF = 1,
  238. WINUSB_ZLP_ON = 2
  239. };
  240. struct winusb_device_handle_priv {
  241. int active_interface;
  242. struct {
  243. HANDLE dev_handle; // WinUSB needs an extra handle for the file
  244. HANDLE api_handle; // used by the API to communicate with the device
  245. uint8_t zlp[USB_MAXENDPOINTS]; // Current per-endpoint SHORT_PACKET_TERMINATE status (enum WINUSB_ZLP)
  246. } interface_handle[USB_MAXINTERFACES];
  247. int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
  248. };
  249. struct usbdk_transfer_priv {
  250. USB_DK_TRANSFER_REQUEST request;
  251. PULONG64 IsochronousPacketsArray;
  252. PUSB_DK_ISO_TRANSFER_RESULT IsochronousResultsArray;
  253. };
  254. struct winusb_transfer_priv {
  255. uint8_t interface_number;
  256. uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
  257. uint8_t *hid_dest; // transfer buffer destination, required for HID
  258. size_t hid_expected_size;
  259. // For isochronous transfers with LibUSBk driver:
  260. void *iso_context;
  261. // For isochronous transfers with Microsoft WinUSB driver:
  262. void *isoch_buffer_handle; // The isoch_buffer_handle to free at the end of the transfer
  263. BOOL iso_break_stream; // Whether the isoch. stream was to be continued in the last call of libusb_submit_transfer.
  264. // As we this structure is zeroed out upon initialization, we need to use inverse logic here.
  265. libusb_transfer_cb_fn iso_user_callback; // Original transfer callback of the user. Might be used for isochronous transfers.
  266. };
  267. struct windows_backend {
  268. int (*init)(struct libusb_context *ctx);
  269. void (*exit)(struct libusb_context *ctx);
  270. int (*get_device_list)(struct libusb_context *ctx,
  271. struct discovered_devs **discdevs);
  272. int (*open)(struct libusb_device_handle *dev_handle);
  273. void (*close)(struct libusb_device_handle *dev_handle);
  274. int (*get_active_config_descriptor)(struct libusb_device *device,
  275. void *buffer, size_t len);
  276. int (*get_config_descriptor)(struct libusb_device *device,
  277. uint8_t config_index, void *buffer, size_t len);
  278. int (*get_config_descriptor_by_value)(struct libusb_device *device,
  279. uint8_t bConfigurationValue, void **buffer);
  280. int (*get_configuration)(struct libusb_device_handle *dev_handle, uint8_t *config);
  281. int (*set_configuration)(struct libusb_device_handle *dev_handle, uint8_t config);
  282. int (*claim_interface)(struct libusb_device_handle *dev_handle, uint8_t interface_number);
  283. int (*release_interface)(struct libusb_device_handle *dev_handle, uint8_t interface_number);
  284. int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle,
  285. uint8_t interface_number, uint8_t altsetting);
  286. int (*clear_halt)(struct libusb_device_handle *dev_handle,
  287. unsigned char endpoint);
  288. int (*reset_device)(struct libusb_device_handle *dev_handle);
  289. void (*destroy_device)(struct libusb_device *dev);
  290. int (*submit_transfer)(struct usbi_transfer *itransfer);
  291. int (*cancel_transfer)(struct usbi_transfer *itransfer);
  292. void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
  293. enum libusb_transfer_status (*copy_transfer_data)(struct usbi_transfer *itransfer, DWORD length);
  294. };
  295. struct windows_context_priv {
  296. const struct windows_backend *backend;
  297. HANDLE completion_port;
  298. HANDLE completion_port_thread;
  299. };
  300. union windows_device_priv {
  301. struct usbdk_device_priv usbdk_priv;
  302. struct winusb_device_priv winusb_priv;
  303. };
  304. struct windows_device_handle_priv {
  305. struct list_head active_transfers;
  306. union {
  307. struct usbdk_device_handle_priv usbdk_priv;
  308. struct winusb_device_handle_priv winusb_priv;
  309. };
  310. };
  311. struct windows_transfer_priv {
  312. OVERLAPPED overlapped;
  313. HANDLE handle;
  314. struct list_head list;
  315. union {
  316. struct usbdk_transfer_priv usbdk_priv;
  317. struct winusb_transfer_priv winusb_priv;
  318. };
  319. };
  320. static inline struct usbdk_device_handle_priv *get_usbdk_device_handle_priv(struct libusb_device_handle *dev_handle)
  321. {
  322. struct windows_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
  323. return &handle_priv->usbdk_priv;
  324. }
  325. static inline struct winusb_device_handle_priv *get_winusb_device_handle_priv(struct libusb_device_handle *dev_handle)
  326. {
  327. struct windows_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
  328. return &handle_priv->winusb_priv;
  329. }
  330. static inline OVERLAPPED *get_transfer_priv_overlapped(struct usbi_transfer *itransfer)
  331. {
  332. struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
  333. return &transfer_priv->overlapped;
  334. }
  335. static inline void set_transfer_priv_handle(struct usbi_transfer *itransfer, HANDLE handle)
  336. {
  337. struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
  338. transfer_priv->handle = handle;
  339. }
  340. static inline struct usbdk_transfer_priv *get_usbdk_transfer_priv(struct usbi_transfer *itransfer)
  341. {
  342. struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
  343. return &transfer_priv->usbdk_priv;
  344. }
  345. static inline struct winusb_transfer_priv *get_winusb_transfer_priv(struct usbi_transfer *itransfer)
  346. {
  347. struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
  348. return &transfer_priv->winusb_priv;
  349. }
  350. extern const struct windows_backend usbdk_backend;
  351. extern const struct windows_backend winusb_backend;
  352. HMODULE load_system_library(struct libusb_context *ctx, const char *name);
  353. unsigned long htab_hash(const char *str);
  354. enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS status);
  355. void windows_force_sync_completion(struct usbi_transfer *itransfer, ULONG size);
  356. #if defined(ENABLE_LOGGING)
  357. const char *windows_error_str(DWORD error_code);
  358. #endif
  359. #endif