CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Dec 2002
    Location
    La Plata, Buenos Aires
    Posts
    615

    SetEvent not signalling in hooked DLL

    I'm doing IPC between an EXE program and a DLL which is injected into another process via SetWindowsHookEx.

    The problem is that I want to the DLL to unload when the main EXE quits, I'm doing that in the WM_CLOSE message:

    Code:
    LRESULT MsgClose(HWND hwnd)
    {
    	dprintf(L"Closing.");
    
    	SetEvent(g_hQuitEvent);
    	WaitForSingleObject(g_thRegNotify, INFINITE);
    	CloseHandle(g_thRegNotify);
    	CloseHandle(g_hQuitEvent);	
    
    	UnhookWinEvent(g_hEvtHook);
    
    	dprintf(L"Removing mailslot mappings\n");
    
    	for (std::map<DWORD,HANDLE>::iterator it = g_mailslotMap.begin(); 
    		it != g_mailslotMap.end(); ++it)
    	{
    		CloseHandle(it->second);
    	}
    
    	dprintf(L"Unhooking processes...\n");
    
    	for (std::set<HHOOK>::iterator it = g_hHookSet.begin();
    		it != g_hHookSet.end(); ++it)
    	{
    		UnhookWindowsHookEx(*it);
    	}
            if (g_hLib32) 
    		FreeLibrary(g_hLib32);
    The DLL hook contains a thread that listens for two evetns: mailslot messages and the quit event with WaitForMultipleObjects:

    Code:
    	do
    	{
    		OVERLAPPED ov;
    		ZeroMemory(&ov,sizeof(ov));
    
    		hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    		ov.hEvent = hEvent;
    
    		if (!ReadFile(g_hMailSlot, &ipcMsg, sizeof(IPCMESSAGE), 0, &ov))
    		{
    			if (GetLastError() != ERROR_IO_PENDING)
    			{
    				dprintf(L" ReadFile FAILED with error %d\n",GetLastError());
    				bContinue = FALSE;
    				rv = GetLastError();
    			}			
    		}
    
    		HANDLE waitEvents[2] = { hEvent, g_hQuitEvent };
    		DWORD wo = WaitForMultipleObjects(2, waitEvents, FALSE, INFINITE); 
    
    		if (wo - WAIT_OBJECT_0 == 1)
    		{
    			dprintf(L" (mailslot thread) Quit event signaled.\n");
    			bContinue = FALSE;			
    		}
    		else
    		{
    			// Process mailslot message
    ...
    ...
    ...
    At DLL exit I perform:

    Code:
    if (g_hMailSlot && g_hMailSlotThread)
    {
    	SetEvent(&g_hQuitEvent);	
    	WaitForSingleObject(g_hMailSlotThread, INFINITE);
    	CloseHandle(g_hMailSlotThread);
    }
    
    dprintf(L"   Mailslot thread terminated.\n");
    If I close the process that the DLL resides in, the g_hQuitEvent is signalled properly. But not when hooking is removed via closing the main EXE.

    Any idea as where I can look? The thread awaits at the WaitForSingleObject line marked above, halting the hosting EXE.

    Thanks in advance.

  2. #2
    Join Date
    Nov 2003
    Posts
    1,902

    Re: SetEvent not signalling in hooked DLL

    You can't wait on a thread handle while in the context of DllMain. The state of the thread handle will never change while the loader lock is being held. This includes global object constructors and destructors.

    http://www.microsoft.com/whdc/driver..._bestprac.mspx

    gg

  3. #3
    Join Date
    Dec 2002
    Location
    La Plata, Buenos Aires
    Posts
    615

    Re: SetEvent not signalling in hooked DLL

    Thank you very much Codeplug.

    I removed the fatal calls from DllMain, but i'm still with the problem of how the following can be achieved:

    1) External EXE posts a (e.g: DLL_UNLOAD_REQUEST) message to a known mailslot.
    2) The injected DLL receives the mailslot message in a worker thread.
    3) This DLL must do something to finalize this worker thread. If this not succeeds, the injected process won't exit later since the DLL contains a WaitForSingleObject call on process exit. The intention is to unload the DLL without killing the hosting process, when the external EXE is closed (I handle WM_CLOSE).

    I've devised some synchronization scheme as follows:

    - EXE sends request to unload DLL and waits for some signal to continue safely (prior to UnhookWindowsHookEx) -- eg: wait on a global "\\SafeToUnload" named event or a message posted to it's queue (alternatives?).

    - Worker thread in injected DLL finalizes itself (preventing locking process waiting for it's thread handle) and signals the event / sends message to EXE app queue to notify that the thread has exited.

    - Now main EXE can safely go with UnhookWindowsHookEx.

    Ideas?

    EDIT: The problem is that when the EXE is running without injected DLLs (this is possible). Termination will lock on waiting for some injected DLL to set the event. I'm sure this can be solved with an array of events for each injected DLL handle. If no injected DLLs = no events available, exits normally.
    Last edited by indiocolifa; January 6th, 2011 at 11:14 PM.

  4. #4
    Join Date
    Dec 2002
    Location
    La Plata, Buenos Aires
    Posts
    615

    Re: SetEvent not signalling in hooked DLL

    Solved.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured