1*c2c66affSColin Finck /** 2*c2c66affSColin Finck * This file has no copyright assigned and is placed in the Public Domain. 3*c2c66affSColin Finck * This file is part of the w64 mingw-runtime package. 4*c2c66affSColin Finck * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5*c2c66affSColin Finck */ 6*c2c66affSColin Finck 7*c2c66affSColin Finck #undef CRTDLL 8*c2c66affSColin Finck #ifndef _DLL 9*c2c66affSColin Finck #define _DLL 10*c2c66affSColin Finck #endif 11*c2c66affSColin Finck 12*c2c66affSColin Finck #define SPECIAL_CRTEXE 13*c2c66affSColin Finck 14*c2c66affSColin Finck #include <oscalls.h> 15*c2c66affSColin Finck #include <internal.h> 16*c2c66affSColin Finck #include <process.h> 17*c2c66affSColin Finck #include <signal.h> 18*c2c66affSColin Finck #include <math.h> 19*c2c66affSColin Finck #include <stdlib.h> 20*c2c66affSColin Finck #include <tchar.h> 21*c2c66affSColin Finck #include <sect_attribs.h> 22*c2c66affSColin Finck #include <locale.h> 23*c2c66affSColin Finck 24*c2c66affSColin Finck #ifndef __winitenv 25*c2c66affSColin Finck extern wchar_t *** __MINGW_IMP_SYMBOL(__winitenv); 26*c2c66affSColin Finck #define __winitenv (* __MINGW_IMP_SYMBOL(__winitenv)) 27*c2c66affSColin Finck #endif 28*c2c66affSColin Finck 29*c2c66affSColin Finck #ifndef __initenv 30*c2c66affSColin Finck extern char *** __MINGW_IMP_SYMBOL(__initenv); 31*c2c66affSColin Finck #define __initenv (* __MINGW_IMP_SYMBOL(__initenv)) 32*c2c66affSColin Finck #endif 33*c2c66affSColin Finck 34*c2c66affSColin Finck /* Hack, for bug in ld. Will be removed soon. */ 35*c2c66affSColin Finck #if defined(__GNUC__) 36*c2c66affSColin Finck #define __ImageBase __MINGW_LSYMBOL(_image_base__) 37*c2c66affSColin Finck #endif 38*c2c66affSColin Finck 39*c2c66affSColin Finck /* This symbol is defined by ld. */ 40*c2c66affSColin Finck extern IMAGE_DOS_HEADER __ImageBase; 41*c2c66affSColin Finck 42*c2c66affSColin Finck extern void __cdecl _fpreset (void); 43*c2c66affSColin Finck #define SPACECHAR _T(' ') 44*c2c66affSColin Finck #define DQUOTECHAR _T('\"') 45*c2c66affSColin Finck 46*c2c66affSColin Finck extern int * __MINGW_IMP_SYMBOL(_fmode); 47*c2c66affSColin Finck extern int * __MINGW_IMP_SYMBOL(_commode); 48*c2c66affSColin Finck 49*c2c66affSColin Finck #undef _fmode 50*c2c66affSColin Finck extern int _fmode; 51*c2c66affSColin Finck extern int * __MINGW_IMP_SYMBOL(_commode); 52*c2c66affSColin Finck #define _commode (* __MINGW_IMP_SYMBOL(_commode)) 53*c2c66affSColin Finck extern int _dowildcard; 54*c2c66affSColin Finck 55*c2c66affSColin Finck extern _CRTIMP void __cdecl _initterm(_PVFV *, _PVFV *); 56*c2c66affSColin Finck 57*c2c66affSColin Finck static int __cdecl check_managed_app (void); 58*c2c66affSColin Finck 59*c2c66affSColin Finck extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a[]; 60*c2c66affSColin Finck extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[]; 61*c2c66affSColin Finck extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[]; 62*c2c66affSColin Finck extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[]; 63*c2c66affSColin Finck 64*c2c66affSColin Finck /* TLS initialization hook. */ 65*c2c66affSColin Finck extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback; 66*c2c66affSColin Finck 67*c2c66affSColin Finck extern _PVFV *__onexitbegin; 68*c2c66affSColin Finck extern _PVFV *__onexitend; 69*c2c66affSColin Finck 70*c2c66affSColin Finck extern int mingw_app_type; 71*c2c66affSColin Finck 72*c2c66affSColin Finck HINSTANCE __mingw_winmain_hInstance; 73*c2c66affSColin Finck _TCHAR *__mingw_winmain_lpCmdLine; 74*c2c66affSColin Finck DWORD __mingw_winmain_nShowCmd; 75*c2c66affSColin Finck 76*c2c66affSColin Finck static int argc; 77*c2c66affSColin Finck extern void __main(void); 78*c2c66affSColin Finck #ifdef WPRFLAG 79*c2c66affSColin Finck static wchar_t **argv; 80*c2c66affSColin Finck static wchar_t **envp; 81*c2c66affSColin Finck #else 82*c2c66affSColin Finck static char **argv; 83*c2c66affSColin Finck static char **envp; 84*c2c66affSColin Finck #endif 85*c2c66affSColin Finck 86*c2c66affSColin Finck static int argret; 87*c2c66affSColin Finck static int mainret=0; 88*c2c66affSColin Finck static int managedapp; 89*c2c66affSColin Finck static int has_cctor = 0; 90*c2c66affSColin Finck static _startupinfo startinfo; 91*c2c66affSColin Finck extern LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler; 92*c2c66affSColin Finck 93*c2c66affSColin Finck extern void _pei386_runtime_relocator (void); 94*c2c66affSColin Finck long CALLBACK _gnu_exception_handler (EXCEPTION_POINTERS * exception_data); 95*c2c66affSColin Finck #ifdef WPRFLAG 96*c2c66affSColin Finck static void duplicate_ppstrings (int ac, wchar_t ***av); 97*c2c66affSColin Finck #else 98*c2c66affSColin Finck static void duplicate_ppstrings (int ac, char ***av); 99*c2c66affSColin Finck #endif 100*c2c66affSColin Finck 101*c2c66affSColin Finck static int __cdecl pre_c_init (void); 102*c2c66affSColin Finck static void __cdecl pre_cpp_init (void); 103*c2c66affSColin Finck static void __cdecl __mingw_prepare_except_for_msvcr80_and_higher (void); 104*c2c66affSColin Finck _CRTALLOC(".CRT$XIAA") _PIFV mingw_pcinit = pre_c_init; 105*c2c66affSColin Finck _CRTALLOC(".CRT$XCAA") _PVFV mingw_pcppinit = pre_cpp_init; 106*c2c66affSColin Finck 107*c2c66affSColin Finck extern int _MINGW_INSTALL_DEBUG_MATHERR; 108*c2c66affSColin Finck 109*c2c66affSColin Finck static int __cdecl 110*c2c66affSColin Finck pre_c_init (void) 111*c2c66affSColin Finck { 112*c2c66affSColin Finck managedapp = check_managed_app (); 113*c2c66affSColin Finck if (mingw_app_type) 114*c2c66affSColin Finck __set_app_type(_GUI_APP); 115*c2c66affSColin Finck else 116*c2c66affSColin Finck __set_app_type (_CONSOLE_APP); 117*c2c66affSColin Finck __onexitbegin = __onexitend = (_PVFV *) _encode_pointer ((_PVFV *)(-1)); 118*c2c66affSColin Finck 119*c2c66affSColin Finck * __MINGW_IMP_SYMBOL(_fmode) = _fmode; 120*c2c66affSColin Finck * __MINGW_IMP_SYMBOL(_commode) = _commode; 121*c2c66affSColin Finck 122*c2c66affSColin Finck #ifdef WPRFLAG 123*c2c66affSColin Finck _wsetargv(); 124*c2c66affSColin Finck #else 125*c2c66affSColin Finck _setargv(); 126*c2c66affSColin Finck #endif 127*c2c66affSColin Finck if (_MINGW_INSTALL_DEBUG_MATHERR == 1) 128*c2c66affSColin Finck { 129*c2c66affSColin Finck __setusermatherr (_matherr); 130*c2c66affSColin Finck } 131*c2c66affSColin Finck 132*c2c66affSColin Finck if (__globallocalestatus == -1) 133*c2c66affSColin Finck { 134*c2c66affSColin Finck } 135*c2c66affSColin Finck return 0; 136*c2c66affSColin Finck } 137*c2c66affSColin Finck 138*c2c66affSColin Finck static void __cdecl 139*c2c66affSColin Finck pre_cpp_init (void) 140*c2c66affSColin Finck { 141*c2c66affSColin Finck startinfo.newmode = _newmode; 142*c2c66affSColin Finck 143*c2c66affSColin Finck #ifdef WPRFLAG 144*c2c66affSColin Finck argret = __wgetmainargs(&argc,&argv,&envp,_dowildcard,&startinfo); 145*c2c66affSColin Finck #else 146*c2c66affSColin Finck argret = __getmainargs(&argc,&argv,&envp,_dowildcard,&startinfo); 147*c2c66affSColin Finck #endif 148*c2c66affSColin Finck } 149*c2c66affSColin Finck 150*c2c66affSColin Finck static int __cdecl __tmainCRTStartup (void); 151*c2c66affSColin Finck 152*c2c66affSColin Finck int __cdecl WinMainCRTStartup (void); 153*c2c66affSColin Finck 154*c2c66affSColin Finck int __cdecl WinMainCRTStartup (void) 155*c2c66affSColin Finck { 156*c2c66affSColin Finck int ret = 255; 157*c2c66affSColin Finck #ifdef __SEH__ 158*c2c66affSColin Finck asm ("\t.l_startw:\n" 159*c2c66affSColin Finck "\t.seh_handler __C_specific_handler, @except\n" 160*c2c66affSColin Finck "\t.seh_handlerdata\n" 161*c2c66affSColin Finck "\t.long 1\n" 162*c2c66affSColin Finck "\t.rva .l_startw, .l_endw, _gnu_exception_handler ,.l_endw\n" 163*c2c66affSColin Finck "\t.text" 164*c2c66affSColin Finck ); 165*c2c66affSColin Finck #endif 166*c2c66affSColin Finck mingw_app_type = 1; 167*c2c66affSColin Finck __security_init_cookie (); 168*c2c66affSColin Finck ret = __tmainCRTStartup (); 169*c2c66affSColin Finck #ifdef __SEH__ 170*c2c66affSColin Finck asm ("\tnop\n" 171*c2c66affSColin Finck "\t.l_endw: nop\n"); 172*c2c66affSColin Finck #endif 173*c2c66affSColin Finck return ret; 174*c2c66affSColin Finck } 175*c2c66affSColin Finck 176*c2c66affSColin Finck int __cdecl mainCRTStartup (void); 177*c2c66affSColin Finck 178*c2c66affSColin Finck #ifdef _WIN64 179*c2c66affSColin Finck int __mingw_init_ehandler (void); 180*c2c66affSColin Finck #endif 181*c2c66affSColin Finck 182*c2c66affSColin Finck int __cdecl mainCRTStartup (void) 183*c2c66affSColin Finck { 184*c2c66affSColin Finck int ret = 255; 185*c2c66affSColin Finck #ifdef __SEH__ 186*c2c66affSColin Finck asm ("\t.l_start:\n" 187*c2c66affSColin Finck "\t.seh_handler __C_specific_handler, @except\n" 188*c2c66affSColin Finck "\t.seh_handlerdata\n" 189*c2c66affSColin Finck "\t.long 1\n" 190*c2c66affSColin Finck "\t.rva .l_start, .l_end, _gnu_exception_handler ,.l_end\n" 191*c2c66affSColin Finck "\t.text" 192*c2c66affSColin Finck ); 193*c2c66affSColin Finck #endif 194*c2c66affSColin Finck mingw_app_type = 0; 195*c2c66affSColin Finck __security_init_cookie (); 196*c2c66affSColin Finck ret = __tmainCRTStartup (); 197*c2c66affSColin Finck #ifdef __SEH__ 198*c2c66affSColin Finck asm ("\tnop\n" 199*c2c66affSColin Finck "\t.l_end: nop\n"); 200*c2c66affSColin Finck #endif 201*c2c66affSColin Finck return ret; 202*c2c66affSColin Finck } 203*c2c66affSColin Finck 204*c2c66affSColin Finck static 205*c2c66affSColin Finck __declspec(noinline) 206*c2c66affSColin Finck int __cdecl 207*c2c66affSColin Finck __tmainCRTStartup (void) 208*c2c66affSColin Finck { 209*c2c66affSColin Finck _TCHAR *lpszCommandLine = NULL; 210*c2c66affSColin Finck STARTUPINFO StartupInfo; 211*c2c66affSColin Finck WINBOOL inDoubleQuote = FALSE; 212*c2c66affSColin Finck memset (&StartupInfo, 0, sizeof (STARTUPINFO)); 213*c2c66affSColin Finck 214*c2c66affSColin Finck #ifndef _WIN64 215*c2c66affSColin Finck /* We need to make sure that this function is build with frame-pointer 216*c2c66affSColin Finck and that we align the stack to 16 bytes for the sake of SSE ops in main 217*c2c66affSColin Finck or in functions inlined into main. */ 218*c2c66affSColin Finck lpszCommandLine = (_TCHAR *) alloca (32); 219*c2c66affSColin Finck memset (lpszCommandLine, 0xcc, 32); 220*c2c66affSColin Finck #ifdef __GNUC__ 221*c2c66affSColin Finck asm __volatile__ ("andl $-16, %%esp" : : : "%esp"); 222*c2c66affSColin Finck #endif 223*c2c66affSColin Finck #endif 224*c2c66affSColin Finck 225*c2c66affSColin Finck if (mingw_app_type) 226*c2c66affSColin Finck GetStartupInfo (&StartupInfo); 227*c2c66affSColin Finck { 228*c2c66affSColin Finck void *lock_free = NULL; 229*c2c66affSColin Finck void *fiberid = ((PNT_TIB)NtCurrentTeb())->StackBase; 230*c2c66affSColin Finck int nested = FALSE; 231*c2c66affSColin Finck while((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock, 232*c2c66affSColin Finck fiberid, 0)) != 0) 233*c2c66affSColin Finck { 234*c2c66affSColin Finck if (lock_free == fiberid) 235*c2c66affSColin Finck { 236*c2c66affSColin Finck nested = TRUE; 237*c2c66affSColin Finck break; 238*c2c66affSColin Finck } 239*c2c66affSColin Finck Sleep(1000); 240*c2c66affSColin Finck } 241*c2c66affSColin Finck if (__native_startup_state == __initializing) 242*c2c66affSColin Finck { 243*c2c66affSColin Finck _amsg_exit (31); 244*c2c66affSColin Finck } 245*c2c66affSColin Finck else if (__native_startup_state == __uninitialized) 246*c2c66affSColin Finck { 247*c2c66affSColin Finck __native_startup_state = __initializing; 248*c2c66affSColin Finck _initterm ((_PVFV *)(void *)__xi_a, (_PVFV *)(void *) __xi_z); 249*c2c66affSColin Finck } 250*c2c66affSColin Finck else 251*c2c66affSColin Finck has_cctor = 1; 252*c2c66affSColin Finck 253*c2c66affSColin Finck if (__native_startup_state == __initializing) 254*c2c66affSColin Finck { 255*c2c66affSColin Finck _initterm (__xc_a, __xc_z); 256*c2c66affSColin Finck __native_startup_state = __initialized; 257*c2c66affSColin Finck } 258*c2c66affSColin Finck _ASSERTE(__native_startup_state == __initialized); 259*c2c66affSColin Finck if (! nested) 260*c2c66affSColin Finck (VOID)InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); 261*c2c66affSColin Finck 262*c2c66affSColin Finck if (__dyn_tls_init_callback != NULL) 263*c2c66affSColin Finck __dyn_tls_init_callback (NULL, DLL_THREAD_ATTACH, NULL); 264*c2c66affSColin Finck 265*c2c66affSColin Finck _pei386_runtime_relocator (); 266*c2c66affSColin Finck __mingw_oldexcpt_handler = SetUnhandledExceptionFilter (_gnu_exception_handler); 267*c2c66affSColin Finck #ifdef _WIN64 268*c2c66affSColin Finck __mingw_init_ehandler (); 269*c2c66affSColin Finck #endif 270*c2c66affSColin Finck __mingw_prepare_except_for_msvcr80_and_higher (); 271*c2c66affSColin Finck 272*c2c66affSColin Finck _fpreset (); 273*c2c66affSColin Finck 274*c2c66affSColin Finck if (mingw_app_type) 275*c2c66affSColin Finck { 276*c2c66affSColin Finck #ifdef WPRFLAG 277*c2c66affSColin Finck lpszCommandLine = (_TCHAR *) _wcmdln; 278*c2c66affSColin Finck #else 279*c2c66affSColin Finck lpszCommandLine = (char *) _acmdln; 280*c2c66affSColin Finck #endif 281*c2c66affSColin Finck while (*lpszCommandLine > SPACECHAR || (*lpszCommandLine && inDoubleQuote)) 282*c2c66affSColin Finck { 283*c2c66affSColin Finck if (*lpszCommandLine == DQUOTECHAR) 284*c2c66affSColin Finck inDoubleQuote = !inDoubleQuote; 285*c2c66affSColin Finck #ifdef _MBCS 286*c2c66affSColin Finck if (_ismbblead (*lpszCommandLine)) 287*c2c66affSColin Finck { 288*c2c66affSColin Finck if (lpszCommandLine) /* FIXME: Why this check? Should I check for *lpszCommandLine != 0 too? */ 289*c2c66affSColin Finck lpszCommandLine++; 290*c2c66affSColin Finck } 291*c2c66affSColin Finck #endif 292*c2c66affSColin Finck ++lpszCommandLine; 293*c2c66affSColin Finck } 294*c2c66affSColin Finck while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) 295*c2c66affSColin Finck lpszCommandLine++; 296*c2c66affSColin Finck 297*c2c66affSColin Finck __mingw_winmain_hInstance = (HINSTANCE) &__ImageBase; 298*c2c66affSColin Finck __mingw_winmain_lpCmdLine = lpszCommandLine; 299*c2c66affSColin Finck __mingw_winmain_nShowCmd = StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? 300*c2c66affSColin Finck StartupInfo.wShowWindow : SW_SHOWDEFAULT; 301*c2c66affSColin Finck } 302*c2c66affSColin Finck duplicate_ppstrings (argc, &argv); 303*c2c66affSColin Finck __main (); 304*c2c66affSColin Finck #ifdef WPRFLAG 305*c2c66affSColin Finck __winitenv = envp; 306*c2c66affSColin Finck /* C++ initialization. 307*c2c66affSColin Finck gcc inserts this call automatically for a function called main, but not for wmain. */ 308*c2c66affSColin Finck mainret = wmain (argc, argv, envp); 309*c2c66affSColin Finck #else 310*c2c66affSColin Finck __initenv = envp; 311*c2c66affSColin Finck mainret = main (argc, argv, envp); 312*c2c66affSColin Finck #endif 313*c2c66affSColin Finck if (!managedapp) 314*c2c66affSColin Finck exit (mainret); 315*c2c66affSColin Finck 316*c2c66affSColin Finck if (has_cctor == 0) 317*c2c66affSColin Finck _cexit (); 318*c2c66affSColin Finck } 319*c2c66affSColin Finck return mainret; 320*c2c66affSColin Finck } 321*c2c66affSColin Finck 322*c2c66affSColin Finck extern int mingw_initltsdrot_force; 323*c2c66affSColin Finck extern int mingw_initltsdyn_force; 324*c2c66affSColin Finck extern int mingw_initltssuo_force; 325*c2c66affSColin Finck extern int mingw_initcharmax; 326*c2c66affSColin Finck 327*c2c66affSColin Finck static int __cdecl 328*c2c66affSColin Finck check_managed_app (void) 329*c2c66affSColin Finck { 330*c2c66affSColin Finck PIMAGE_DOS_HEADER pDOSHeader; 331*c2c66affSColin Finck PIMAGE_NT_HEADERS pPEHeader; 332*c2c66affSColin Finck PIMAGE_OPTIONAL_HEADER32 pNTHeader32; 333*c2c66affSColin Finck PIMAGE_OPTIONAL_HEADER64 pNTHeader64; 334*c2c66affSColin Finck 335*c2c66affSColin Finck /* Force to be linked. */ 336*c2c66affSColin Finck mingw_initltsdrot_force=1; 337*c2c66affSColin Finck mingw_initltsdyn_force=1; 338*c2c66affSColin Finck mingw_initltssuo_force=1; 339*c2c66affSColin Finck mingw_initcharmax=1; 340*c2c66affSColin Finck 341*c2c66affSColin Finck pDOSHeader = (PIMAGE_DOS_HEADER) &__ImageBase; 342*c2c66affSColin Finck if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE) 343*c2c66affSColin Finck return 0; 344*c2c66affSColin Finck 345*c2c66affSColin Finck pPEHeader = (PIMAGE_NT_HEADERS)((char *)pDOSHeader + pDOSHeader->e_lfanew); 346*c2c66affSColin Finck if (pPEHeader->Signature != IMAGE_NT_SIGNATURE) 347*c2c66affSColin Finck return 0; 348*c2c66affSColin Finck 349*c2c66affSColin Finck pNTHeader32 = (PIMAGE_OPTIONAL_HEADER32) &pPEHeader->OptionalHeader; 350*c2c66affSColin Finck switch (pNTHeader32->Magic) 351*c2c66affSColin Finck { 352*c2c66affSColin Finck case IMAGE_NT_OPTIONAL_HDR32_MAGIC: 353*c2c66affSColin Finck if (pNTHeader32->NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR) 354*c2c66affSColin Finck return 0; 355*c2c66affSColin Finck return !! pNTHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress; 356*c2c66affSColin Finck case IMAGE_NT_OPTIONAL_HDR64_MAGIC: 357*c2c66affSColin Finck pNTHeader64 = (PIMAGE_OPTIONAL_HEADER64)pNTHeader32; 358*c2c66affSColin Finck if (pNTHeader64->NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR) 359*c2c66affSColin Finck return 0; 360*c2c66affSColin Finck return !! pNTHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress; 361*c2c66affSColin Finck } 362*c2c66affSColin Finck return 0; 363*c2c66affSColin Finck } 364*c2c66affSColin Finck 365*c2c66affSColin Finck #ifdef WPRFLAG 366*c2c66affSColin Finck static size_t wbytelen(const wchar_t *p) 367*c2c66affSColin Finck { 368*c2c66affSColin Finck size_t ret = 1; 369*c2c66affSColin Finck while (*p!=0) { 370*c2c66affSColin Finck ret++,++p; 371*c2c66affSColin Finck } 372*c2c66affSColin Finck return ret*2; 373*c2c66affSColin Finck } 374*c2c66affSColin Finck static void duplicate_ppstrings (int ac, wchar_t ***av) 375*c2c66affSColin Finck { 376*c2c66affSColin Finck wchar_t **avl; 377*c2c66affSColin Finck int i; 378*c2c66affSColin Finck wchar_t **n = (wchar_t **) malloc (sizeof (wchar_t *) * (ac + 1)); 379*c2c66affSColin Finck 380*c2c66affSColin Finck avl=*av; 381*c2c66affSColin Finck for (i=0; i < ac; i++) 382*c2c66affSColin Finck { 383*c2c66affSColin Finck size_t l = wbytelen (avl[i]); 384*c2c66affSColin Finck n[i] = (wchar_t *) malloc (l); 385*c2c66affSColin Finck memcpy (n[i], avl[i], l); 386*c2c66affSColin Finck } 387*c2c66affSColin Finck n[i] = NULL; 388*c2c66affSColin Finck *av = n; 389*c2c66affSColin Finck } 390*c2c66affSColin Finck #else 391*c2c66affSColin Finck static void duplicate_ppstrings (int ac, char ***av) 392*c2c66affSColin Finck { 393*c2c66affSColin Finck char **avl; 394*c2c66affSColin Finck int i; 395*c2c66affSColin Finck char **n = (char **) malloc (sizeof (char *) * (ac + 1)); 396*c2c66affSColin Finck 397*c2c66affSColin Finck avl=*av; 398*c2c66affSColin Finck for (i=0; i < ac; i++) 399*c2c66affSColin Finck { 400*c2c66affSColin Finck size_t l = strlen (avl[i]) + 1; 401*c2c66affSColin Finck n[i] = (char *) malloc (l); 402*c2c66affSColin Finck memcpy (n[i], avl[i], l); 403*c2c66affSColin Finck } 404*c2c66affSColin Finck n[i] = NULL; 405*c2c66affSColin Finck *av = n; 406*c2c66affSColin Finck } 407*c2c66affSColin Finck #endif 408*c2c66affSColin Finck 409*c2c66affSColin Finck #ifdef __MINGW_SHOW_INVALID_PARAMETER_EXCEPTION 410*c2c66affSColin Finck #define __UNUSED_PARAM_1(x) x 411*c2c66affSColin Finck #else 412*c2c66affSColin Finck #define __UNUSED_PARAM_1 __UNUSED_PARAM 413*c2c66affSColin Finck #endif 414*c2c66affSColin Finck static void __cdecl 415*c2c66affSColin Finck __mingw_invalidParameterHandler (const wchar_t * __UNUSED_PARAM_1(expression), 416*c2c66affSColin Finck const wchar_t * __UNUSED_PARAM_1(function), 417*c2c66affSColin Finck const wchar_t * __UNUSED_PARAM_1(file), 418*c2c66affSColin Finck unsigned int __UNUSED_PARAM_1(line), 419*c2c66affSColin Finck uintptr_t __UNUSED_PARAM(pReserved)) 420*c2c66affSColin Finck { 421*c2c66affSColin Finck #ifdef __MINGW_SHOW_INVALID_PARAMETER_EXCEPTION 422*c2c66affSColin Finck wprintf(L"Invalid parameter detected in function %s. File: %s Line: %u\n", function, file, line); 423*c2c66affSColin Finck wprintf(L"Expression: %s\n", expression); 424*c2c66affSColin Finck #endif 425*c2c66affSColin Finck } 426*c2c66affSColin Finck 427*c2c66affSColin Finck HANDLE __mingw_get_msvcrt_handle(void); 428*c2c66affSColin Finck 429*c2c66affSColin Finck static void __cdecl 430*c2c66affSColin Finck __mingw_prepare_except_for_msvcr80_and_higher (void) 431*c2c66affSColin Finck { 432*c2c66affSColin Finck _invalid_parameter_handler (*fIPH)(_invalid_parameter_handler) = NULL; 433*c2c66affSColin Finck 434*c2c66affSColin Finck fIPH = (void*)GetProcAddress (__mingw_get_msvcrt_handle(), "_set_invalid_parameter_handler"); 435*c2c66affSColin Finck if (fIPH) 436*c2c66affSColin Finck (*fIPH)(__mingw_invalidParameterHandler); 437*c2c66affSColin Finck } 438