{*******************************************************************************
Procedure: EnumFileHandles
Author : EvilSoft, mp
Date : 2008-09-04
Comment : List all file handles.
*******************************************************************************}
procedure EnumFileHandles(CallBack: TEnumFileHandlesCB; FilterStr:
string = '
');
var
HandlesInfo : PSYSTEM_HANDLE_INFORMATION_EX;
FileName :
string;
r : Integer;
ObjTypeNumberFile : Integer;
lib : integer;
DupHandle : THandle;
ProcHandle : THandle;
OSVer : TOSVersionInfo;
label
log;
begin
// Load libraries
lib := LoadLibrary('
ntdll.dll');
if lib = 0
then
Exit;
try
@NtQuerySystemInformation := GetProcAddress(lib, '
NtQuerySystemInformation');
@NtQueryInformationFile := GetProcAddress(lib, '
NtQueryInformationFile');
@NtQueryObject := GetProcAddress(lib, '
NtQueryObject');
if (@NtQuerySystemInformation =
nil)
or
(@NtQueryInformationFile =
nil)
or
(@NtQueryObject =
nil)
then
Exit;
// Determine ObjectTypeNumber constant for file objects
// Windows 95 Windows 98 Windows Me Windows NT 4.0 Windows 2000 Windows XP
//Plattform-ID 1 1 1 2 2 2
//Majorversion 4 4 4 4 5 5
//Minorversion 0 10 90 0 0 1
ZeroMemory(@OSVer, sizeof(TOSVersionInfo));
OSVer.dwOSVersionInfoSize := sizeof(TOSVersionInfo);
GetVersionEx(OSVer);
ObjTypeNumberFile := 23;
// ???
if OSVer.dwMajorVersion <= 5
then
begin
if OSVer.dwMinorVersion = 1
then
ObjTypeNumberFile := 28
//XP
else
ObjTypeNumberFile := 26;
//2K
end
else if OSVer.dwMajorVersion >= 6
then
ObjTypeNumberFile := 25;
//VISTA
// Get all handles
HandlesInfo := GetInfoTable(SystemHandleInformation);
try
if HandlesInfo =
nil then
Exit;
for r := 0
to HandlesInfo^.NumberOfHandles - 1
do
begin
begin
// Process file handles only
if HandlesInfo^.Information[r].ObjectTypeNumber = ObjTypeNumberFile
then
begin
// Get process handle. Needed for DuplicateHandle
ProcHandle := OpenProcess(PROCESS_ALL_ACCESS, false, HandlesInfo^.Information[r].ProcessId);
if ProcHandle <> 0
then
begin
// Why?
if DuplicateHandle(ProcHandle, HandlesInfo^.Information[r].Handle, GetCurrentProcess, @DupHandle, 0,
False, DUPLICATE_SAME_ACCESS)
then
begin
FileName := GetFileNameByHandle(DupHandle);
CloseHandle(DupHandle);
end
else
FileName := '
';
if FileName <> '
'
then
begin
if (pos(LowerCase(FilterStr), LowerCase(FileName)) > 0)
or (FilterStr = '
')
then
begin
if Assigned(CallBack)
then
begin
CallBack(HandlesInfo^.Information[r].ProcessId, HandlesInfo^.Information[r].Handle, FileName)
end;
end;
end;
CloseHandle(ProcHandle);
end;
end;
end;
end;
// for HandlesInfo^.NumberOfHandles
finally
FreeMem(HandlesInfo);
end;
finally
FreeLibrary(lib);
end;
end;