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