From: Rémi Bernon rbernon@codeweavers.com
--- dlls/kernel32/kernel_main.c | 5 +++ dlls/kernelbase/main.c | 5 +++ dlls/ntdll/misc.c | 5 +++ dlls/win32u/main.c | 5 +++ dlls/winecrt0/crt_dllmain.c | 77 ++++++++++++++++++++++++++++++++++++- dlls/wow64/system.c | 5 +++ dlls/wow64cpu/cpu.c | 5 +++ dlls/wow64win/syscall.c | 5 +++ 8 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/kernel_main.c b/dlls/kernel32/kernel_main.c index ae16195a550..b7bfe4981b9 100644 --- a/dlls/kernel32/kernel_main.c +++ b/dlls/kernel32/kernel_main.c @@ -214,3 +214,8 @@ BOOL WINAPI GetSystemRegistryQuota(PDWORD pdwQuotaAllowed, PDWORD pdwQuotaUsed)
return TRUE; } + +BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) +{ + return DllMain( inst, reason, reserved ); +} diff --git a/dlls/kernelbase/main.c b/dlls/kernelbase/main.c index 60173ba6513..b687e84acfe 100644 --- a/dlls/kernelbase/main.c +++ b/dlls/kernelbase/main.c @@ -570,3 +570,8 @@ HRESULT WINAPI GetAcceptLanguagesW(WCHAR *langbuf, DWORD *buflen) *buflen = 0; return E_NOT_SUFFICIENT_BUFFER; } + +BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) +{ + return DllMain( inst, reason, reserved ); +} diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c index ab01c77531c..e5f0c886b66 100644 --- a/dlls/ntdll/misc.c +++ b/dlls/ntdll/misc.c @@ -501,3 +501,8 @@ ULONG WINAPIV EtwTraceMessage( TRACEHANDLE handle, ULONG flags, LPGUID guid, /*U va_end( valist ); return ret; } + +BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) +{ + return DllMain( inst, reason, reserved ); +} diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index 8e32fc63556..ca2ab58299d 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -2211,3 +2211,8 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved ) } return TRUE; } + +BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) +{ + return DllMain( inst, reason, reserved ); +} diff --git a/dlls/winecrt0/crt_dllmain.c b/dlls/winecrt0/crt_dllmain.c index 181760c884a..6c24908f037 100644 --- a/dlls/winecrt0/crt_dllmain.c +++ b/dlls/winecrt0/crt_dllmain.c @@ -25,9 +25,84 @@ #include "windef.h" #include "winbase.h"
+#include "corecrt_startup.h" + +#if defined(_MSC_VER) +#define _CRTALLOC(x) __declspec(allocate(x)) +#elif defined(__GNUC__) +#define _CRTALLOC(x) __attribute__((section(x))) +#else +#define _CRTALLOC(x) static /* unsupported */ +#endif + +_CRTALLOC(".CRT$XIA") void (*__xi_a)(void) = 0; +_CRTALLOC(".CRT$XIZ") void (*__xi_z)(void) = 0; +_CRTALLOC(".CRT$XCA") void (*__xc_a)(void) = 0; +_CRTALLOC(".CRT$XCZ") void (*__xc_z)(void) = 0; + +#if defined(__GNUC__) +extern void (*__CTOR_LIST__[])(void) __attribute__((weak)); +extern void (*__DTOR_LIST__[])(void) __attribute__((weak)); +#endif + +static CRITICAL_SECTION onexit_cs; +static CRITICAL_SECTION_DEBUG onexit_cs_debug = +{ + 0, 0, &onexit_cs, + { &onexit_cs_debug.ProcessLocksList, &onexit_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": onexit_cs") } +}; +static CRITICAL_SECTION onexit_cs = { &onexit_cs_debug, -1, 0, 0, 0, 0 }; +static _onexit_t *onexit_begin, *onexit_end; + +static void _CRT_INIT(void) +{ + void (**ctor)(void); + if ((ctor = &__xi_a)) while (++ctor != &__xi_z && *ctor) (*ctor)(); + if ((ctor = &__xc_a)) while (++ctor != &__xc_z && *ctor) (*ctor)(); +#if defined(__GNUC__) + if ((ctor = __CTOR_LIST__) && *ctor == (void *)-1) while (++ctor != __DTOR_LIST__ && *ctor) (*ctor)(); +#endif +} + +static _onexit_t dll_onexit( _onexit_t func, _onexit_t **start, _onexit_t **end ) +{ + int len = (*end - *start); + _onexit_t *tmp; + + if (!func || ++len <= 0) return NULL; + if (!(tmp = HeapReAlloc( GetProcessHeap(), 0, *start, len * sizeof(*tmp) ))) return NULL; + *start = tmp; + *end = tmp + len; + tmp[len - 1] = func; + + return func; +} + +int __cdecl atexit( void (__cdecl *func)(void) ) +{ + int ret; + EnterCriticalSection( &onexit_cs ); + ret = dll_onexit( (_onexit_t)func, &onexit_begin, &onexit_end ) == (_onexit_t)func; + LeaveCriticalSection( &onexit_cs ); + return ret; +} + BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) { - return DllMain( inst, reason, reserved ); + BOOL ret; + + if (reason == DLL_PROCESS_ATTACH) _CRT_INIT(); + + ret = DllMain( inst, reason, reserved ); + + if (reason == DLL_PROCESS_DETACH) + { + while (onexit_end-- > onexit_begin) (**onexit_end)(); + HeapFree( GetProcessHeap(), 0, onexit_begin ); + } + + return ret; }
#endif diff --git a/dlls/wow64/system.c b/dlls/wow64/system.c index 6e78c462984..355d10850d2 100644 --- a/dlls/wow64/system.c +++ b/dlls/wow64/system.c @@ -850,3 +850,8 @@ NTSTATUS WINAPI wow64_NtWow64GetNativeSystemInformation( UINT *args ) return STATUS_INVALID_INFO_CLASS; } } + +BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) +{ + return DllMain( inst, reason, reserved ); +} diff --git a/dlls/wow64cpu/cpu.c b/dlls/wow64cpu/cpu.c index c574315ec7d..abfa45e0667 100644 --- a/dlls/wow64cpu/cpu.c +++ b/dlls/wow64cpu/cpu.c @@ -436,3 +436,8 @@ NTSTATUS WINAPI BTCpuTurboThunkControl( ULONG enable ) /* we don't have turbo thunks yet */ return STATUS_SUCCESS; } + +BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) +{ + return DllMain( inst, reason, reserved ); +} diff --git a/dlls/wow64win/syscall.c b/dlls/wow64win/syscall.c index 55b9dec9722..2b2c0fe54dc 100644 --- a/dlls/wow64win/syscall.c +++ b/dlls/wow64win/syscall.c @@ -58,3 +58,8 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved ) NtCurrentTeb()->Peb->KernelCallbackTable = user_callbacks; return TRUE; } + +BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) +{ + return DllMain( inst, reason, reserved ); +}