[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1223
  • Last Modified:

FreeLibrary and DLLMain

Now, I have a DLL (DLL A) that calls a second DLL (DLL B) to build a function upcall table.  These functions are used throughout the life of DLL A by other external processes.  Now, my question is...  since this upcall table needs to be valid for the lifetime of DLL A, how can I free the reference to DLL B since I cannot call FreeLibrary from DllMain during PROCESS_DETACH?

I do not have access to the other applications that use this upcall table, so the idea of having a special function called prior to unload that would clean everything up isn't going to work.

How can I cleanly unload DLL B when DLL A is about to exit?
0
guitarmanchu
Asked:
guitarmanchu
1 Solution
 
aib_42Commented:
I'm not sure why exactly calling LoadLibrary/FreeLibrary from DllMain is a problem, but if it's only to prevent deadlocks due to dependencies/freeing orders, you might just get away with calling FreeLibrary, probably with even more luck if A is the only module getting unloaded (i.e. DLL_PROCESS_DETACH was signalled due to FreeLibrary(A), lpvReserved=NULL)

I was going to suggest having B free itself (with a call from A), but if you stick to the API documentation, you are not supposed to call functions that may call functions that may call FreeLibrary... Which, as far as I understand, means you HAVE TO free B before or after A's DllMain is called.

I would suggest allocating some executable memory (VirtualAlloc?), populating it with the 6-byte code needed to free B and exit, and calling it using CreateThread...only if it wasn't a horrible, horrible hack.
0
 
i_maheshCommented:
you can make use of thread synchronization using events or posting message to a thread using PostThreadMessage API and listen for the event / message in a thread in DLL B and unload the DLL when you receive the event / message.
0
 
DFPercushCommented:
Create a monitor thread when DLL_A is loaded and have it clean up DLL_B for you:

void Monitor(LPVOID hWaitableObject)
{
WaitForSingleObject(hWaitableObject);
//Sleep(1);  SwitchToThread();  // Optional
FreeLibrary(hDLL_B);
}

// You will have to know hDLL_B somehow, or pass it in a structure when creating the thread.

BOOL DllMain( HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved)
{
    DWORD monitor_thread;
    if (fdwReason == PROCESS_ATTACH)
    {
           CreateThread(NULL, 500, Monitor, hInstDll, 0, &monitor_thread);
           // OR:  CreateThread(NULL, 500, Monitor, GetCurrentThread(), 0, &monitor_thread);
    }
}

//--------------------------------------------------------------
// If that does not work, you could use a system event object and manually signal it

BOOL DllMain( HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved)
{
    DWORD monitor_thread;
    HANDLE hEvent;
    if (fdwReason == PROCESS_ATTACH)
    {
            hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
           CreateThread(NULL, 500, Monitor, hEvent, 0, &monitor_thread);
     }
    else if (fdwReason == PROCESS_DETACH)
    {
            PulseEvent(hEvent);
    }
}
0
 
DFPercushCommented:
WaitForSingleObject() takes 2 parameters, my mistake. The second is a time-out in ms, and I would recommend setting it to INFINITE.

WaitForSingleObject(hWaitableObject, INFINITE);
0
 
guitarmanchuAuthor Commented:
Fantastic answer, thanks!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now