type
SYSTEM_PROCESS_INFORMATION = packed record
NextEntryOffset: DWORD;
NumberOfThreads: DWORD;
Reserved1: array[0..47] of Byte;
Reserved2: array[0..2] of PVOID;
UniqueProcessId: THandle;
Reserved3: PVOID;
HandleCount: DWORD;
Reserved4: array[0..3] of Byte;
Reserved5: array[0..10] of PVOID;
PeakPagefileUsage: DWORD;
PrivatePageCount: DWORD;
Reserved6: array[0..5] of INT64;
end;
_SYSTEM_HANDLE = packed record
ProcessID: DWORD;
HandleType: WORD;
HandleNumber: WORD;
KernelAddress: DWORD;
Flags: DWORD;
end;
_SYSTEM_HANDLE_INFORMATION = packed record
Count: DWORD;
Handles: array[0..0] of _SYSTEM_HANDLE;
end;
function NtQueryInformationProcess(const H: THandle; const InformationType: DWORD;
Data: Pointer; const cbSize: DWORD; var RetSize: DWORD): DWORD; stdcall; external 'ntdll.dll';
function NtQuerySystemInformation(const InformationType: DWORD;
Data: Pointer; const cbSize: DWORD; var RetSize: DWORD): DWORD; stdcall; external 'ntdll.dll';
function GetProcessHandleCount(const PID: DWORD): Integer;
const
CIDefaultSize = 50;
var
Ret: DWORD;
i : Integer;
pdata: ^_SYSTEM_HANDLE_INFORMATION;
pi : ^_SYSTEM_HANDLE;
begin
pdata := nil;
Result := 0;
Ret := 0;
EnablePrivilege('SeDebugPrivilege', True);
pdata := AllocMem(CIDefaultSize);
try
NtQuerySystemInformation(16, pdata, CIDefaultSize, Ret);
if Ret > CIDefaultSize then
begin
ReallocMem(pdata, Ret);
if pdata = nil then Exit;
if NtQuerySystemInformation(16, pdata, Ret, Ret) <> 0 then Exit;
end;
pi := @pdata.Handles;
for i := 0 to pdata.Count - 1 do
begin
if pi.ProcessID = PID then Inc(Result);
Inc(pi);
end;
finally
if pdata <> nil then FreeMem(pdata);
end;
end;