📄 crtdll.c
字号:
#ifndef _SYSCRT
if (_initterm_e( __xi_a, __xi_z ) != 0)
return FALSE;
#else /* _SYSCRT */
_initterm((_PVFV *)(void *)__xi_a, (_PVFV *)(void *)__xi_z);
#endif /* _SYSCRT */
/*
* Invoke C++ constructors
*/
_initterm(__xc_a,__xc_z);
/*
* Set the native initialization state to initialized.
*/
__native_startup_state = __initialized;
}
if(!nested)
{
/* For X86, the definition of InterlockedExchangePointer wrongly causes warning C4312 */
#pragma warning(push)
#pragma warning(disable:4312)
InterlockedExchangePointer((volatile PVOID *)&__native_startup_lock,0);
#pragma warning(pop)
}
/*
* If we have any dynamically initialized __declspec(thread)
* variables, then invoke their initialization for the thread on
* which the DLL is being loaded, by calling __dyn_tls_init through
* a callback defined in tlsdyn.obj. We can't rely on the OS
* calling __dyn_tls_init with DLL_PROCESS_ATTACH because, on
* Win2K3 and before, that call happens before the CRT is
* initialized.
*/
if (__dyn_tls_init_callback != NULL &&
_IsNonwritableInCurrentImage((PBYTE)&__dyn_tls_init_callback))
{
__dyn_tls_init_callback(hDllHandle, DLL_THREAD_ATTACH,
lpreserved);
}
/* Enable buffer count checking if linking against static lib */
_CrtSetCheckCount(TRUE);
/*
* Increment the process attached flag.
*/
__proc_attached++;
}
else if ( dwReason == DLL_PROCESS_DETACH )
{
/*
* 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.
*/
/*
* do _onexit/atexit() terminators
* (if there are any)
*
* These terminators MUST be executed in
* reverse order (LIFO)!
*
* NOTE:
* This code assumes that __onexitbegin
* points to the first valid onexit()
* entry and that __onexitend points
* past the last valid entry. If
* __onexitbegin == __onexitend, the
* table is empty and there are no
* routines to call.
*/
void *lock_free=0;
void *fiberid=((PNT_TIB)NtCurrentTeb())->StackBase;
int nested=FALSE;
while((lock_free=InterlockedCompareExchangePointer((volatile PVOID *)&__native_startup_lock, fiberid, 0))!=0)
{
if(lock_free==fiberid)
{
nested=TRUE;
break;
}
/* some other thread is running native startup/shutdown during a cctor/domain unload.
Should only happen if this DLL was built using the Everett-compat loader lock fix in vcclrit.h
*/
/* wait for the other thread to complete init before we return */
Sleep(1000);
}
if(__native_startup_state!=__initialized)
{
/* somehow we are in a very bad state running shutdown when we have not started */
_amsg_exit( _RT_CRT_INIT_CONFLICT);
}
else
{
_PVFV * onexitbegin = (_PVFV *) DecodePointer(__onexitbegin);
if (onexitbegin)
{
_PVFV * onexitend = (_PVFV *) DecodePointer(__onexitend);
_PVFV function_to_call = NULL;
/* save the start and end for later comparison */
_PVFV * onexitbegin_saved = onexitbegin;
_PVFV * onexitend_saved = onexitend;
while (1)
{
_PVFV * onexitbegin_new = NULL;
_PVFV * onexitend_new = NULL;
/* find the last valid function pointer to call. */
while (--onexitend >= onexitbegin && (*onexitend == NULL || *onexitend == _encoded_null()))
{
/* keep going backwards. */
}
if (onexitend < onexitbegin)
{
/* there are no more valid entries in the list, we are done. */
break;
}
/* cache the function to call. */
function_to_call = (_PVFV) DecodePointer(*onexitend);
/* mark the function pointer as visited. */
*onexitend = (_PVFV)_encoded_null();
/* call the function, which can eventually change __onexitbegin and __onexitend */
(*function_to_call)();
onexitbegin_new = (_PVFV *) DecodePointer(__onexitbegin);
onexitend_new = (_PVFV *) DecodePointer(__onexitend);
if ( ( onexitbegin_saved != onexitbegin_new ) || ( onexitend_saved != onexitend_new ) )
{
/* reset only if either start or end has changed */
onexitbegin = onexitbegin_saved = onexitbegin_new;
onexitend = onexitend_saved = onexitend_new;
}
}
/*
* free the block holding onexit table to
* avoid memory leaks. Also zero the ptr
* variables so that they are clearly cleaned up.
*/
_free_crt ( onexitbegin ) ;
__onexitbegin = __onexitend = (_PVFV *)_encoded_null();
}
__native_startup_state = __uninitialized;
if(!nested)
{
/* For X86, the definition of InterlockedExchangePointer wrongly causes warning C4312 */
#pragma warning(push)
#pragma warning(disable:4312)
InterlockedExchangePointer((volatile PVOID *)&__native_startup_lock,0);
#pragma warning(pop)
}
}
}
return TRUE;
}
static
BOOL __cdecl
__DllMainCRTStartup(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
);
BOOL WINAPI
_DllMainCRTStartup(
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 __DllMainCRTStartup(hDllHandle, dwReason, lpreserved);
}
__declspec(noinline)
BOOL __cdecl
__DllMainCRTStartup(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
BOOL retcode = TRUE;
__try {
__native_dllmain_reason = dwReason;
__try{
/*
* 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) ) {
retcode = FALSE;
__leave;
}
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 )
__leave;
}
retcode = DllMain(hDllHandle, dwReason, lpreserved);
if ( (dwReason == DLL_PROCESS_ATTACH) && !retcode ) {
/*
* The user's DllMain routine returned failure. Unwind the init.
*/
DllMain(hDllHandle, DLL_PROCESS_DETACH, lpreserved);
_CRT_INIT(hDllHandle, DLL_PROCESS_DETACH, lpreserved);
if ( _pRawDllMain )
(*_pRawDllMain)(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);
}
}
} __except ( __CppXcptFilter(GetExceptionCode(), GetExceptionInformation()) ) {
retcode = FALSE;
}
} __finally
{
__native_dllmain_reason = __NO_REASON;
}
return retcode ;
}
#endif /* CRTDLL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -