Is there a way to somehow control the order DLLs are loaded? This is mainly related to the limitation one must obey while present within DllMain() function.
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
SHGetKnownFolderPath()
}
case DLL_PROCESS_DETACH:
{
DllMainProcessDetach(hinstDLL, lpReserved);
return TRUE;
}
default:
break;
}
return TRUE;
}
In that particular code, i use SHGetKnownFolderPath() to retrieve a certain directory, Once SHGetKnownFolderPath is executed, i get the following call stack:
after disassembling stack's code, i realized the problematic call is Ole32's CoTaskMemAlloc() function.
So i once again set another debugging session with only 1 function called within DllMain() : CoTaskMemAlloc() and disassembled the code:
EAX register which holds g_pMalloc's address is null, which appears not to be initialized by dllcrt.
I don't think you can safely call shell functions in DllMain
. There is a long list of things you can't do due to the way process initialization is done in Windows.
You should never perform the following tasks from within DllMain
:
Call LoadLibrary
or LoadLibraryEx
(either directly or indirectly).
This can cause a deadlock or a crash.
Call GetStringTypeA
, GetStringTypeEx
, or GetStringTypeW
(either
directly or indirectly). This can cause a deadlock or a crash.
CoInitializeEx
. Under certain
conditions, this function can call LoadLibraryEx
. CreateProcess
. Creating a process can load another DLL. ExitThread
. Exiting a thread during DLL detach can cause the
loader lock to be acquired again, causing a deadlock or a crash. CreateThread
. Creating a thread can work if you do not
synchronize with other threads, but it is risky. The following tasks are safe to perform within DllMain
:
NULL
, putting off the initialization of
dynamic members. In Microsoft Windows Vista™, you can use the
one-time initialization functions to ensure that a block of code is
executed only once in a multithreaded environment.