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