WIN32 CreateSemaphore primitve: named semaphore shared with a process and a service

PALAZON Philippe 20 Reputation points
2024-06-27T09:04:00.09+00:00

Hello support,

When i create a named semaphore, it seems that memory space between a service and a process is different.

Between processes:

If i run a second time a process after invoking CreateSemaphore (of course same name that the first) GetLastError() returns ERROR_ALREADY_EXISTS.

Between services:

It's the same behaviour if i run a second service in trying to create a semaphore with the same name.

So, all is correct.

Between a process and a service

However, if i run a process in creating a named semaphore and if after i run a service with the same semaphore CreateSemaphore returns no error. It's the same behaviour if i run the service and after the process

The code looks like

=============
static const std::wstring g_namedSem = L"SemTest";

HANDLE sem = ::CreateSemaphore(0,0, LONG_MAX, g_namedSem .c_str());

if(sem == NULL)

{

// failed

}

else

{

if (GetLastError() == ERROR_ALREADY_EXISTS) 

{			

	// already created	

}

else

{

	// It's OK i can continue

}

}

==========

I'm working under Windows 10

Thanks a lot.

Regards,

                Philippe
Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
11,117 questions
{count} votes

Accepted answer
  1. RLWA32 42,796 Reputation points
    2024-06-29T16:24:32.1666667+00:00

    For a named semaphore created by a Windows service you could allow the semaphore to receive its default security descriptor. Afterwards, the service could add an access control entry (ACE) to the security descriptor that grants access to the user account for processes running in the interactive session. A Microsoft example of a function that can accomplish this is at Modifying the ACLs of an Object in C++


1 additional answer

Sort by: Most helpful
  1. RLWA32 42,796 Reputation points
    2024-06-28T20:28:26.3466667+00:00

    A Windows service will create a named kernel object (i.e., semaphore, event, etc.) in the global namespace.

    Unless the name of a kernel object is prefixed with "Global" an application running in an interactive session will create/open the object in that session's namespace. This is not the same object that was created by the service. So the application should use the "Global"prefix to obtain a handle to a semaphore created by a Windows service or create a kernel object that a Windows service will access.

    The next obstacle to deal with is security. For example, a Windows Service running under the SYSTEM account that calls CreateSemaphore and passes NULL as the lpSecurityAttributes parameter will create an object with a default security descriptor that allows access to SYSTEM and the Administrators group. Consequently the call to CreateSemaphore by an application running under a user account will fail with an Access denied error. So if the Windows service creates the semaphore it should provide for a security descriptor that allows access to the user account that is running in the interactive session.

    2 people found this answer helpful.