Форум: "WinAPI";
Текущий архив: 2005.08.21;
Скачать: [xml.tar.bz2];
ВнизПрототип IoVolumeDeviceToDosName в user-mode. Найти похожие ветки
← →
BiN © (2005-06-30 14:15) [0]Уважаемые мастера.
Может кто знает, существует ли сабжевый вариант в готовом виде?
Напомню, что функция возвращает dos-стилизованное имя диска по ссылке на его девайс. Не хотелось бы ворошить символьные ссылки, строить список томов и т.п, так как список этот может и поменяться в процессе работы.
Авантюрный вариант (-)) с перескоком в режим ядра прошу не рассматривать.
С уважением,
← →
Игорь Шевченко © (2005-06-30 14:21) [1]BiN © (30.06.05 14:15)
http://www.schevchenko.net.ru/SRC/DeviceIoControl_60.zip
unit HsDeviceTranslation не поможет ?
С уважением,
← →
BiN © (2005-06-30 14:40) [2]Игорь Шевченко © (30.06.05 14:21) [1]
Спасибо, Игорь. Но, к сожалению, это как раз относится к тому, что "Не хотелось бы...".
Конечная цель задумки - при перечислении открытых ссылок на объеты-файлы определить букву (если таковая имеется) устройства на котором эти файлы "сидят".
С уважением,
← →
Игорь Шевченко © (2005-06-30 14:48) [3]Начиная с XP, в Ntdll есть RtlNtPathNameToDosPathName.
> Конечная цель задумки - при перечислении открытых ссылок
> на объеты-файлы определить букву (если таковая имеется)
> устройства на котором эти файлы "сидят".
Я в своем примере сделал так:type
TFileNameTranslator = class(TStringList)
private
function GetDriveName(const Index: Integer): string;
public
constructor Create;
function TranslateNtFileName (const Value: string): string;
end;{ TFileNameTranslator }
constructor TFileNameTranslator.Create;
var
I: Integer;
Buffer: ZString;
Drive: array[0..2] of char;
Drives: DWORD;
begin
inherited;
FillChar(Drive, SizeOf(Drive), 0);
Drive[1] := ":";
Drives := GetLogicalDrives;
for I:=0 to 31 do begin
if (Drives and (1 shl I)) <> 0 then begin
Drive[0] := Char(I + Ord("A"));
QueryDosDevice(Drive, Buffer, sizeof(Buffer));
AddObject(Buffer, TObject(I));
end;
end;
end;
function TFileNameTranslator.GetDriveName(const Index: Integer): string;
var
DriveNo: Integer;
begin
SetLength(Result, 2);
DriveNo := Integer(Objects[Index]);
Result[1] := Char(DriveNo + Ord("A"));
Result[2] := ":";
end;
function TFileNameTranslator.TranslateNtFileName(
const Value: string): string;
var
I: Integer;
begin
for I:=0 to Pred(Count) do
if Copy(Value, 1, Length(Strings[I])) = Strings[I] then begin
Result := Value;
System.Delete(Result, 1, Length(Strings[I]));
Result := GetDriveName(I) + Result;
Exit;
end;
Result := Value;
end;
И, соответственно, при использовании:procedure GetProcessFiles (const PID: Cardinal; Files: TStrings);
var
Handles: THSNtHandles;
I: Integer;
Translator: TFileNameTranslator;
begin
Files.Clear;
Translator := TFileNameTranslator.Create;
try
Handles := GetProcessHandles (PID);
for I:=0 to Pred(Handles.Count) do
if SameText(Handles[I].ObjectTypeName, "File") then
Files.Add (Translator.TranslateNtFileName(Handles[I].ObjectName));
finally
Translator.Free;
end;
end;
С уважением,
← →
BiN © (2005-06-30 15:04) [4]А Handles[I].ObjectName - это _сырое_ имя объекта, взятое с помощью xxQueryObject? Или в него входит имя девайса (може, глупый вопрос, но я никак не могу получить оное имя. Имя драйвера - пожалуйста, метка тома - легко. А вот злополучное "Device\xxxx" - никак)?
С уважением,
← →
Игорь Шевченко © (2005-06-30 15:10) [5]BiN © (30.06.05 15:04) [4]
Полный код (описание FileTranslator в предыдущем посте) такой:unit NtHandles;
interface
uses
Classes;
procedure GetProcessFiles (const PID: Cardinal; Files: TStrings);
implementation
uses
Windows, SysUtils,
NtDll, NtProcessInfo, //TODO: Перенести функцию QueryListInformation в
// NtDll.pas
HsNtDef, NtUtils, HSObjectList;
type
THSNtHandle = class
private
FPID: ULONG;
FObjectType: Byte;
FFlags: Byte;
FHandle: Word;
FObject: Pointer;
FGrantedAccess: ACCESS_MASK;
FObjectTypeName: string;
function AcquireDuplicatedHandle: THandle;
function GetObjectName: string;
public
constructor Create (APID: ULONG; AObjectType, AFlags: Byte;
AHandle: Word; AObject: Pointer; AGrantedAccess: ACCESS_MASK);
property ObjectTypeName: string read FObjectTypeName;
property ObjectName: string read GetObjectName;
end;
THSNtHandles = class(THSObjectList)
private
function GetItems(I: Integer): THSNtHandle;
public
property Items[I: Integer]: THSNtHandle read GetItems; default;
end;
function GetProcessHandles (const PID: ULONG): THSNtHandles;
var
HandlesInfo: Pointer;
HandlesInfoSize: ULONG;
rc: NTSTATUS;
I: Integer;
begin
HandlesInfo := QueryListInformation (SystemHandleInformation, rc,
HandlesInfoSize);
Result := THSNtHandles.Create;
if not NT_SUCCESS(rc) then
Exit;
try
with PSYSTEM_HANDLES_INFORMATION(HandlesInfo)^ do
for I:=0 to Pred(Count) do
if Data[I].PID = PID then
Result.Add(THsNtHandle.Create(Data[I].PID, Data[I].ObjectType,
Data[I].Flags, Data[I].Handle, Data[I].FObject,
Data[I].GrantedAccess));
FreeMem(HandlesInfo);
except
Result.Free;
raise;
end;
end;
procedure GetProcessFiles (const PID: Cardinal; Files: TStrings);
var
Handles: THSNtHandles;
I: Integer;
Translator: TFileNameTranslator;
begin
Files.Clear;
Translator := TFileNameTranslator.Create;
try
Handles := GetProcessHandles (PID);
for I:=0 to Pred(Handles.Count) do
if SameText(Handles[I].ObjectTypeName, "File") then
Files.Add (Translator.TranslateNtFileName(Handles[I].ObjectName));
finally
Translator.Free;
end;
end;
{ THSNtHandles }
function THSNtHandles.GetItems(I: Integer): THSNtHandle;
begin
Result := THSNtHandle(inherited Items[I]);
end;
{ THSNtHandle }
function THSNtHandle.AcquireDuplicatedHandle: THandle;
var
hProcess: THandle;
begin
Result := INVALID_HANDLE_VALUE;
hProcess := OpenProcess(PROCESS_DUP_HANDLE, false, FPID);
if hProcess <> 0 then
try
if not DuplicateHandle (hProcess, FHandle, GetCurrentProcess,
@Result, 0, false, 0) then
Result := INVALID_HANDLE_VALUE;
finally
CloseHandle(hProcess);
end;
end;
constructor THSNtHandle.Create(APID: ULONG; AObjectType, AFlags: Byte;
AHandle: Word; AObject: Pointer; AGrantedAccess: ACCESS_MASK);
var
rc: NTSTATUS;
DupHandle: THandle;
ReturnLength: ULONG;
BasicInfo: OBJECT_BASIC_INFORMATION;
ObjectType: Pointer;
ObjectTypeLength: Integer;
begin
FPID := APID;
FObjectType := AObjectType;
FFlags := AFlags;
FHandle := AHandle;
FObject := AObject;
FGrantedAccess := AGrantedAccess;
DupHandle := AcquireDuplicatedHandle;
try
rc := NtQueryObject(DupHandle, ObjectBasicInformation, @BasicInfo,
SizeOf(BasicInfo),@ReturnLength);
if NT_SUCCESS(rc) then begin
ObjectTypeLength := BasicInfo.TypeInformationLength+2;
GetMem(ObjectType, ObjectTypeLength);
try
rc := NtQueryObject(DupHandle, ObjectTypeInformation,
ObjectType, ObjectTypeLength, @ReturnLength);
if NT_SUCCESS(rc) then
with POBJECT_TYPE_INFORMATION(ObjectType)^ do
FObjectTypeName := HSUnicodeStringToAnsiString (Name);
finally
FreeMem(ObjectType);
end;
end;
finally
CloseHandle(DupHandle);
end;
end;
function THSNtHandle.GetObjectName: string;
var
ReturnLength: ULONG;
ObjectInfo: Pointer;
ObjectInfoLength: Integer;
rc: NTSTATUS;
DupHandle: THandle;
begin
DupHandle := AcquireDuplicatedHandle;
try
ObjectInfoLength := MAX_PATH * SizeOf(WideChar);
GetMem(ObjectInfo, ObjectInfoLength);
try
rc := NtQueryObject (DupHandle, ObjectNameInformation, ObjectInfo,
ObjectInfoLength, @ReturnLength);
if NT_SUCCESS(rc) then
with POBJECT_NAME_INFORMATION(ObjectInfo)^ do
Result := HSUnicodeStringToAnsiString (Name);
finally
FreeMem(ObjectInfo);
end;
finally
CloseHandle(DupHandle);
end;
end;
end.
С уважением,
← →
BiN © (2005-06-30 15:42) [6]Еще раз спасибо -)
По поводу полного имени файла: у меня почему-то складывалось впечатление, чтоNtQueryObject (DupHandle, ObjectNameInformation
для файла возвращает значение хранящееся в поле FileName структуры_FILE_OBJECT = packed record
...
{02E} FileName: UNICODE_STRING;
А оно вон как. Отрадно -).
С уважением,
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.08.21;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.046 c