static int __cdecl pre_c_init(void) { _PVFV * onexitbegin; /* * create the onexit table. */ onexitbegin = (_PVFV *)_malloc_crt(32 * sizeof(_PVFV)); __onexitend = __onexitbegin = (_PVFV *)_encode_pointer(onexitbegin); if ( onexitbegin == NULL ) /* * cannot allocate minimal required * size. generate failure to load DLL */ return 1; *onexitbegin = (_PVFV) NULL; /* * Run the RTC initialization code for this DLL */ #ifdef _RTC _RTC_Initialize(); atexit(_RTC_Terminate); #endif /* _RTC */ #ifndef _SYSCRT /* * Register __clean_type_info_names so that we clean up all the * type_info.names that are allocated */ atexit(__clean_type_info_names); #endif /* _SYSCRT */ return 0; }
int __tmainCRTStartup( void ) { unsigned int osplatform = 0; unsigned int winver = 0; unsigned int winmajor = 0; unsigned int winminor = 0; unsigned int osver = 0; int initret; int mainret = 0; OSVERSIONINFOA* posvi; int managedapp; #ifdef _WINMAIN_ _TUCHAR* lpszCommandLine; STARTUPINFO StartupInfo; __try { /* Note: MSDN specifically notes that GetStartupInfo returns no error, and throws unspecified SEH if it fails, so the very general exception handler below is appropriate */ GetStartupInfo(&StartupInfo); } __except (EXCEPTION_EXECUTE_HANDLER) { return 255; } #endif /* _WINMAIN_ */ /* * Dynamically allocate the OSVERSIONINFOA buffer, so we avoid * triggering the /GS buffer overrun detection. That can't be * used here, since the guard cookie isn't available until we * initialize it from here! */ posvi = (OSVERSIONINFOA*)HeapAlloc(GetProcessHeap(), 0, sizeof(OSVERSIONINFOA)); if (!posvi) { fast_error_exit(_RT_HEAP); return 255; } /* * Get the full Win32 version */ posvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); if (!GetVersionExA(posvi)) { HeapFree(GetProcessHeap(), 0, posvi); return 255; } osplatform = posvi->dwPlatformId; winmajor = posvi->dwMajorVersion; winminor = posvi->dwMinorVersion; /* * The somewhat bizarre calculations of _osver and _winver are * required for backward compatibility (used to use GetVersion) */ osver = (posvi->dwBuildNumber) & 0x07fff; HeapFree(GetProcessHeap(), 0, posvi); if (osplatform != VER_PLATFORM_WIN32_NT) { osver |= 0x08000; } winver = (winmajor << 8) + winminor; _set_osplatform(osplatform); _set_winver(winver); _set_winmajor(winmajor); _set_winminor(winminor); _set_osver(osver); /* * Determine if this is a managed application */ managedapp = check_managed_app(); if (!_heap_init(1)) { /* initialize heap */ fast_error_exit(_RT_HEAPINIT); /* write message and die */ } if (!_mtinit()) { /* initialize multi-thread */ fast_error_exit(_RT_THREAD); /* write message and die */ } /* Enable buffer count checking if linking against static lib */ _CrtSetCheckCount(TRUE); /* * Initialize the Runtime Checks stuff */ #ifdef _RTC _RTC_Initialize(); #endif /* _RTC */ /* * Guard the remainder of the initialization code and the call * to user's main, or WinMain, function in a __try/__except * statement. */ __try { if (_ioinit() < 0) { /* initialize lowio */ _amsg_exit(_RT_LOWIOINIT); } /* get wide cmd line info */ _tcmdln = (_TSCHAR*)GetCommandLineT(); /* get wide environ info */ _tenvptr = (_TSCHAR*)GetEnvironmentStringsT(); if (_tsetargv() < 0) { _amsg_exit(_RT_SPACEARG); } if (_tsetenvp() < 0) { _amsg_exit(_RT_SPACEENV); } initret = _cinit(TRUE); /* do C data initialize */ if (initret != 0) { _amsg_exit(initret); } #ifdef _WINMAIN_ lpszCommandLine = _twincmdln(); mainret = _tWinMain((HINSTANCE)&__ImageBase, NULL, lpszCommandLine, StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT ); #else /* _WINMAIN_ */ _tinitenv = _tenviron; mainret = _tmain(__argc, _targv, _tenviron); #endif /* _WINMAIN_ */ if (!managedapp) { exit(mainret); } _cexit(); } __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation())) { /* * Should never reach here */ mainret = GetExceptionCode(); if (!managedapp) { _exit(mainret); } _c_exit(); } /* end of try - except */ return mainret; }
/* * routine in DLL to do initialization (in this case, C++ constructors) */ extern void __cdecl _initterm(_PVFV *, _PVFV *); #ifdef _WINMAIN_ #ifdef WPRFLAG int wWinMainCRTStartup( #else /* WPRFLAG */ int WinMainCRTStartup( #endif /* WPRFLAG */ #else /* _WINMAIN_ */ #ifdef WPRFLAG int wmainCRTStartup( #else /* WPRFLAG */ int mainCRTStartup( #endif /* WPRFLAG */ #endif /* _WINMAIN_ */ void ) { int argc = 0; /* three standard arguments to main */ _TSCHAR **argv = NULL; _TSCHAR **envp = NULL; int argret = 0; #ifdef _WINMAIN_ _TUCHAR *lpszCommandLine; STARTUPINFO StartupInfo; #endif /* _WINMAIN_ */ #ifdef WPRFLAG int envp_count = 0; #endif //_startupinfo startinfo; /* * Determine if this is a managed application */ //managedapp = check_managed_app(); /* * Set __app_type properly */ #ifdef _WINMAIN_ //__set_app_type(_GUI_APP); #else /* _WINMAIN_ */ //__set_app_type(_CONSOLE_APP); #endif /* _WINMAIN_ */ #ifdef _WINMAIN_ #ifdef WPRFLAG dbgmsg("wWinMainCRTStartup()"); #else dbgmsg("WinMainCRTStartup()"); #endif #else #ifdef WPRFLAG dbgmsg("wmainCRTStartup()"); #else dbgmsg("mainCRTStartup()"); #endif #endif /* * Mark this module as an EXE file so that atexit/_onexit * will do the right thing when called, including for C++ * d-tors. */ __onexitbegin = __onexitend = (_PVFV *)(-1); dbgmsg("OK1b"); /* * Propogate the _fmode and _commode variables to the DLL * (crash in crtdll.dll...?) */ //*_IMP___FMODE = _fmode; dbgmsg("OK1c"); //*_IMP___COMMODE = _commode; dbgmsg("OK1d"); #ifdef _M_IX86 /* * Set the local copy of the Pentium FDIV adjustment flag * (not supported by crtdll.dll) */ //_adjust_fdiv = * _imp___adjust_fdiv; #endif /* _M_IX86 */ dbgmsg("OK2"); /* * Run the RTC initialization code for this DLL */ #ifdef _RTC _RTC_Initialize(); #endif /* _RTC */ /* * Call _setargv(), which will trigger a call to __setargv() if * SETARGV.OBJ is linked with the EXE. If SETARGV.OBJ is not * linked with the EXE, a dummy _setargv() will be called. */ #ifdef WPRFLAG //_wsetargv(); #else /* WPRFLAG */ //_setargv(); #endif /* WPRFLAG */ /* * If the user has supplied a _matherr routine then set * __pusermatherr to point to it. */ // if ( !__defaultmatherr ) // __setusermatherr(_matherr); #ifdef _M_IX86 //_setdefaultprecision(); #endif /* _M_IX86 */ /* * Do runtime startup initializers. * * Note: the only possible entry we'll be executing here is for * __lconv_init, pulled in from charmax.obj only if the EXE was * compiled with -J. All other .CRT$XI* initializers are only * run as part of the CRT itself, and so for the CRT DLL model * are not found in the EXE. For that reason, we call _initterm, * not _initterm_e, because __lconv_init will never return failure, * and _initterm_e is not exported from the CRT DLL. * * Note further that, when using the CRT DLL, executing the * .CRT$XI* initializers is only done for an EXE, not for a DLL * using the CRT DLL. That is to make sure the -J setting for * the EXE is not overriden by that of any DLL. */ //_initterm( __xi_a, __xi_z ); #ifdef _RTC atexit(_RTC_Terminate); #endif /* _RTC */ /* * Get the arguments for the call to main. Note this must be * done explicitly, rather than as part of the dll's * initialization, to implement optional expansion of wild * card chars in filename args */ dbgmsg("OK3"); //startinfo.newmode = 0; #ifdef WPRFLAG _wcmdln = GetCommandLineW(); argv = (_TSCHAR**)CommandLineToArgvW(_wcmdln, &argc); if (argv == NULL) FatalAppExitA(0, "This application requires Windows NT."); _wpgmptr = (wchar_t*)argv[0]; __wargv = (wchar_t**)argv; __argc = argc; _wenviron[0] = GetEnvironmentStringsW(); while ((_wenviron[envp_count][0] != 0) & (envp_count < MAX_WENVIRON_COUNT)) { _wenviron[envp_count+1] = _wenviron[envp_count]+ wcslen(_wenviron[envp_count])+1; envp_count++; } if ((argv == NULL) | (envp_count >= MAX_WENVIRON_COUNT)) argret = -1; if (argret < 0) _amsg_exit(_RT_SPACEARG); _wenviron[envp_count] = NULL; envp = (_TSCHAR**)_wenviron; #else /* WPRFLAG */ argret = __GetMainArgs(&argc, &argv, &envp, 0, NULL /*&startinfo*/); if (argv == NULL) _amsg_exit(_RT_SPACEARG); __argc = argc; __argv = argv; _environ = envp; _pgmptr = argv[0]; #endif dbgmsg("OK4"); /* * do C++ constructors (initializers) specific to this EXE */ //_initterm( __xc_a, __xc_z ); #ifdef _WINMAIN_ /* * Skip past program name (first token in command line). * Check for and handle quoted program name. */ #ifdef WPRFLAG /* OS may not support "W" flavors */ if (_wcmdln == NULL) FatalAppExitA(0, "This application requires Windows NT."); lpszCommandLine = (wchar_t *)_wcmdln; #else /* WPRFLAG */ lpszCommandLine = (unsigned char *)_acmdln; #endif /* WPRFLAG */ if ( *lpszCommandLine == DQUOTECHAR ) { /* * Scan, and skip over, subsequent characters until * another double-quote or a null is encountered. */ while ( *++lpszCommandLine && (*lpszCommandLine != DQUOTECHAR) ); /* * If we stopped on a double-quote (usual case), skip * over it. */ if ( *lpszCommandLine == DQUOTECHAR ) lpszCommandLine++; } while (*lpszCommandLine > SPACECHAR) lpszCommandLine++; if (*lpszCommandLine >= SPACECHAR) lpszCommandLine++; dbgmsg("OK5"); /* * Skip past any white space preceeding the second token. */ while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) { lpszCommandLine++; } StartupInfo.dwFlags = 0; GetStartupInfo( &StartupInfo ); #ifdef WPRFLAG __winitenv = (wchar_t**)envp; exit(wWinMain( #else /* WPRFLAG */ __initenv = envp; exit(WinMain( #endif /* WPRFLAG */ GetModuleHandleA(NULL), NULL, (LPTSTR)lpszCommandLine, StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT )); #else /* _WINMAIN_ */ #ifdef WPRFLAG dbgmsg("OK6"); exit(wmain(argc, (wchar_t**)argv, (wchar_t**)envp)); #else /* WPRFLAG */ dbgmsg("OK6"); exit(main(argc, argv, envp)); #endif /* WPRFLAG */ #endif /* _WINMAIN_ */ }
BOOL WINAPI _CRT_INIT( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved ) { unsigned int osplatform = 0; unsigned int winver = 0; unsigned int winmajor = 0; unsigned int winminor = 0; unsigned int osver = 0; /* * Start-up code only gets executed when the process is initialized */ if (dwReason == DLL_PROCESS_ATTACH) { /* * Dynamically allocate the OSVERSIONINFOA buffer, so we avoid * triggering the /GS buffer overrun detection. That can't be * used here, since the guard cookie isn't available until we * initialize it from here! */ OSVERSIONINFOA* posvi = (OSVERSIONINFOA*)HeapAlloc(GetProcessHeap(), 0, sizeof(OSVERSIONINFOA)); if (!posvi) { return FALSE; } /* * Get the full Win32 version */ posvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); if (!GetVersionExA(posvi)) { HeapFree(GetProcessHeap(), 0, posvi); return FALSE; } osplatform = posvi->dwPlatformId; winmajor = posvi->dwMajorVersion; winminor = posvi->dwMinorVersion; /* * The somewhat bizarre calculations of _osver and _winver are * required for backward compatibility (used to use GetVersion) */ osver = (posvi->dwBuildNumber) & 0x07fff; HeapFree(GetProcessHeap(), 0, posvi); if (osplatform != VER_PLATFORM_WIN32_NT) { osver |= 0x08000; } winver = (winmajor << 8) + winminor; _set_osplatform(osplatform); _set_winver(winver); _set_winmajor(winmajor); _set_winminor(winminor); _set_osver(osver); if (!_heap_init(1)) { /* initialize heap */ return FALSE; /* fail to load DLL */ } if (!_mtinit()) { /* initialize multi-thread */ _heap_term(); /* heap is now invalid! */ return FALSE; /* fail to load DLL */ } /* * Initialize the Runtime Checks stuff */ #ifdef _RTC _RTC_Initialize(); #endif /* _RTC */ _acmdln = (char*)GetCommandLineA(); _aenvptr = (char*)__crtGetEnvironmentStringsA(); if (_ioinit() < 0) { /* initialize lowio */ _mtterm(); /* free TLS index, call _mtdeletelocks() */ _heap_term(); /* heap is now invalid! */ return FALSE; /* fail to load DLL */ } if (_setargv() < 0 || /* get cmd line info */ _setenvp() < 0 || /* get environ info */ _cinit(FALSE) != 0) { /* do C data initialize, but don't init floating point */ _ioterm(); /* shut down lowio */ _mtterm(); /* free TLS index, call _mtdeletelocks() */ _heap_term(); /* heap is now invalid! */ return FALSE; /* fail to load DLL */ } /* Enable buffer count checking if linking against static lib */ _CrtSetCheckCount(TRUE); /* * increment flag to indicate process attach notification * has been received */ __proc_attached++; } else if (dwReason == DLL_PROCESS_DETACH) { if (__proc_attached > 0) { __proc_attached--; /* * Any basic clean-up code that goes here must be duplicated * below in _DllMainCRTStartup for the case where the user's * DllMain() routine fails on a Process Attach notification. * This does not include calling user C++ destructors, etc. */ if (_C_Termination_Done == FALSE) { _cexit(); } #ifdef _DEBUG /* Dump all memory leaks */ if (_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & _CRTDBG_LEAK_CHECK_DF) { _CrtDumpMemoryLeaks(); } #endif /* _DEBUG */ /* * What remains is to clean up the system resources we have * used (handles, critical sections, memory,...,etc.). This * needs to be done if the whole process is NOT terminating. */ #ifndef _DEBUG if (lpreserved == NULL) { #endif /* _DEBUG */ /* * The process is NOT terminating so we must clean up... */ /* Shut down lowio */ _ioterm(); _mtterm(); /* This should be the last thing the C run-time does */ _heap_term(); /* heap is now invalid! */ #ifndef _DEBUG } #endif /* _DEBUG */ } else /* no prior process attach, just return */ { return FALSE; } } else if (dwReason == DLL_THREAD_ATTACH) { _ptiddata ptd; /* Initialize FlsGetValue function pointer */ __set_flsgetvalue(); if (((ptd = _calloc_crt(1, sizeof(struct _tiddata))) != NULL)) { if (FLS_SETVALUE(__flsindex, (LPVOID)ptd)) { /* * Initialize of per-thread data */ _initptd(ptd, NULL); ptd->_tid = GetCurrentThreadId(); ptd->_thandle = (uintptr_t)(-1); } else { _free_crt(ptd); return FALSE; } } else { return FALSE; } } else if (dwReason == DLL_THREAD_DETACH) { _freeptd(NULL); /* free up per-thread CRT data */ } return TRUE ; }
static int __cdecl pre_c_init(void) { /* * Determine if this is a managed application */ managedapp = check_managed_app(); /* * Set __app_type properly */ #ifdef _WINMAIN_ __set_app_type(_GUI_APP); #else /* _WINMAIN_ */ __set_app_type(_CONSOLE_APP); #endif /* _WINMAIN_ */ /* * Mark this module as an EXE file so that atexit/_onexit * will do the right thing when called, including for C++ * d-tors. */ __onexitbegin = __onexitend = (_PVFV*)_encode_pointer((_PVFV*)(-1)); /* * Propogate the _fmode and _commode variables to the DLL */ *_IMP___FMODE = _fmode; *_IMP___COMMODE = _commode; #ifdef _M_IX86 /* * Set the local copy of the Pentium FDIV adjustment flag */ _adjust_fdiv = * _imp___adjust_fdiv; #endif /* _M_IX86 */ /* * Run the RTC initialization code for this DLL */ #ifdef _RTC _RTC_Initialize(); #endif /* _RTC */ /* * Call _setargv(), which will trigger a call to __setargv() if * SETARGV.OBJ is linked with the EXE. If SETARGV.OBJ is not * linked with the EXE, a dummy _setargv() will be called. */ #ifdef WPRFLAG _wsetargv(); #else /* WPRFLAG */ _setargv(); #endif /* WPRFLAG */ /* * If the user has supplied a _matherr routine then set * __pusermatherr to point to it. */ if (!__defaultmatherr) { __setusermatherr(_matherr); } #ifdef _M_IX86 _setdefaultprecision(); #endif /* _M_IX86 */ /* Enable per-thread locale if user asked for it */ if (__globallocalestatus == -1) { _configthreadlocale(-1); } return 0; }