Click here to Skip to main content
Licence 
First Posted 1 Dec 2004
Views 20,553
Bookmarked 7 times

CreateMutexwithatwist

By | 1 Dec 2004 | Article
CreateMutex with a twist…. some non default arguments.

Introduction

This is just a brief follow-up on the excellent article submitted by Liviu Birjega: Windows-based application over Terminal Services using WtsAPI32.

In my own experience, under WTS, the function CreateMutex can be called simply like this:

hMutex = CreateMutex(NULL, FALSE, csAppName);

BUT, doing so for a 2nd and subsequent sessions resolves with a return error 5 (ERROR_ACCESS_DENIED) when calling GetLastError().

On further reading the MSDN documentation, it provides some explanation as follows:

“… Pointer to a security descriptor for the object that controls the sharing of it. If NULL is specified for this member, the object is assigned the default security descriptor of the calling process.

This is not the same as granting access to everyone by assigning a null DACL.

The default security descriptor is based on the default DACL of the access token belonging to the calling process. By default, the default DACL in the access token of a process allows access only to the user represented by the access token. If other users must access the object, you can either create a security descriptor with a null DACL, or add ACEs to the DACL that grants access to a group of users.”

This is explained in more detail in Rob Manderson’s excellent article: Using Access Control Lists to secure access to your objects.

So, in order to get back the desired result (183 = ERROR_ALREADY_EXISTS) when calling GetLastError() you will have to actually do something like this…

BOOL IsAnotherWTSUserLoggedIn(LPCTSTR sAppName)
{
   if(GetSystemMetrics(SM_REMOTESESSION))
   {
      HANDLE hMutex = NULL;
      SECURITY_DESCRIPTOR sd;
 
      InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);

      SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);

      SECURITY_ATTRIBUTES sa = { sizeof sa, &sd, FALSE };

      CString csAppName;
      csAppName.Format(_T(“Global\\%s”), sAppName);

      hMutex = ::CreateMutex(&sa, FALSE, csAppName);

      if( GetLastError() == ERROR_ALREADY_EXISTS )
      {
          CloseHandle(hMutex);
          return TRUE;
      }
   }

   return FALSE;
}

Yes, and just one more little comment for Liviu, it seems that the correct “Verb” to use is “Global” – not “Session” as suggested – this is also supported in the MSDN documentation. Hope someone finds some use for all this, I know I did.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Alex Evans

Web Developer

Australia Australia

Member

Born in Romania in 1945, lived for some 30 years in Israel and moved to join the family in Australia in 1985.
 
Started programming in 1973 (yes, the stone age…) on WANG, with BASIC, Assembler, then some Fortran around 1979, in 1981 got my first home “Personal Computer” – A Dragon 32 (had it connected to a TV monitor and a cassette deck for data / program storage)..
 
Later on PDP-11 , Data General AOS/VS for some 8 years, IBM 32/34/36 with RPG II and III, real “Fun” language to work with (NOT).
 
In 1985 moved to Australia, started a love affair with dBase III, then Clipper 87 and finally in 1991 switched 100% to work in C and later in C++
 
In my “Spare time” I build and fly Radio Control Model Airplanes.


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 1 Pinmemberkustt11021:50 20 Apr '09  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 1 Dec 2004
Article Copyright 2004 by Alex Evans
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid