Home | History | Annotate | Download | only in os
      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 (at) 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 #if defined(__CYGWIN__ )
     41 #define _stricmp strcasecmp
     42 #define _snprintf snprintf
     43 #define _strdup strdup
     44 // _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
     45 #define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, (LPDWORD)f)
     46 #endif
     47 
     48 #define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
     49 #define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
     50 #define safe_min(a, b) MIN((size_t)(a), (size_t)(b))
     51 #define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
     52 	((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
     53 #define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
     54 #define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
     55 #define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
     56 #define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
     57 #define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
     58 #define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
     59 #define safe_strlen(str) ((str==NULL)?0:strlen(str))
     60 #define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0)
     61 #define safe_stprintf _sntprintf
     62 #define safe_tcslen(str) ((str==NULL)?0:_tcslen(str))
     63 #define safe_unref_device(dev) do {if (dev != NULL) {libusb_unref_device(dev); dev = NULL;}} while(0)
     64 #define wchar_to_utf8_ms(wstr, str, strlen) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, strlen, NULL, NULL)
     65 #ifndef ARRAYSIZE
     66 #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
     67 #endif
     68 
     69 #define ERR_BUFFER_SIZE	256
     70 
     71 
     72 /*
     73  * API macros - leveraged from libusb-win32 1.x
     74  */
     75 #ifndef _WIN32_WCE
     76 #define DLL_STRINGIFY(s) #s
     77 #define DLL_LOAD_LIBRARY(name) LoadLibraryA(DLL_STRINGIFY(name))
     78 #else
     79 #define DLL_STRINGIFY(s) L#s
     80 #define DLL_LOAD_LIBRARY(name) LoadLibrary(DLL_STRINGIFY(name))
     81 #endif
     82 
     83 /*
     84  * Macros for handling DLL themselves
     85  */
     86 #define DLL_DECLARE_HANDLE(name)				\
     87 	static HMODULE __dll_##name##_handle = NULL
     88 
     89 #define DLL_GET_HANDLE(name)					\
     90 	do {							\
     91 		__dll_##name##_handle = DLL_LOAD_LIBRARY(name);	\
     92 		if (!__dll_##name##_handle)			\
     93 			return LIBUSB_ERROR_OTHER;		\
     94 	} while (0)
     95 
     96 #define DLL_FREE_HANDLE(name)					\
     97 	do {							\
     98 		if (__dll_##name##_handle) {			\
     99 			FreeLibrary(__dll_##name##_handle);	\
    100 			__dll_##name##_handle = NULL;		\
    101 		}						\
    102 	} while(0)
    103 
    104 
    105 /*
    106  * Macros for handling functions within a DLL
    107  */
    108 #define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args)	\
    109 	typedef ret (api * __dll_##name##_func_t)args;			\
    110 	static __dll_##name##_func_t prefixname = NULL
    111 
    112 #define DLL_DECLARE_FUNC(api, ret, name, args)				\
    113 	DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
    114 #define DLL_DECLARE_FUNC_PREFIXED(api, ret, prefix, name, args)		\
    115 	DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefix##name, name, args)
    116 
    117 #define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure)	\
    118 	do {								\
    119 		HMODULE h = __dll_##dll##_handle;			\
    120 		prefixname = (__dll_##name##_func_t)GetProcAddress(h,	\
    121 				DLL_STRINGIFY(name));			\
    122 		if (prefixname)						\
    123 			break;						\
    124 		prefixname = (__dll_##name##_func_t)GetProcAddress(h,	\
    125 				DLL_STRINGIFY(name) DLL_STRINGIFY(A));	\
    126 		if (prefixname)						\
    127 			break;						\
    128 		prefixname = (__dll_##name##_func_t)GetProcAddress(h,	\
    129 				DLL_STRINGIFY(name) DLL_STRINGIFY(W));	\
    130 		if (prefixname)						\
    131 			break;						\
    132 		if (ret_on_failure)					\
    133 			return LIBUSB_ERROR_NOT_FOUND;			\
    134 	} while(0)
    135 
    136 #define DLL_LOAD_FUNC(dll, name, ret_on_failure)			\
    137 	DLL_LOAD_FUNC_PREFIXNAME(dll, name, name, ret_on_failure)
    138 #define DLL_LOAD_FUNC_PREFIXED(dll, prefix, name, ret_on_failure)	\
    139 	DLL_LOAD_FUNC_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
    140