Discussion:
CoGetObject() can not be called during DLL_PROCESS_ATTACH?
(too old to reply)
JJ
2022-04-20 19:50:00 UTC
Permalink
I'm trying to use a third party COM object in a DLL when the DLL is being
loaded (i.e. at DLL_PROCESS_ATTACH stage).

The COM object is instantiated using CoGetObject() like below, but it hangs.
For the sake of reproducing the problem in any system, the WMI service
object is used as an example.

CoInitializeEx(NULL, COINIT_MULTITHREADED); //returns zero. already checked.
CoGetObject(L"winmgmts:", NULL, IID_IDispatch, &pObj); //it hangs
//code execution never reached here

The code works fine if it's executed from an exported DLL function and
called by the host process, after LoadLibrary() returns.

What's went wrong? Is there a solution? Or is it that, CoGetObject() can not
be used during DLL_PROCESS_ATTACH?

Note: WMI has `WbemScripting.SWbemLocator` alternative class name for use
with CoCreateInstance(). The third party COM object I'm actually using, does
not have any alternative class name which is usable with CoCreateInstance().
So, I can not use CoCreateInstance().
Apd
2022-04-20 23:00:12 UTC
Permalink
Post by JJ
I'm trying to use a third party COM object in a DLL when the DLL is being
loaded (i.e. at DLL_PROCESS_ATTACH stage).
Seems like a bad idea. Have you read the warnings for DllMain? You
can't use anything tha calls LoadLibrary.

This extract from an old MSDN:

"Warning On attach, the body of your DLL entry-point function should
perform only simple initialization tasks,
[...]
Calling functions other than TLS, object-creation, and file functions
may result in problems that are difficult to diagnose. For example,
calling User, Shell, COM, RPC, and Windows Sockets functions (or any
functions that call these functions) can cause access violation
errors, because their DLLs call LoadLibrary to load other system
components".

Note the mention of COM.
JJ
2022-04-21 20:44:57 UTC
Permalink
Post by Apd
Post by JJ
I'm trying to use a third party COM object in a DLL when the DLL is being
loaded (i.e. at DLL_PROCESS_ATTACH stage).
Seems like a bad idea. Have you read the warnings for DllMain? You
can't use anything tha calls LoadLibrary.
"Warning On attach, the body of your DLL entry-point function should
perform only simple initialization tasks,
[...]
Calling functions other than TLS, object-creation, and file functions
may result in problems that are difficult to diagnose. For example,
calling User, Shell, COM, RPC, and Windows Sockets functions (or any
functions that call these functions) can cause access violation
errors, because their DLLs call LoadLibrary to load other system
components".
Note the mention of COM.
Darn. I forgot about it. Thank you both for reminding me that.

Currently, I just use an initialization function which is conditionally
called at start of all exported functions, to make sure that the COM object
is already exist before the functions do their main task.

Pity that, there's no mechanism for an auto-called DLL function after the
DLL has been loaded.
Apd
2022-04-21 23:48:24 UTC
Permalink
Post by JJ
Post by Apd
Note the mention of COM.
Darn. I forgot about it. Thank you both for reminding me that.
Currently, I just use an initialization function which is conditionally
called at start of all exported functions, to make sure that the COM
object is already exist before the functions do their main task.
Pity that, there's no mechanism for an auto-called DLL function after
the DLL has been loaded.
What you're doing is the same as an MSDN suggestion. They mention
using a named mutex to check if the init has been done.
JJ
2022-04-22 14:57:37 UTC
Permalink
Post by Apd
What you're doing is the same as an MSDN suggestion. They mention
using a named mutex to check if the init has been done.
How does a mutex take part in this mechanism? Cause in my case, the host
process' thread which call LoadLibrary() to load my DLL, use the same thread
for calling the exported DLL function. If mutex is was created by the
DllMain(), it won't be signalled when the host process calls the exported
DLL function.
Apd
2022-04-22 15:50:11 UTC
Permalink
Post by JJ
Post by Apd
What you're doing is the same as an MSDN suggestion. They mention
using a named mutex to check if the init has been done.
How does a mutex take part in this mechanism? Cause in my case, the host
process' thread which call LoadLibrary() to load my DLL, use the same
thread for calling the exported DLL function. If mutex is was created by
the DllMain(), it won't be signalled when the host process calls the
exported DLL function.
This from MSDN:
"have the initialization routine create a named mutex, and have each
routine in the DLL call the initialization routine if the mutex does
not exist".

So it's only a matter of checking for the presence of one. You could
probably use some other system or process-wide object like an atom.
R.Wieser
2022-04-21 07:28:49 UTC
Permalink
JJ
Post by JJ
What's went wrong? Is there a solution? Or is it that, CoGetObject()
can not be used during DLL_PROCESS_ATTACH?
Likely exactly that. To extend upon Apds response, I think the relevant
part to it is named here :

https://docs.microsoft.com/en-us/windows/win32/api/objbase/nf-objbase-coinitialize

"Because there is no way to control the order in which in-process servers
are loaded or unloaded, do not call CoInitialize, CoInitializeEx, or
CoUninitialize from the DllMain function."

Regards,
Rudy Wieser
Loading...