Здесь решение с использованием Native Api, документированное http://undocumented.ntinternals.net/.
Я пропустил несколько вещей, потому что они сделали бы код еще длиннее. Код прост, когда вы понимаете синтаксис нативного API. Например, (почти) все нативные функции API, они экспортированы ntdll и плохо документированы Microsoft, возвращают NTSTATUS и не используют функцию simliar для получения Set / GetLastError (). Если сбой NtQuerySemaphore (Status! = STATUS_SUCCESS), вы можете посмотреть код ошибки здесь: http://source.winehq.org/source/include/ntstatus.h.
Хорошо, давайте перейдем к коду, он довольно прост, сначала определив некоторые структуры, которые вы можете получить с ntinernals.net. Затем получить адрес NtQuerySemaphore в ntdll.dll. Вам не нужно использовать LoadLibrary, потому что каждый процесс загружен ntdll.dll.
NtQuerySemaphore также прост, первый параметр - дескриптор семафора, второй - класс информации, который вы хотите получить (в нашем случае SemaphoreBasicInformation = 0x0).
Третий параметр - указатель на структуру, которая восстанавливает информацию. Четвертый paramwter - это размер структуры. В-пятых, будет ReturnLength, например, если вы можете получить имя семафора с помощью этой функции, этот параметр может содержать необходимый размер буфера после первого вызова с неверным SemaphoreInformationLength.
Довольно! Код:)
#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);
}
Еще одна вещь, предупреждаем, Microsoft может удалить или изменить способ работы этой функции.
Приветствия злой пирог