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