136 lines
4.0 KiB
C
136 lines
4.0 KiB
C
/***
|
|
*_vcclrit.h
|
|
*
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
*
|
|
*Purpose:
|
|
* This file defines the functions and variables used by user
|
|
* to initialize CRT and the dll in IJW scenario.
|
|
*
|
|
****/
|
|
|
|
#pragma once
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
extern IMAGE_DOS_HEADER __ImageBase;
|
|
|
|
BOOL WINAPI _DllMainCRTStartup(
|
|
HANDLE hDllHandle,
|
|
DWORD dwReason,
|
|
LPVOID lpreserved
|
|
);
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#ifdef _cplusplus
|
|
#define __USE_GLOBAL_NAMESPACE ::
|
|
#else
|
|
#define __USE_GLOBAL_NAMESPACE
|
|
#endif
|
|
|
|
// Used to lock
|
|
__declspec( selectany ) LONG volatile __lock_handle = 0;
|
|
|
|
// Init called
|
|
__declspec(selectany) BOOL volatile __initialized = FALSE;
|
|
|
|
// Term called
|
|
__declspec( selectany ) BOOL volatile __terminated = FALSE;
|
|
|
|
__inline BOOL WINAPI __crt_dll_initialize()
|
|
{
|
|
// Try to make the variable names unique, so that the variables don't even clash with macros.
|
|
static BOOL volatile (__retval) = FALSE;
|
|
static DWORD volatile (__lockThreadId) = 0xffffffff;
|
|
DWORD volatile (__currentThreadId) = __USE_GLOBAL_NAMESPACE(GetCurrentThreadId)();
|
|
int (__int_var)=0;
|
|
|
|
// Take Lock, This is needed for multithreaded scenario. Moreover the threads
|
|
// need to wait here to make sure that the dll is initialized when they get
|
|
// past this function.
|
|
while ( __USE_GLOBAL_NAMESPACE(InterlockedExchange)( &(__lock_handle), 1) == 1 )
|
|
{
|
|
++(__int_var);
|
|
if ((__lockThreadId) == (__currentThreadId))
|
|
{
|
|
return TRUE;
|
|
}
|
|
__USE_GLOBAL_NAMESPACE(Sleep)( (__int_var)>1000?100:0 );
|
|
|
|
// If you hang in this loop, this implies that your dllMainCRTStartup is hung on another
|
|
// thread. The most likely cause of this is a hang in one of your static constructors or
|
|
// destructors.
|
|
}
|
|
// Note that we don't really need any interlocked stuff here as the writes are always
|
|
// in the lock. Only reads are outside the lock.
|
|
(__lockThreadId) = (__currentThreadId);
|
|
__try {
|
|
|
|
if ( (__terminated) == TRUE )
|
|
{
|
|
(__retval) = FALSE;
|
|
}
|
|
else if ( (__initialized) == FALSE )
|
|
{
|
|
(__retval) = (_DllMainCRTStartup)( ( HINSTANCE )( &__ImageBase ), DLL_PROCESS_ATTACH, 0 );
|
|
(__initialized) = TRUE;
|
|
}
|
|
|
|
} __finally {
|
|
// revert the __lockThreadId
|
|
(__lockThreadId) = 0xffffffff;
|
|
// Release Lock
|
|
__USE_GLOBAL_NAMESPACE(InterlockedExchange)( &(__lock_handle), 0 );
|
|
}
|
|
return (__retval);
|
|
}
|
|
|
|
__inline BOOL WINAPI __crt_dll_terminate()
|
|
{
|
|
static BOOL volatile (__retval) = TRUE;
|
|
static DWORD volatile (__lockThreadId) = 0xffffffff;
|
|
DWORD volatile (__currentThreadId) = __USE_GLOBAL_NAMESPACE(GetCurrentThreadId)();
|
|
int (__int_var)=0;
|
|
|
|
// Take Lock, this lock is needed to keep Terminate in sync with Initialize.
|
|
while ( __USE_GLOBAL_NAMESPACE(InterlockedExchange)( &(__lock_handle), 1) == 1 )
|
|
{
|
|
++(__int_var);
|
|
if ((__lockThreadId) == (__currentThreadId))
|
|
{
|
|
return TRUE;
|
|
}
|
|
__USE_GLOBAL_NAMESPACE(Sleep)( (__int_var)>1000?100:0 );
|
|
|
|
// If you hang in this loop, this implies that your dllMainCRTStartup is hung on another
|
|
// thread. The most likely cause of this is a hang in one of your static constructors or
|
|
// destructors.
|
|
}
|
|
// Note that we don't really need any interlocked stuff here as the writes are always
|
|
// in the lock. Only reads are outside the lock.
|
|
(__lockThreadId) = (__currentThreadId);
|
|
__try {
|
|
|
|
if ( (__initialized) == FALSE )
|
|
{
|
|
(__retval) = FALSE;
|
|
}
|
|
else if ( (__terminated) == FALSE )
|
|
{
|
|
(__retval) = _DllMainCRTStartup( ( HINSTANCE )( &(__ImageBase) ), DLL_PROCESS_DETACH, 0 );
|
|
(__terminated) = TRUE;
|
|
}
|
|
|
|
} __finally {
|
|
// revert the __lockThreadId
|
|
(__lockThreadId) = 0xffffffff;
|
|
// Release Lock
|
|
__USE_GLOBAL_NAMESPACE(InterlockedExchange)( &(__lock_handle), 0 );
|
|
}
|
|
return (__retval);
|
|
}
|