Geoff Chappell - Software Analyst
This function creates or opens a named global counter.
HANDLE SHGlobalCounterCreateNamed ( LPCTSTR lpName, LONG lInitialCount);
The function exists in ANSI and Unicode forms.
The lpName argument provides the address of a null-terminated string that names the counter.
The lInitialCount argument provides the initial value to set for a counter that is created rather than opened.
The function returns a handle to the counter, if successful, else NULL.
The global counter is implemented as the release count in a named semaphore. The name of the semaphore is “shell” followed by a period and then by the name that is given for the counter (or, to be strict, by as many characters from the given name as keep the semaphore’s name within MAX_PATH characters.)
The function attempts to create the semaphore, including to open a semaphore that already exists with the same name. If the semaphore gets newly created, it receives the given initial count and a maximum count of MAXLONG. Creation will fail if lInitialCount is negative. If the semaphore exists already, then lInitialCount is irrelevant.
All being well, all semaphores for global counters are created with security descriptors that would permit all access to all users (as arranged through SHLWAPI’s own CreateAllAccessSecurityAttributes function). However, the function does seem prepared for the semaphore to exist already yet not grant full access (SEMAPHORE_ALL_ACCESS). If the semaphore does not open through CreateSemaphore, the function tries through OpenSemaphore but asking only for the least rights (SYNCHRONIZE and SEMAPHORE_MODIFY_STATE) that suffice for incrementing and decrementing the counter.
Of the ANSI and Unicode forms of this function, the ANSI has the native implementation. The Unicode implementation converts the given name to ANSI (on the stack) for a call to the ANSI form.
The SHGlobalCounterCreateNamed function is exported from SHLWAPI as ordinals 422 and 423 (for ANSI and Unicode forms respectively) in version 5.00 and higher.
Though this function dates from as long ago as 1999, it was still not documented by Microsoft in the MSDN Library at least as late as the CD edition dated January 2004.