Here the solution using Native Api is documented at http://undocumented.ntinternals.net/ . I missed something because it would make the code even longer. The code is simple when you understand the syntax of the native api. For example, almost all of the internal api function exported by ntdll and not documented by Microsoft returns NTSTATUS and does not use the simliar functions to get Set / GetLastError (). If NtQuerySemaphore does not work (Status! = STATUS_SUCCESS), you can find the error code here: http://source.winehq.org/source/include/ntstatus.h .
Ok, let's get to the code, it's pretty straightforward, by first defining some of the structures you can get from ntinernals.net. Then get the NtQuerySemaphore address in the ntdll.dll file. You do not need to use LoadLibrary because the ntdll.dll file is loaded in each process.
NtQuerySemaphore is also easy, the first parameter is the semaphore descriptor, the second is the information class that you want to extract (in our case, SemaphoreBasicInformation = 0x0). The third parameter is a pointer to a structure that reproduces information. The fourth parameter is the size of the structure. Fifth, it will be ReturnLength, for example, if you can get the sempahore name with this function, this parameter can contain the size of the needs buffer after the first call with the wrong SemaphoreInformationLength.
Enough! The 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); }
The last thing to warn, Microsoft may remove or change the way this function works.
Greetings of the Evil
evilpie
source share