Форум: "WinAPI";
Текущий архив: 2007.02.04;
Скачать: [xml.tar.bz2];
ВнизПолучить список открытых в системе файлов (WinNT) Найти похожие ветки
← →
Anatolii (2006-09-18 11:05) [0]Достаточно долго возился с поиском информации по теме. Информации мало :( Нижеприведенный пример не работает... Список дисков получает корректно, а вот уже при запросе имен файлов, DeviceIoControl возвращает в buf пустые значения. Может ошибка в коде, может для NT систем можно иначе получить список файлов?
procedure TForm1.Button1Click(Sender: TObject);
type
TRegs = Record
reg_EBX : Dword;
reg_EDX : Pointer;//PChar;
reg_ECX : Dword;
reg_EAX : Dword;
reg_EDI : Dword;
reg_ESI : Dword;
reg_Flags : Dword;
end;
var nd,j,i:integer;
buf: array[0..100] of char;
F,cb:Cardinal;
Regs:TRegs;
begin
nd := 0;
j := GetLogicalDriveStrings(MAX_PATH,@buf);
for i := 1 to j do if buf[i]=":" then Inc(nd);
F := CreateFile(PChar("\\.\vwin32"),0,0,NIL,0,FILE_FLAG_DELETE_ON_CLOSE,0);
for i := 3 to nd do //Пропускаем диски A и B
begin
j := 0;
while True do
begin
FillChar(Regs,SizeOf(TRegs),0);
FillChar(buf,SizeOf(TRegs),0);
Regs.reg_EBX := i;
Regs.reg_EDX := @buf;
Regs.reg_ECX := $486D;
Regs.reg_EAX := $440D;
Regs.reg_EDI := 0;
Regs.reg_ESI := j;
Inc(j);
DeviceIoControl(F,1,@Regs,sizeof(Regs),@Regs,sizeof(regs),cb,NIL);
OemToChar(@buf,@buf);
ListBox2.Items.Add(StrPas(@buf));
if (Regs.reg_Flags or 1 = Regs.reg_Flags) then break;
end;
end;
CloseHandle(F);
end;
← →
Rouse_ © (2006-09-18 12:16) [1]Вот так:
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Unit Name : Unit15
// * Purpose : Перечисление всех открытых файлов в системе
// * (до которых получилось достучаться)
// * Author : Александр (Rouse_) Багель
// * Version : 1.00
// ****************************************************************************
//
unit Unit15;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TForm15 = class(TForm)
Button1: TButton;
Memo1: TMemo;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
public
procedure ShowLockedProcess(FileName: String);
end;
var
Form15: TForm15;
implementation
{$R *.dfm}
type
NT_STATUS = Cardinal;
TFileDirectoryInformation = packed record
NextEntryOffset: ULONG;
FileIndex: ULONG;
CreationTime: LARGE_INTEGER;
LastAccessTime: LARGE_INTEGER;
LastWriteTime: LARGE_INTEGER;
ChangeTime: LARGE_INTEGER;
EndOfFile: LARGE_INTEGER;
AllocationSize: LARGE_INTEGER;
FileAttributes: ULONG;
FileNameLength: ULONG;
FileName: array[0..0] of WideChar;
end;
FILE_DIRECTORY_INFORMATION = TFileDirectoryInformation;
PFileDirectoryInformation = ^TFileDirectoryInformation;
PFILE_DIRECTORY_INFORMATION = PFileDirectoryInformation;
PSYSTEM_THREADS = ^SYSTEM_THREADS;
SYSTEM_THREADS = packed record
KernelTime: LARGE_INTEGER;
UserTime: LARGE_INTEGER;
CreateTime: LARGE_INTEGER;
WaitTime: ULONG;
StartAddress: Pointer;
UniqueProcess: DWORD;
UniqueThread: DWORD;
Priority: Integer;
BasePriority: Integer;
ContextSwitchCount: ULONG;
State: Longint;
WaitReason: Longint;
end;
PSYSTEM_PROCESS_INFORMATION = ^SYSTEM_PROCESS_INFORMATION;
SYSTEM_PROCESS_INFORMATION = packed record
NextOffset: ULONG;
ThreadCount: ULONG;
Reserved1: array [0..5] of ULONG;
CreateTime: FILETIME;
UserTime: FILETIME;
KernelTime: FILETIME;
ModuleNameLength: WORD;
ModuleNameMaxLength: WORD;
ModuleName: PWideChar;
BasePriority: ULONG;
ProcessID: ULONG;
InheritedFromUniqueProcessID: ULONG;
HandleCount: ULONG;
Reserved2 : array[0..1] of ULONG;
PeakVirtualSize : ULONG;
VirtualSize : ULONG;
PageFaultCount : ULONG;
PeakWorkingSetSize : ULONG;
WorkingSetSize : ULONG;
QuotaPeakPagedPoolUsage : ULONG;
QuotaPagedPoolUsage : ULONG;
QuotaPeakNonPagedPoolUsage : ULONG;
QuotaNonPagedPoolUsage : ULONG;
PageFileUsage : ULONG;
PeakPageFileUsage : ULONG;
PrivatePageCount : ULONG;
ReadOperationCount : LARGE_INTEGER;
WriteOperationCount : LARGE_INTEGER;
OtherOperationCount : LARGE_INTEGER;
ReadTransferCount : LARGE_INTEGER;
WriteTransferCount : LARGE_INTEGER;
OtherTransferCount : LARGE_INTEGER;
ThreadInfo: array [0..0] of SYSTEM_THREADS;
end;
PSYSTEM_HANDLE_INFORMATION = ^SYSTEM_HANDLE_INFORMATION;
SYSTEM_HANDLE_INFORMATION = packed record
ProcessId: DWORD;
ObjectTypeNumber: Byte;
Flags: Byte;
Handle: Word;
pObject: Pointer;
GrantedAccess: DWORD;
end;
PSYSTEM_HANDLE_INFORMATION_EX = ^SYSTEM_HANDLE_INFORMATION_EX;
SYSTEM_HANDLE_INFORMATION_EX = packed record
NumberOfHandles: dword;
Information: array [0..0] of SYSTEM_HANDLE_INFORMATION;
end;
PFILE_NAME_INFORMATION = ^FILE_NAME_INFORMATION;
FILE_NAME_INFORMATION = packed record
FileNameLength: ULONG;
FileName: array [0..MAX_PATH - 1] of WideChar;
end;
PUNICODE_STRING = ^TUNICODE_STRING;
TUNICODE_STRING = packed record
Length : WORD;
MaximumLength : WORD;
Buffer : array [0..MAX_PATH - 1] of WideChar;
end;
POBJECT_NAME_INFORMATION = ^TOBJECT_NAME_INFORMATION;
TOBJECT_NAME_INFORMATION = packed record
Name : TUNICODE_STRING;
end;
PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
IO_STATUS_BLOCK = packed record
Status: NT_STATUS;
Information: DWORD;
end;
PGetFileNameThreadParam = ^TGetFileNameThreadParam;
TGetFileNameThreadParam = packed record
hFile: THandle;
Data: array [0..MAX_PATH - 1] of Char;
Status: NT_STATUS;
end;
const
STATUS_SUCCESS = NT_STATUS($00000000);
STATUS_INVALID_INFO_CLASS = NT_STATUS($C0000003);
STATUS_INFO_LENGTH_MISMATCH = NT_STATUS($C0000004);
STATUS_INVALID_DEVICE_REQUEST = NT_STATUS($C0000010);
ObjectNameInformation = 1;
FileDirectoryInformation = 1;
FileNameInformation = 9;
SystemProcessesAndThreadsInformation = 5;
SystemHandleInformation = 16;
function ZwQuerySystemInformation(ASystemInformationClass: DWORD;
ASystemInformation: Pointer; ASystemInformationLength: DWORD;
AReturnLength: PDWORD): NT_STATUS; stdcall; external "ntdll.dll";
function NtQueryInformationFile(FileHandle: THandle;
IoStatusBlock: PIO_STATUS_BLOCK; FileInformation: Pointer;
Length: DWORD; FileInformationClass: DWORD): NT_STATUS;
stdcall; external "ntdll.dll";
function NtQueryObject(ObjectHandle: THandle;
ObjectInformationClass: DWORD; ObjectInformation: Pointer;
ObjectInformationLength: ULONG;
ReturnLength: PDWORD): NT_STATUS; stdcall; external "ntdll.dll";
function GetLongPathNameA(lpszShortPath, lpszLongPath: PChar;
cchBuffer: DWORD): DWORD; stdcall; external kernel32;
procedure TForm15.Button1Click(Sender: TObject);
begin
ShowLockedProcess("");
end;
procedure TForm15.ShowLockedProcess(FileName: String);
function GetInfoTable(ATableType: DWORD): Pointer;
var
dwSize: DWORD;
pPtr: Pointer;
ntStatus: NT_STATUS;
begin
Result := nil;
dwSize := WORD(-1);
GetMem(pPtr, dwSize);
ntStatus := ZwQuerySystemInformation(ATableType, pPtr, dwSize, nil);
while ntStatus = STATUS_INFO_LENGTH_MISMATCH do
begin
dwSize := dwSize * 2;
ReallocMem(pPtr, dwSize);
ntStatus := ZwQuerySystemInformation(ATableType, pPtr, dwSize, nil);
end;
if ntStatus = STATUS_SUCCESS then
Result := pPtr
else
FreeMem(pPtr);
end;
← →
Rouse_ © (2006-09-18 12:17) [2]
function GetFileNameThread(lpParameters: Pointer): DWORD; stdcall;
var
FileNameInfo: FILE_NAME_INFORMATION;
ObjectNameInfo: TOBJECT_NAME_INFORMATION;
IoStatusBlock: IO_STATUS_BLOCK;
pThreadParam: TGetFileNameThreadParam;
dwReturn: DWORD;
begin
ZeroMemory(@FileNameInfo, SizeOf(FILE_NAME_INFORMATION));
pThreadParam := PGetFileNameThreadParam(lpParameters)^;
Result := NtQueryInformationFile(pThreadParam.hFile, @IoStatusBlock,
@FileNameInfo, MAX_PATH * 2, FileNameInformation);
if Result = STATUS_SUCCESS then
begin
Result := NtQueryObject(pThreadParam.hFile, ObjectNameInformation,
@ObjectNameInfo, MAX_PATH * 2, @dwReturn);
if Result = STATUS_SUCCESS then
begin
pThreadParam.Status := Result;
WideCharToMultiByte(CP_ACP, 0,
@ObjectNameInfo.Name.Buffer[ObjectNameInfo.Name.MaximumLength -
ObjectNameInfo.Name.Length],
ObjectNameInfo.Name.Length, @pThreadParam.Data[0],
MAX_PATH, nil, nil);
end
else
begin
pThreadParam.Status := STATUS_SUCCESS;
Result := STATUS_SUCCESS;
WideCharToMultiByte(CP_ACP, 0,
@FileNameInfo.FileName[0], IoStatusBlock.Information,
@pThreadParam.Data[0],
MAX_PATH, nil, nil);
end;
end;
PGetFileNameThreadParam(lpParameters)^ := pThreadParam;
ExitThread(Result);
end;
function GetFileNameFromHandle(hFile: THandle): String;
var
lpExitCode: DWORD;
pThreadParam: TGetFileNameThreadParam;
hThread: THandle;
begin
Result := "";
ZeroMemory(@pThreadParam, SizeOf(TGetFileNameThreadParam));
pThreadParam.hFile := hFile;
hThread := CreateThread(nil, 0, @GetFileNameThread, @pThreadParam, 0, PDWORD(nil)^);
if hThread <> 0 then
try
case WaitForSingleObject(hThread, 100) of
WAIT_OBJECT_0:
begin
GetExitCodeThread(hThread, lpExitCode);
if lpExitCode = STATUS_SUCCESS then
Result := pThreadParam.Data;
end;
WAIT_TIMEOUT:
TerminateThread(hThread, 0);
end;
finally
CloseHandle(hThread);
end;
end;
function SetDebugPriv: Boolean;
var
Token: THandle;
tkp: TTokenPrivileges;
begin
Result := false;
if OpenProcessToken(GetCurrentProcess,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
begin
if LookupPrivilegeValue(nil, PChar("SeDebugPrivilege"),
tkp.Privileges[0].Luid) then
begin
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
Result := AdjustTokenPrivileges(Token, False,
tkp, 0, PTokenPrivileges(nil)^, PDWord(nil)^);
end;
end;
end;
type
DriveQueryData = record
DiskLabel: String;
DiskDosQuery: String;
DosQueryLen: Integer;
end;
← →
Rouse_ © (2006-09-18 12:17) [3]
var
hFile, hProcess: THandle;
pHandleInfo: PSYSTEM_HANDLE_INFORMATION_EX;
I, Drive: Integer;
ObjectTypeNumber: Byte;
FileDirectory, FilePath, ProcessName: String;
SystemInformation, TempSI: PSYSTEM_PROCESS_INFORMATION;
DosDevices: array [0..25] of DriveQueryData;
LongFileName, TmpFileName: String;
begin
SetLength(LongFileName, MAX_PATH);
GetLongPathNameA(PChar(FileName), @LongFileName[1], MAX_PATH);
for Drive := 0 to 25 do
begin
DosDevices[Drive].DiskLabel := Chr(Drive + Ord("a")) + ":";
SetLength(DosDevices[Drive].DiskDosQuery, MAXCHAR);
ZeroMemory(@DosDevices[Drive].DiskDosQuery[1], MAXCHAR);
QueryDosDevice(PChar(DosDevices[Drive].DiskLabel),
@DosDevices[Drive].DiskDosQuery[1], MAXCHAR);
DosDevices[Drive].DosQueryLen := Length(PChar(DosDevices[Drive].DiskDosQuery));
SetLength(DosDevices[Drive].DiskDosQuery, DosDevices[Drive].DosQueryLen);
end;
ObjectTypeNumber := 0;
SetDebugPriv;
hFile := CreateFile("NUL", GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
if hFile = INVALID_HANDLE_VALUE then RaiseLastOSError;
try
pHandleInfo := GetInfoTable(SystemHandleInformation);
if pHandleInfo = nil then RaiseLastOSError;
try
for I := 0 to pHandleInfo^.NumberOfHandles - 1 do
if pHandleInfo^.Information[I].Handle = hFile then
if pHandleInfo^.Information[I].ProcessId = GetCurrentProcessId then
begin
ObjectTypeNumber := pHandleInfo^.Information[I].ObjectTypeNumber;
Break;
end;
finally
FreeMem(pHandleInfo);
end;
finally
CloseHandle(hFile);
end;
SystemInformation := GetInfoTable(SystemProcessesAndThreadsInformation);
if SystemInformation <> nil then
try
pHandleInfo := GetInfoTable(SystemHandleInformation);
if pHandleInfo <> nil then
try
ProgressBar1.Position := 0;
ProgressBar1.Max := pHandleInfo^.NumberOfHandles;
for I := 0 to pHandleInfo^.NumberOfHandles - 1 do
begin
if pHandleInfo^.Information[I].ObjectTypeNumber = ObjectTypeNumber then
begin
hProcess := OpenProcess(PROCESS_DUP_HANDLE, True,
pHandleInfo^.Information[I].ProcessId);
if hProcess > 0 then
try
if DuplicateHandle(hProcess, pHandleInfo^.Information[I].Handle,
GetCurrentProcess, @hFile, 0, False, DUPLICATE_SAME_ACCESS) then
try
if Application.Terminated then Exit;
FilePath := GetFileNameFromHandle(hFile);
if FilePath <> "" then
begin
FileDirectory := "";
for Drive := 0 to 25 do
if DosDevices[Drive].DosQueryLen > 0 then
if Copy(FilePath, 1, DosDevices[Drive].DosQueryLen) =
DosDevices[Drive].DiskDosQuery then
begin
FileDirectory := DosDevices[Drive].DiskLabel;
Delete(FilePath, 1, DosDevices[Drive].DosQueryLen);
Break;
end;
if FileDirectory = "" then Continue;
TempSI := SystemInformation;
repeat
if TempSI^.ProcessID =
pHandleInfo^.Information[I].ProcessId then
begin
ProcessName := TempSI^.ModuleName;
Break;
end;
TempSI := Pointer(DWORD(TempSI) + TempSI^.NextOffset);
until TempSI^.NextOffset = 0;
SetLength(TmpFileName, MAX_PATH);
GetLongPathNameA(PChar(FileDirectory + FilePath), @TmpFileName[1], MAX_PATH);
Memo1.Lines.Add(ProcessName + ": " + TmpFileName);
end;
finally
CloseHandle(hFile);
end;
finally
CloseHandle(hProcess);
end;
end;
ProgressBar1.Position := ProgressBar1.Position + 1;
Application.ProcessMessages;
end;
finally
FreeMem(pHandleInfo);
end;
finally
FreeMem(SystemInformation);
end;
ShowMessage("All handles found.");
end;
end.
← →
Anatolii (2006-09-18 14:43) [4]100% попадание. Спасибо большое :)
← →
Rouse_ © (2006-09-18 15:08) [5]Ты только учитывай что не все файлы можно так получить ибо не всегда OpenProcess отработает с флагом PROCESS_DUP_HANDLE, особливо касается фалов открытых из драйвера...
← →
BiN © (2006-09-21 10:42) [6]
> Rouse_ © (18.09.06 12:17) [2]
>...
> WAIT_TIMEOUT:
TerminateThread(hThread, 0);
Я понимаю, что зависает, но ведь по живому режешь...
-)
зыж
как вариант можно попробовать поиграть с GetMappedFileName.
← →
Rouse_ © (2006-09-21 11:45) [7]
> Я понимаю, что зависает, но ведь по живому режешь...
А что делать, на синхронном пайпе висить, шоб его приподняло :) Приходиться делать подобным образом, потомучто другие методы не дали результата :)
← →
Rouse_ © (2006-09-21 11:47) [8]Но вообще на практике это обходиться NtQueryInformationFile которая за пайп даже не хватается и посему реально TerminateThread не отрабатывается, а осталось со времени экспериментов :)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2007.02.04;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.041 c