mirror of
https://github.com/reactos/reactos.git
synced 2024-08-30 23:28:58 +00:00
220 lines
5.5 KiB
C
220 lines
5.5 KiB
C
/**
|
|
* This file has no copyright assigned and is placed in the Public Domain.
|
|
* This file is part of the w64 mingw-runtime package.
|
|
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
|
|
*/
|
|
|
|
#ifdef CRTDLL
|
|
#undef CRTDLL
|
|
#ifndef _DLL
|
|
#define _DLL
|
|
#endif
|
|
|
|
#include <oscalls.h>
|
|
#include <internal.h>
|
|
#include <stdlib.h>
|
|
//#include <windows.h>
|
|
#define _DECL_DLLMAIN
|
|
#include <process.h>
|
|
#include <crtdbg.h>
|
|
|
|
#ifndef _CRTIMP
|
|
#ifdef CRTDLL
|
|
#define _CRTIMP __declspec(dllexport)
|
|
#else
|
|
#ifdef _DLL
|
|
#define _CRTIMP __declspec(dllimport)
|
|
#else
|
|
#define _CRTIMP
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#include <sect_attribs.h>
|
|
#include <locale.h>
|
|
|
|
extern void __cdecl _initterm(_PVFV *,_PVFV *);
|
|
extern void __main ();
|
|
extern void _pei386_runtime_relocator (void);
|
|
extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a[];
|
|
extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];
|
|
extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
|
|
extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];
|
|
|
|
/* TLS initialization hook. */
|
|
extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
|
|
|
|
static int __proc_attached = 0;
|
|
|
|
extern _PVFV *__onexitbegin;
|
|
extern _PVFV *__onexitend;
|
|
|
|
extern int mingw_app_type;
|
|
|
|
extern WINBOOL WINAPI DllMain (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved);
|
|
|
|
extern WINBOOL WINAPI DllEntryPoint (HANDLE, DWORD, LPVOID);
|
|
|
|
static int __cdecl pre_c_init (void);
|
|
|
|
_CRTALLOC(".CRT$XIAA") _PIFV pcinit = pre_c_init;
|
|
|
|
static int
|
|
__cdecl
|
|
pre_c_init (void)
|
|
{
|
|
_PVFV *onexitbegin;
|
|
|
|
onexitbegin = (_PVFV *) malloc (32 * sizeof (_PVFV));
|
|
__onexitend = __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin);
|
|
|
|
if (onexitbegin == NULL)
|
|
return 1;
|
|
*onexitbegin = (_PVFV) NULL;
|
|
return 0;
|
|
}
|
|
|
|
WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
|
|
{
|
|
if (dwReason == DLL_PROCESS_DETACH)
|
|
{
|
|
if (__proc_attached > 0)
|
|
__proc_attached--;
|
|
else
|
|
return FALSE;
|
|
}
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
{
|
|
void *lock_free = NULL;
|
|
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;
|
|
}
|
|
Sleep(1000);
|
|
}
|
|
if (__native_startup_state == __initializing)
|
|
{
|
|
_amsg_exit (31);
|
|
}
|
|
else if (__native_startup_state == __uninitialized)
|
|
{
|
|
__native_startup_state = __initializing;
|
|
|
|
_initterm ((_PVFV *) (void *) __xi_a, (_PVFV *) (void *) __xi_z);
|
|
}
|
|
if (__native_startup_state == __initializing)
|
|
{
|
|
_initterm (__xc_a, __xc_z);
|
|
__native_startup_state = __initialized;
|
|
}
|
|
if (! nested)
|
|
{
|
|
(void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
|
|
}
|
|
if (__dyn_tls_init_callback != NULL)
|
|
{
|
|
__dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved);
|
|
}
|
|
__proc_attached++;
|
|
}
|
|
else if (dwReason == DLL_PROCESS_DETACH)
|
|
{
|
|
void *lock_free = NULL;
|
|
while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,(PVOID) 1, 0)) != 0)
|
|
{
|
|
Sleep(1000);
|
|
}
|
|
if (__native_startup_state != __initialized)
|
|
{
|
|
_amsg_exit (31);
|
|
}
|
|
else
|
|
{
|
|
_PVFV * onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
|
|
if (onexitbegin)
|
|
{
|
|
_PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend);
|
|
while (--onexitend >= onexitbegin)
|
|
if (*onexitend != NULL)
|
|
(**onexitend) ();
|
|
free (onexitbegin);
|
|
__onexitbegin = __onexitend = (_PVFV *) NULL;
|
|
}
|
|
__native_startup_state = __uninitialized;
|
|
(void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static WINBOOL __DllMainCRTStartup (HANDLE, DWORD, LPVOID);
|
|
|
|
WINBOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID);
|
|
int __mingw_init_ehandler (void);
|
|
|
|
WINBOOL WINAPI
|
|
DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
|
|
{
|
|
mingw_app_type = 0;
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
{
|
|
__security_init_cookie ();
|
|
#ifdef _WIN64
|
|
__mingw_init_ehandler ();
|
|
#endif
|
|
}
|
|
return __DllMainCRTStartup (hDllHandle, dwReason, lpreserved);
|
|
}
|
|
|
|
__declspec(noinline) WINBOOL
|
|
__DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
|
|
{
|
|
WINBOOL retcode = TRUE;
|
|
|
|
__native_dllmain_reason = dwReason;
|
|
if (dwReason == DLL_PROCESS_DETACH && __proc_attached == 0)
|
|
{
|
|
retcode = FALSE;
|
|
goto i__leave;
|
|
}
|
|
_pei386_runtime_relocator ();
|
|
if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH)
|
|
{
|
|
retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved);
|
|
if (!retcode)
|
|
goto i__leave;
|
|
retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved);
|
|
if (! retcode)
|
|
{
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
_CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
|
|
goto i__leave;
|
|
}
|
|
}
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
__main ();
|
|
retcode = DllMain(hDllHandle,dwReason,lpreserved);
|
|
if (dwReason == DLL_PROCESS_ATTACH && ! retcode)
|
|
{
|
|
DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
|
|
DllEntryPoint (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
|
|
_CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
|
|
}
|
|
if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
|
|
{
|
|
retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved);
|
|
if (_CRT_INIT (hDllHandle, dwReason, lpreserved) == FALSE)
|
|
retcode = FALSE;
|
|
}
|
|
i__leave:
|
|
__native_dllmain_reason = UINT_MAX;
|
|
return retcode ;
|
|
}
|
|
#endif
|