Click here to Skip to main content
15,891,946 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello guys

I have a problem with an out of process COM-server. I inject a DLL into a foreign process and this DLL registers some Classes as local servers. This is done in the following way:
1. For each object the following registry entries are created:
HKLM\SOFTWARE\Classes\CLSID\{GUID OF CLASS}\LocalServer32 and its default value is set to the path of the executable of the foreign process.

2. For each object CoRegisterClassObject is called like that:
CoRegisterClassObject(riid, static_cast<IUnknown*>(factory), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &token); So far this call always returned S_OK.

3. After all objects are registered CoResumeClassObjects is called and the message loop is entered.

Now the consuming application wants to create such an object and calls CoCreateInstance with CLSCTX_LOCAL_SERVER. Even tough the foreign process is running and has registered its objects the process is started again (at least it means that the object was correctly put in the registry) and the request is not sent to the already running one. But whats the reason for that beahaviour? Did i forget something about telling the OS that my objects are available?

On a sidenote there is another weird thing. If i remove the message loop and replace it with a WaitForSingleObject in the following way:
HANDLE hEvent = NULL;
unsigned long __stdcall ServerThread(LPVOID)
{
	CoInitialize(NULL);
	REG_CLASS(TestClass);
	CoResumeClassObjects();
	MSG msg;
	hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	/*while(GetMessage(&msg, 0, 0, 0) > 0)
	{
		std::cout << msg.message << std::endl;
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}*/
	std::cout << "Waiting for event" << std::endl;
	WaitForSingleObject(hEvent, INFINITE);
	std::cout << "Event set!" << std::endl;
	UNREG_CLASS(TestClass);
	ExitThread(0);
}


And try to set it in DllMain like that:
BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
{
	if(reason == DLL_PROCESS_DETACH)
	{
		if(hEvent != NULL)
		{
			SetEvent(hEvent);
			std::cin.get();
		}
	}
	return TRUE;
}


I get the output that its waiting for the event and with other outputs i also see that SetEvent returns TRUE but "Event set" is never printed to the console. Why is the event not working? I also checked that the events are the same and they are.

Thanks for any help
Regner
Posted
Updated 6-Jun-11 22:42pm
v2

Well, my own "temporary" solution to the problem is the following:
The problem was that i started my foreign process as administrator and the consumer client just as invoker. If i start the foreign process as invoker it gets detected and requests are delagated to it.

I guess that i have to provide some sort of security options allowing processes on lower levels to connect to my process. Or is that impossible with UAC?
 
Share this answer
 
It is really unclear where the hEvent comes from in your DllMain. You cannot share local handles between processes. You should create the event object by name and this should work.
// exe
HANDLE h = CreateEvent(0,0,0,AnyGuid());
WaitForSingleObject(h,INFINITE);
CloseHandle(h);

// dll
HANDLE h = CreateEvent(0,0,0,SameGuidAsEXE());
SetEvent(h);
CloseHandle(h);


regards.
 
Share this answer
 
Comments
Regner44 9-Jun-11 10:13am    
The problem was the following:
DllMain gets called with DLL_PROCESS_DETACH when all the threads are already shut down. So setting the even there wont cause any effect as the thread aint running anymore.
mbue 9-Jun-11 12:42pm    
Im afraid that i dont understand your intention. You can anytime- anwhere- from signal an event to another process. The event needs the neccessary access rigts to signal (see the naming conventions). You can tell your DLL the event name via function call parameter, so it can set the event on unloading (DLL_PROCESS_DETACH) the DLL. I tell it again: do not share any handle among processes.
Regards.
Regner44 9-Jun-11 12:52pm    
Hi mbue,

The handles are not shared among processes. The problem is that if my DLL is about to get unloaded in the process because the process is about to exit it calls Dllmain after it has terminated all threads. So actually when i set my event so that the thread can continue the thread already has been shut down by the system.
mbue 9-Jun-11 13:34pm    
A COM Server is starting by call CoCreateInstance, then the EXE will will wait for about 5000 ms (Microsoft COM server template in MFC) if the interfaces are not longer in use. Thats a thread is still waiting for a ref count becomes zero. If there are no further requests about the interfaces - the EXE server will shut down. To prevent the server from shutting down you have to AddRef one of the interfaces he provide. The are no external events or handles the exe is waiting for. The only thing to keep the COM-EXE alive is to hold an interface pointer. If there is no Release to that interfaces the server will never terminate (shutdown). So i had a problem with a product used by a C# environment their garbage collector never terminated my COM exe.
But be aware from usage of interfaces by loaded modules to prevent circular references. So you should define a common event object name the server can wait for until all loaded modules (DLL) and their threads are ready for unload. Usually COM uses the DllCanUnloadNow function to determine the module can be unloaded. Therefore you have to increment a global ref-count for critical objects or threads.
Regards.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900