diff --git a/reactos/lib/sdk/crt/msvcrtex.cmake b/reactos/lib/sdk/crt/msvcrtex.cmake index bf48060f62d..fb99ca0700d 100644 --- a/reactos/lib/sdk/crt/msvcrtex.cmake +++ b/reactos/lib/sdk/crt/msvcrtex.cmake @@ -66,7 +66,9 @@ elseif(ARCH MATCHES amd64) endif() if(MSVC) - list(APPEND MSVCRTEX_SOURCE startup/mscmain.c) + list(APPEND MSVCRTEX_SOURCE + startup/mscmain.c + startup/mscdllmain.c) else() list(APPEND MSVCRTEX_SOURCE startup/gccmain.c) endif() diff --git a/reactos/lib/sdk/crt/startup/crtdll.c b/reactos/lib/sdk/crt/startup/crtdll.c index ed3a73fd51d..019a834cf3c 100644 --- a/reactos/lib/sdk/crt/startup/crtdll.c +++ b/reactos/lib/sdk/crt/startup/crtdll.c @@ -50,7 +50,19 @@ extern _PVFV *__onexitend; extern int mingw_app_type; +/* + * It is possible that a DLL provides no DllMain entry point. + * Mark it as a weak symbol for GCC. + * Tests show that at link time, MSVC looks for a function first in the object files provided, and then + * in the libraries. This means that we must provide a basic implementation in msvcrtex, which will be used + * if none is found in the object files provided to link.exe. + * This also means that we can't rely on a DllMain function implemented in a static library when linking a DLL. + */ +#ifdef __GNUC__ +extern WINBOOL WINAPI DllMain (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) __attribute__((weak)); +#else extern WINBOOL WINAPI DllMain (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved); +#endif extern WINBOOL WINAPI DllEntryPoint (HANDLE, DWORD, LPVOID); @@ -198,10 +210,12 @@ __DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) } if (dwReason == DLL_PROCESS_ATTACH) __main (); - retcode = DllMain(hDllHandle,dwReason,lpreserved); + if(DllMain) + retcode = DllMain(hDllHandle,dwReason,lpreserved); if (dwReason == DLL_PROCESS_ATTACH && ! retcode) { - DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved); + if(DllMain) + DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved); DllEntryPoint (hDllHandle, DLL_PROCESS_DETACH, lpreserved); _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved); } diff --git a/reactos/lib/sdk/crt/startup/mscdllmain.c b/reactos/lib/sdk/crt/startup/mscdllmain.c new file mode 100644 index 00000000000..721e9457ab5 --- /dev/null +++ b/reactos/lib/sdk/crt/startup/mscdllmain.c @@ -0,0 +1,11 @@ +#include +#define _DECL_DLLMAIN +#include + +WINBOOL WINAPI DllMain (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) +{ + /* If the DLL provides no DllMain, then chances are that it doesn't bother with thread initialization */ + if(dwReason == DLL_PROCESS_ATTACH) + DisableThreadLibraryCalls(hDllHandle); + return TRUE; +}