Mutex doesn't removed after FreeLibrary

CSecurity
CSecurity used Ask the Experts™
on
Hi

I have a DLL which creates like this:
HANDLE hMutex = ::CreateMutex(NULL,FALSE, "Testing");

I have program which loads this DLL:

HMODULE test = LoadLibrary("MyDLL.dll");
do something

FreeLibrary(test);


Now I do this check AFTER! FreeLibrary:

      HANDLE hMutex = ::CreateMutex(NULL,FALSE, "c14");
      if (hMutex != NULL)
      {
            if(GetLastError() == ERROR_ALREADY_EXISTS)
                  MessageBox(0, "Already Loaded!", "Loaded!", 64);
            
            else
                  MessageBox(0, "NOT Loaded!", "NOT Loaded!", 64);
            
      }

Always I get already loaded!

I don't want it, I want to lose Mutex when MyDLL is unloaded... How to accomplish this? FreeLibrary doesn't remove DLL from memory?

Please advice... Even if you better method for detection of loaded/unloaded DLL please advice... I don't want to use CreateWindow method, but if I have to use, I'll use...
Thanks
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
evilrixSenior Software Engineer (Avast)

Commented:
THat's odd because the name of the other mutex is different.

HANDLE hMutex = ::CreateMutex(NULL,FALSE, "Testing");
HANDLE hMutex = ::CreateMutex(NULL,FALSE, "c14");

So there is no way the 2nd one (c14) already existing can have anything to do with the first(Testing).

Are you sure your analysis of this problem is correct?

Also, GetError is ONLY valid if the CreateMutex returns NULL, which it clearly doesn't for it to get into this code. This means the create has worked and the error response from GetError is most likely unrelated.

"If the function fails, the return value is NULL. To get extended error information, call GetLastError."
http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx
jkr
Top Expert 2012
Commented:
>>I want to lose Mutex when MyDLL is unloaded... How to accomplish this?

Since mutexes are designed to work across process boundaries, the behaviour you're observing is absolutely 'by design' (unless you forgot to call 'CloseHandle()' on your mutex). If you want to force the closing of the mutex in question, you could do that like
void ForceCloseMutex(LPCTSTR pName) {
 
  HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE,pName);
 
  while(CloseHandle(hMutex)); 
}
 
// ...
 
BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,  // handle to DLL module
  DWORD fdwReason,     // reason for calling function
  LPVOID lpvReserved   // reserved
) {
 
  switch(fdwReason) {
 
    // ...
 
    case DLL_PROCESS_DETACH: ForceCloseMutex(_T("MyMutex"));
  };
}

Open in new window

Author

Commented:
evilrix, that was mistyping... sorry!

About jkr... Sometimes my DLL crashes and goes away, this is what I'm doing such thing... I want to see if my DLL is crashed or exited unexpectedly, so I can't run ForceCloseMutex, because it won't get fired
Become a CompTIA Certified Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

evilrixSenior Software Engineer (Avast)

Commented:
>> Sometimes my DLL crashes and goes away, this is what I'm doing such thing...
Maybe the correct thing to do is to fix the problem rather than adding an additional layer of complexity on to of it? :)

Commented:
I must agree with evlirix, but, btw, calling Loadlibrary twice with the same dll isn't a problem since it checks if it has already been loaded. You cant load it twice.



Commented:
" Sometimes my DLL crashes and goes away" <<< how a dll can crash and not the process ?
jkr
Top Expert 2012

Commented:
When that process crashes, why don't you just open the already existing mutex? E.g.
HANDLE ConnectMutex ( LPCTSTR pszName)
{
 
   HANDLE hMutex   =   CreateMutex (   NULL,
                                       FALSE,
                                       FALSE,
                                       pszName
                                   );
 
   if  (   INVALID_HANDLE_VALUE    ==  hMutex)
       {
           if  (   ERROR_ALREADY_EXISTS    ==  GetLastError    ())
               {
                   hMutex  =   OpenMutex   (   SYNCHRONIZE,
                                               FALSE,
                                               pszName
                                           );
 
                   if  (   INVALID_HANDLE_VALUE    ==  hMutex)
                       {
 
                           return NULL;
                       }
               }
       }
 
   return hMutex;
}

Open in new window

Author

Commented:
Some users detach my dll using some programs... That's my problem... I want to see when my DLL is unloaded and doesn't exists in memory, I should re-load my dll...

Author

Commented:
I open same Mutex and Same Mutex exists... I mean that... c14 and Testing I meant Testing...

Author

Commented:
That's very good idea to enumerate loaded modules, but when I include dbghelp.h I get error:

unresolved external symbol __imp__EnumerateLoadedModules@12

Author

Commented:
Solved it:

#pragma comment(lib, "dbghelp.lib")

Author

Commented:
Thank you guys

Commented:
You need to add Dbghelp.lib in your project.

Anyway, i agree evilrix, you shouldnt have this dll unloaded, and a dll crashing doesnt get unloaded, the process crash too.

I do not understand why you need to add this stuff.

Author

Commented:
Is there a program which can unload a module from another process?

If yes... That's why I need it. Some people unload my DLL from some process, while it should be loaded and exist in ALL processes.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial