1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #define _UWINAPI_ 25 #include <systools/win32/uwinapi.h> 26 27 #ifndef _INC_MALLOC 28 # include <malloc.h> 29 #endif 30 31 #if defined(_MSC_VER) && (_MSC_VER >= 1400) 32 #pragma warning(disable:4740) 33 #endif 34 35 #ifndef _INC_TCHAR 36 # ifdef UNICODE 37 # define _UNICODE 38 # endif 39 # include <TCHAR.H> 40 #endif 41 42 // Globally disable "warning C4100: unreferenced formal parameter" caused by 43 // IMPLEMENT_THUNK: 44 #ifdef _MSC_VER 45 #pragma warning(disable:4100) 46 #endif 47 48 /* Version macros */ 49 50 #define MAKE_VER_WIN32( major, minor, build, isWindows ) \ 51 ((DWORD)MAKELONG( MAKEWORD( major, minor ), (build) | ( isWindows ? 0x8000 : 0 ) )) 52 53 #define MAKE_VER_WIN32_NT( major, minor, build ) \ 54 MAKE_VER_WIN32( major, minor, build, FALSE ) 55 56 #define MAKE_VER_WIN32_WINDOWS( major, minor, build ) \ 57 MAKE_VER_WIN32( major, minor, build, TRUE ) 58 59 #define VER_WIN32_WINDOWS_95 MAKE_VER_WIN32_WINDOWS( 4, 0, 0 ) 60 #define VER_WIN32_WINDOWS_98 MAKE_VER_WIN32_WINDOWS( 4, 10, 0 ) 61 #define VER_WIN32_WINDOWS_ME MAKE_VER_WIN32_WINDOWS( 4, 90, 0 ) 62 #define VER_WIN32_NT_NT4 MAKE_VER_WIN32_NT( 4, 0, 0 ) 63 #define VER_WIN32_NT_2000 MAKE_VER_WIN32_NT( 5, 0, 0 ) 64 #define VER_WIN32_NT_XP MAKE_VER_WIN32_NT( 5, 1, 0 ) 65 66 67 #ifdef __cplusplus 68 69 #define _AUTO_WSTR2STR( lpStrA, lpStrW ) \ 70 LPSTR lpStrA; \ 71 if ( lpStrW ) \ 72 { \ 73 int cNeeded = WideCharToMultiByte( CP_ACP, 0, lpStrW, -1, NULL, 0, NULL, NULL ); \ 74 lpStrA = (LPSTR)_alloca( cNeeded * sizeof(CHAR) ); \ 75 WideCharToMultiByte( CP_ACP, 0, lpStrW, -1, lpStrA, cNeeded, NULL, NULL ); \ 76 } \ 77 else \ 78 lpStrA = NULL; 79 80 81 #define AUTO_WSTR2STR( lpStr ) \ 82 _AUTO_WSTR2STR( lpStr##A, lpStr##W ) 83 84 #define AUTO_STR( lpStr, cchBuffer ) \ 85 LPSTR lpStr##A = lpStr##W ? (LPSTR)_alloca( (cchBuffer) * sizeof(CHAR) ) : NULL; 86 87 #endif /* __cplusplus */ 88 89 90 #define STRBUF2WSTR( lpStr, cchSrcBuffer, cchDestBuffer ) \ 91 MultiByteToWideChar( CP_ACP, 0, lpStr##A, cchSrcBuffer, lpStr##W, (int) cchDestBuffer ) 92 93 #define STR2WSTR( lpStr, cchBuffer ) \ 94 STRBUF2WSTR( lpStr, -1, cchBuffer ) 95 96 #define WSTR2STR( lpStr, cchBuffer ) \ 97 WideCharToMultiByte( CP_ACP, 0, lpStr##W, -1, lpStr##A, cchBuffer, NULL, NULL ) 98 99 EXTERN_C void WINAPI ResolveThunk_WINDOWS( FARPROC *lppfn, LPCSTR lpLibFileName, LPCSTR lpFuncName, FARPROC lpfnEmulate, FARPROC lpfnFailure ); 100 EXTERN_C void WINAPI ResolveThunk_TRYLOAD( FARPROC *lppfn, LPCSTR lpLibFileName, LPCSTR lpFuncName, FARPROC lpfnEmulate, FARPROC lpfnFailure ); 101 EXTERN_C void WINAPI ResolveThunk_ALLWAYS( FARPROC *lppfn, LPCSTR lpLibFileName, LPCSTR lpFuncName, FARPROC lpfnEmulate, FARPROC lpfnFailure ); 102 103 104 105 106 #ifdef __MINGW32__ 107 #define IMPLEMENT_THUNK( module, resolve, rettype, calltype, func, params ) \ 108 static void func##_Thunk(); \ 109 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr = (FARPROC)func##_Thunk; \ 110 EXTERN_C rettype calltype func params \ 111 { \ 112 asm(" popl %ebp"); \ 113 asm(" jmp *(%0)"::"m"(module##_##func##_Ptr)); \ 114 } \ 115 EXTERN_C rettype calltype func##_##resolve params; \ 116 static rettype calltype func##_##Failure params; \ 117 static void func##_Thunk() \ 118 { \ 119 ResolveThunk_##resolve( &module##_##func##_Ptr, #module ".dll", #func, (FARPROC)func##_##resolve, (FARPROC)func##_##Failure ); \ 120 asm(" movl %ebp, %esp"); \ 121 asm(" popl %ebp"); \ 122 asm(" jmp *(%0)"::"m"(module##_##func##_Ptr)); \ 123 } \ 124 static rettype calltype func##_##Failure params \ 125 { \ 126 SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); \ 127 return (rettype)0; \ 128 } \ 129 EXTERN_C rettype calltype func##_##resolve params 130 #else 131 #define IMPLEMENT_THUNK( module, resolve, rettype, calltype, func, params ) \ 132 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr; \ 133 EXTERN_C rettype calltype func##_##resolve params; \ 134 static rettype calltype func##_##Failure params; \ 135 static _declspec ( naked ) void func##_Thunk() \ 136 { \ 137 ResolveThunk_##resolve( &module##_##func##_Ptr, #module ".dll", #func, (FARPROC)func##_##resolve, (FARPROC)func##_##Failure ); \ 138 _asm jmp [module##_##func##_Ptr] \ 139 } \ 140 EXTERN_C _declspec( naked ) rettype calltype func params \ 141 { \ 142 _asm jmp [module##_##func##_Ptr] \ 143 } \ 144 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr = (FARPROC)func##_Thunk; \ 145 static rettype calltype func##_##Failure params \ 146 { \ 147 SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); \ 148 return (rettype)0; \ 149 } \ 150 EXTERN_C rettype calltype func##_##resolve params 151 #endif 152 153 154 155 #ifdef __MINGW32__ 156 #define DEFINE_CUSTOM_THUNK( module, resolve, rettype, calltype, func, params ) \ 157 static void func##_Thunk(); \ 158 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr = (FARPROC)func##_Thunk; \ 159 static void func##_Thunk() \ 160 { \ 161 ResolveThunk_##resolve( &module##_##func##_Ptr, #module ".dll", #func ); \ 162 asm(" movl %ebp, %esp"); \ 163 asm(" popl %ebp"); \ 164 asm(" jmp *(%0)"::"m"(module##_##func##_Ptr)); \ 165 } \ 166 EXTERN_C rettype calltype func params \ 167 { \ 168 asm(" popl %ebp"); \ 169 asm(" jmp *(%0)"::"m"(module##_##func##_Ptr)); \ 170 } 171 #else 172 #define DEFINE_CUSTOM_THUNK( module, resolve, rettype, calltype, func, params ) \ 173 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr; \ 174 static _declspec ( naked ) void func##_Thunk() \ 175 { \ 176 ResolveThunk_##resolve( &module##_##func##_Ptr, #module ".dll", #func ); \ 177 _asm jmp [module##_##func##_Ptr] \ 178 } \ 179 EXTERN_C _declspec( naked ) rettype calltype func params \ 180 { \ 181 _asm jmp [module##_##func##_Ptr] \ 182 } \ 183 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr = (FARPROC)func##_Thunk; 184 #endif 185 186 187 #ifdef __MINGW32__ 188 #define DEFINE_DEFAULT_THUNK( module, resolve, rettype, calltype, func, params ) \ 189 static void func##_Thunk(); \ 190 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr = (FARPROC)func##_Thunk; \ 191 static rettype calltype func##_##Failure params; \ 192 static _declspec ( naked ) void func##_Thunk() \ 193 { \ 194 ResolveThunk_##resolve( &module##_##func##_Ptr, #module ".dll", #func, NULL, (FARPROC)func##_##Failure ); \ 195 asm(" movl %ebp, %esp"); \ 196 asm(" popl %ebp"); \ 197 asm(" jmp *(%0)"::"m"(module##_##func##_Ptr)); \ 198 } \ 199 EXTERN_C _declspec( naked ) rettype calltype func params \ 200 { \ 201 asm(" popl %ebp"); \ 202 asm(" jmp *(%0)"::"m"(module##_##func##_Ptr)); \ 203 } \ 204 static rettype calltype func##_##Failure params \ 205 { \ 206 SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); \ 207 return (rettype)0; \ 208 } 209 #else 210 #define DEFINE_DEFAULT_THUNK( module, resolve, rettype, calltype, func, params ) \ 211 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr; \ 212 static rettype calltype func##_##Failure params; \ 213 static _declspec ( naked ) void func##_Thunk() \ 214 { \ 215 ResolveThunk_##resolve( &module##_##func##_Ptr, #module ".dll", #func, NULL, (FARPROC)func##_##Failure ); \ 216 _asm jmp [module##_##func##_Ptr] \ 217 } \ 218 EXTERN_C _declspec( naked ) rettype calltype func params \ 219 { \ 220 _asm jmp [module##_##func##_Ptr] \ 221 } \ 222 EXTERN_C _declspec( dllexport ) FARPROC module##_##func##_Ptr = (FARPROC)func##_Thunk; \ 223 static rettype calltype func##_##Failure params \ 224 { \ 225 SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); \ 226 return (rettype)0; \ 227 } 228 #endif 229