Loading DLLs in in DLLMAIN() / DLL_PROCESS_ATTACH may cause trouble. But may COM Objects be instanced using e.q. CoInitialize() / CoCreateInstance()?
EDIT: The question is:
Could creating COM instances cause similar errors like loading DLLs in this circumstances?
Loading DLLs an creating COM instances seem to me similar in a way.
I'm not sure where you got that quote from, but it doesn't sound right.
You should never put any code of any significance into DllMain. Especially code that invokes LoadLibrary. Many Windows APIs will call LoadLibrary under the hood, so it's best to avoid doing any complex initialization here. Use a global C++ object (for it's constructor) or better yet, export a function for initialization.
CoCreateInstance for in-proc components ultimately will call LoadLibrary or one of its variants. It would not be wise to call this function in DllMain either.
Related
I have been writing a C++ program where I am creating a shortcut link for an exe file, and to do that I need to write the CoInitialize(0); at the starting. And without it the code does not work. Can someone help me to know why we use it?
I just want to know why we use this function.
CoInitialize(), and the extended and more recommended version CoInitializeEx(), are used to initialize the COM library for the current thread:
Initializes the COM library on the current thread
...
New applications should call CoInitializeEx instead of CoInitialize.
It has to be called for each thread that uses COM.
Note that CoInitialize() identifies the concurrency model as single-thread apartment (STA), whereas with CoInitializeEx() you have the freedom to specify the concurrency model.
More about COM threads and other related issues: Processes, Threads, and Apartments.
In case you are not familiar with COM (from the documentation):
COM is a platform-independent, distributed, object-oriented system for creating binary software components that can interact. COM is the foundation technology for Microsoft's OLE (compound documents) and ActiveX (Internet-enabled components) technologies.
If your program requires calling one of the initialization functions above, it means that either you directly, or any library you use, are using COM.
Note that each successful call to CoInitialize/Ex() must be matched with a call to CoUninitialize().
Edit:
As #IInspectable commented, using a COM object on a thread does not strictly require calling CoInitialize/Ex().
But, since COM objects have threading requirements as noted above, calling it ensures that the current thread uses the proper COM concurrency model.
See Why does CoCreateInstance work even though my thread never called CoInitialize? The curse of the implicit MTA.
I need to destroy some objects when my DLL is unloaded. This object contains a thread that sometimes calls the WSASocket function (for reconnecting a connection). So, I call the destructor from DllMain in response to DLL_PROCESS_DETACH, but that causes my application to hang. Specifically, the call to WSASocket locks up.
I know that some functions cannot be called from DllMain, especially functions that call LoadLibrary and FreeLibrary. But why does the WSASocket function have this same problem?
It's because you shouldn't use DllMain for that cause. Many system procs will cause a deadlock being called from DllMain. Declare an additional export proc especially for deinitialization of your dll and call it right before FreeLibrary.
Also, I recommend you to read "Best Dll Practices" by MSFT. There are a lot of reasons to stay away from DllMain.
In c++ ,I want to hook more than one dll to a process. Right now I use CreateProcesswithdll() which can hook only one api at a time. What can I do to inject multiple dlls?
I came across this problem because MS detours requires us to name our custom dll the same as original dll in order to properly detour the api calls. So even though i could have different api calls handled in the same detour dll I created I need to have different names to hook calls from different apis, which means I need different detour Dlls. This also means I need to inject different DLLs. Am I right?
If I am unclear about something I will try to present it more clearly :D
Thanks!
P.S: Just to make my problem more lucid. I need to inject more than 1 dll onto the same process. CreateProcesswithdll() creates a new process with its thread in sleep state. It is woken up after the detours has finished injecting the dll and setting up the hooks. If I want to inject more than one dll I obviously cant repeatedly call CreateProcesswithdll()
so what do i do?? or Is my understanding about some aspect of this wrong?
Calling LoadLibrary() and FreeLibrary() is NOT SAFE from DLLMain(). From TFA:
"The entry-point function should
perform only simple initialization or
termination tasks. It must not call
the LoadLibrary or LoadLibraryEx
function (or a function that calls
these functions), because this may
create dependency loops in the DLL
load order. This can result in a DLL
being used before the system has
executed its initialization code.
Similarly, the entry-point function
must not call the FreeLibrary function
(or a function that calls FreeLibrary)
during process termination, because
this can result in a DLL being used
after the system has executed its
termination code."
EDIT: Apologies - this was meant as a comment for Serge's answer above.
Seems like detourattach and detourdetach will do the trick for me. Thanks everyone!
I found this blog useful!
Obviously you can load any number of DLLs from the first DLL you inject with detours.
EDIT.
When DLL is loaded system runs DllMain of your DLL (with fdwReason==DLL_PROCESS_ATTACH) and then within that function you can do whatever you like, e.g. you can call LoadLibrary to load other DLLs.
ADD:
I totally agree with comments that calling LoadLibrary from DllMain is unsafe. So you can call LoadLibrary (and all the other tricky things) from thread created in DllMain.
I have got a DLL in which a singleton is defined.
I have got an app which can load multiple instances of this DLL.
The DLL needs a singleton instance per DLL instance, otherwise it will crash.
I observed that there was only one singleton instance for multiple DLL instances. Why? How can I resolved it (if possible, without refactoring the singleton into something else)?
Thanks for any help.
You mentioned that you have multiple instances inside your app, which implies that they all live inside the same process.
Singletons like any other static member are limited to one per application regardless of whether they belong to an object loaded from a DLL etc.
No way without refactoring your code. A DLL is "loaded" into the process space. Any static member defined in there is static for the process (a loaded DLL doesn't have its own memory).
You'll have to write a non-standard "singleton" to get multiple objects.
And if you don't have the sources to the dll, then you must load it in different processes, one "singleton" per process. These could be simple child-processes to your main process that just handle the dll communication part.
Then of course, you must come with some communication scheme between your main process and your child processes, which will depend on how much you are using the dll. Is it just a couple of calls with a lot of data? Or a lot of different calls that differ from run to run?
Generally if you are using the dll to make more than a couple of simple calls it's probably easier to refactor your own code.
I'm faced with the problem that my applications global variable destructors are not called. This seems to occur only if my application successfully connects to an oracle database (using OCI).
I put some breakpoints in the CRT and it seems that DllMain (or __DllMainCRTStartup) is not called with DLL_PROCESS_DETACH, thus no atexit() is called which explains why my destructors are not called.
I have no idea why this happens.
I realize that this is probably not enough information to be able to indicate the cause, but my question is: What would be a good start to look for the cause of this problem?
This is a list of things I already tried:
search the net for solutions
attached the debugger and enable native exceptions to see there was no hidden crash, sometimes I get an exception in the .Net framework, but the app seems to continue.
try to reproduce in a small application, no success
The most common situation I encounter where this occurs is a program crash. In certain circumstances crashes can happen silently from an end user perspective. I would attach a debugger to the program, set it to break on all native exceptions and run the scenario.
It's possible that someone is calling TerminateProcess, which unlike ExitProcess does not notify DLLs of shutdown.
This might be helpful:
What happens to global variables declared in a DLL?
Are your globals declared inside a dll, or in your application's memory space?
Calling theexit API often means that the application exits without calling destructors. I an not sure that VC does in this case.
Also try avoid using global objects. This is because you have little control over when and in what order the constructors and destructors are called. Rather convert the objects into pointers and initialise and destroy the pointers using the appropriate DllMain hooks. Since DllMain is an OS construct and not a language construct, it should prove more reliable in the case of normal exits.