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 #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