65,176
社区成员




BOOL __cdecl
__CRTDLL_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;
if ( dwReason == DLL_PROCESS_ATTACH ) {
OSVERSIONINFOA *posvi;
/*
* 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)
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);
posvi = NULL;
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 defined (_M_IX86) && defined (_SYSCRT)
/*
* Make sure we are NOT running on Win32s
*/
if ( osplatform == VER_PLATFORM_WIN32s ) {
__crtMessageBoxA("MSVCRT.DLL for Win32\n\nError: MSVCRT.DLL is not compatible with Win32s.",
"Microsoft Visual C++ Runtime Library",
MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
return FALSE;
}
#endif /* defined (_M_IX86) && defined (_SYSCRT) */
if ( !_heap_init(1) ) /* initialize heap */
/*
* The heap cannot be initialized, return failure to the
* loader.
*/
return FALSE;
if(!_mtinit()) /* initialize multi-thread */
{
/*
* If the DLL load is going to fail, we must clean up
* all resources that have already been allocated.
*/
_heap_term(); /* heap is now invalid! */
return FALSE; /* fail DLL load on failure */
}
if (_ioinit() < 0) { /* inherit file info */
/* Clean up already-allocated resources */
/* free TLS index, call _mtdeletelocks() */
_mtterm();
_heap_term(); /* heap is now invalid! */
return FALSE; /* fail DLL load on failure */
}
_aenvptr = (char *)__crtGetEnvironmentStringsA();
_acmdln = (char *)GetCommandLineA();
_wcmdln = (wchar_t *)__crtGetCommandLineW();
...
...
return TRUE;
}
BOOL WINAPI _DllMainCRTStartup(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
BOOL retcode = TRUE;
/*
* If this is a process detach notification, check that there has
* been a prior process attach notification.
*/
if ( (dwReason == DLL_PROCESS_DETACH) && (__proc_attached == 0) )
return FALSE;
if ( dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH )
{
if ( _pRawDllMain )
retcode = (*_pRawDllMain)(hDllHandle, dwReason, lpreserved);
if ( retcode )
retcode = _CRT_INIT(hDllHandle, dwReason, lpreserved);
if ( !retcode )
return FALSE;
}
retcode = DllMain(hDllHandle, dwReason, lpreserved);
if ( (dwReason == DLL_PROCESS_ATTACH) && !retcode )
/*
* The user's DllMain routine returned failure, the C runtime
* needs to be cleaned up. Do this by calling _CRT_INIT again,
* this time imitating DLL_PROCESS_DETACH. Note this will also
* clear the __proc_attached flag so the cleanup will not be
* repeated upon receiving the real process detach notification.
*/
_CRT_INIT(hDllHandle, DLL_PROCESS_DETACH, lpreserved);
if ( (dwReason == DLL_PROCESS_DETACH) ||
(dwReason == DLL_THREAD_DETACH) )
{
if ( _CRT_INIT(hDllHandle, dwReason, lpreserved) == FALSE )
retcode = FALSE ;
if ( retcode && _pRawDllMain )
retcode = (*_pRawDllMain)(hDllHandle, dwReason, lpreserved);
}
return retcode ;
}
dll crt 版本,都会先调用
BOOL WINAPI
_CRTDLL_INIT(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
/*
* The /GS security cookie must be initialized before any exception
* handling targetting the current image is registered. No function
* using exception handling can be called in the current image until
* after __security_init_cookie has been called.
*/
__security_init_cookie();
}
return __CRTDLL_INIT(hDllHandle, dwReason, lpreserved);
}
然后在 __CRTDLL_INIT(hDllHandle, dwReason, lpreserved); 会做一系列初始化
exe ,和dll都一样
dll版本在调用 _mainCRTStartup() 前就始化了_crtheap,
在crtlib.c的这个函数里
BOOL WINAPI
_CRTDLL_INIT(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
/*
* The /GS security cookie must be initialized before any exception
* handling targetting the current image is registered. No function
* using exception handling can be called in the current image until
* after __security_init_cookie has been called.
*/
__security_init_cookie();
}
return __CRTDLL_INIT(hDllHandle, dwReason, lpreserved);
}
你可以在这个函数里下一个断点,你会发现它先被调用才到 __tmainCRTStartup