I have a question regarding using Semaphores
HANDLE WINAPI CreateSemaphore(...);
Is there anyway I can get the current value of the semaphore?
I have a question regarding using Semaphores
HANDLE WINAPI CreateSemaphore(...);
Is there anyway I can get the current value of the semaphore?
I think you need to call
DWORD WINAPI WaitForSingleObject
with a second argument set to 0 (immediate result requested).
and take actions depending on the result.
I hope this will help you, Jerom Wagner
No, and that's intentional. Even if you could get the "current" value, that value might very well have changed before you could do anything with it. The only way to do anything with it is to get and set the value atomically -- e.g., wait for the semaphore to be free and set it to "owned" (by that piece of code) in the same operation.
Can be solved by undocumented NtQuerySemaphore
See:
http://forums.msdn.microsoft.com/en-US/vcgeneral/thread/c44f0e63-b20f-4895-9dc3-eb2034de2aa4
Here the solution using Native Api, documented by http://undocumented.ntinternals.net/. I ommited a few thing because these would make the code even longer. The code is easy, when you understand the syntax of the native api. For example (nearly) all native api function, these exported by ntdll and not documented well by microsoft, return NTSTATUS, and dont use a functions simliar to get Set/GetLastError (). If NtQuerySemaphore fails (Status != STATUS_SUCCESS) you might want to look up the error code here: http://source.winehq.org/source/include/ntstatus.h.
Okay lets get to the code, its pretty straight forward, first defining some structs you can get from ntinernals.net. Then getting the address of NtQuerySemaphore in the ntdll.dll. You dont need to use LoadLibrary, because every process has ntdll.dll loaded.
NtQuerySemaphore is easy too, first parameter is the handle to the semaphore, second the information class you want to retrive (in our case SemaphoreBasicInformation = 0x0). Thee third parameter is an pointer to an struct, wich revieces the informations. Fourth paramwter is the sizeof the struct. Fifth would be the the ReturnLength, for example if you could recieve the name of the sempahore with this function, this parameter could hold the need buffer size after the first call with an incorrect SemaphoreInformationLength.
Enough! Code :)
#include <windows.h>
#include <stdio.h>
typedef LONG NTSTATUS;
typedef NTSTATUS (NTAPI *_NtQuerySemaphore)(
HANDLE SemaphoreHandle,
DWORD SemaphoreInformationClass, /* Would be SEMAPHORE_INFORMATION_CLASS */
PVOID SemaphoreInformation, /* but this is to much to dump here */
ULONG SemaphoreInformationLength,
PULONG ReturnLength OPTIONAL
);
typedef struct _SEMAPHORE_BASIC_INFORMATION {
ULONG CurrentCount;
ULONG MaximumCount;
} SEMAPHORE_BASIC_INFORMATION;
int main (int argc, char *argv[])
{
_NtQuerySemaphore NtQuerySemaphore;
HANDLE Semaphore;
SEMAPHORE_BASIC_INFORMATION BasicInfo;
NTSTATUS Status;
Semaphore = CreateSemaphore (NULL, 50, 100, "Test");
NtQuerySemaphore = (_NtQuerySemaphore)GetProcAddress (GetModuleHandle ("ntdll.dll"), "NtQuerySemaphore");
if (NtQuerySemaphore)
{
Status = NtQuerySemaphore (Semaphore, 0 /*SemaphoreBasicInformation*/,
&BasicInfo, sizeof (SEMAPHORE_BASIC_INFORMATION), NULL);
if (Status == ERROR_SUCCESS)
{
printf ("CurrentCount: %lu", BasicInfo.CurrentCount);
}
}
CloseHandle (Semaphore);
}
One last thing, be warned, microsoft could remove or change the way this function works.
Cheers evilpie