1 /*
2  * Windows backend common header for libusb 1.0
3  *
4  * This file brings together header code common between
5  * the desktop Windows and Windows CE backends.
6  * Copyright © 2012-2013 RealVNC Ltd.
7  * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
8  * With contributions from Michael Plante, Orin Eman et al.
9  * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
10  * Major code testing contribution by Xiaofan Chen
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25  */
26 
27 #pragma once
28 
29 // Windows API default is uppercase - ugh!
30 #if !defined(bool)
31 #define bool BOOL
32 #endif
33 #if !defined(true)
34 #define true TRUE
35 #endif
36 #if !defined(false)
37 #define false FALSE
38 #endif
39 
40 #define EPOCH_TIME	UINT64_C(116444736000000000)	// 1970.01.01 00:00:000 in MS Filetime
41 
42 #if defined(__CYGWIN__ )
43 #define _stricmp strcasecmp
44 #define _strdup strdup
45 // _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
46 #define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, (LPDWORD)f)
47 #endif
48 
49 #define safe_free(p) do {if (p != NULL) {free((void *)p); p = NULL;}} while (0)
50 
51 #ifndef ARRAYSIZE
52 #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
53 #endif
54 
55 #define ERR_BUFFER_SIZE	256
56 
57 /*
58  * API macros - leveraged from libusb-win32 1.x
59  */
60 #ifndef _WIN32_WCE
61 #define DLL_STRINGIFY(s) #s
62 #define DLL_LOAD_LIBRARY(name) LoadLibraryA(DLL_STRINGIFY(name))
63 #else
64 #define DLL_STRINGIFY(s) L#s
65 #define DLL_LOAD_LIBRARY(name) LoadLibrary(DLL_STRINGIFY(name))
66 #endif
67 
68 /*
69  * Macros for handling DLL themselves
70  */
71 #define DLL_HANDLE_NAME(name) __dll_##name##_handle
72 
73 #define DLL_DECLARE_HANDLE(name)				\
74 	static HMODULE DLL_HANDLE_NAME(name) = NULL
75 
76 #define DLL_GET_HANDLE(name)					\
77 	do {							\
78 		DLL_HANDLE_NAME(name) = DLL_LOAD_LIBRARY(name);	\
79 		if (!DLL_HANDLE_NAME(name))			\
80 			return FALSE;				\
81 	} while (0)
82 
83 #define DLL_FREE_HANDLE(name)					\
84 	do {							\
85 		if (DLL_HANDLE_NAME(name)) {			\
86 			FreeLibrary(DLL_HANDLE_NAME(name));	\
87 			DLL_HANDLE_NAME(name) = NULL;		\
88 		}						\
89 	} while (0)
90 
91 
92 /*
93  * Macros for handling functions within a DLL
94  */
95 #define DLL_FUNC_NAME(name) __dll_##name##_func_t
96 
97 #define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args)	\
98 	typedef ret (api * DLL_FUNC_NAME(name))args;			\
99 	static DLL_FUNC_NAME(name) prefixname = NULL
100 
101 #define DLL_DECLARE_FUNC(api, ret, name, args)				\
102 	DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
103 #define DLL_DECLARE_FUNC_PREFIXED(api, ret, prefix, name, args)		\
104 	DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefix##name, name, args)
105 
106 #define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure)	\
107 	do {								\
108 		HMODULE h = DLL_HANDLE_NAME(dll);			\
109 		prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h,	\
110 				DLL_STRINGIFY(name));			\
111 		if (prefixname)						\
112 			break;						\
113 		prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h,	\
114 				DLL_STRINGIFY(name) DLL_STRINGIFY(A));	\
115 		if (prefixname)						\
116 			break;						\
117 		prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h,	\
118 				DLL_STRINGIFY(name) DLL_STRINGIFY(W));	\
119 		if (prefixname)						\
120 			break;						\
121 		if (ret_on_failure)					\
122 			return FALSE;					\
123 	} while (0)
124 
125 #define DLL_LOAD_FUNC(dll, name, ret_on_failure)			\
126 	DLL_LOAD_FUNC_PREFIXNAME(dll, name, name, ret_on_failure)
127 #define DLL_LOAD_FUNC_PREFIXED(dll, prefix, name, ret_on_failure)	\
128 	DLL_LOAD_FUNC_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
129