Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.21;
Скачать: CL | DM;

Вниз

Прототип 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 вся ветка

Текущий архив: 2005.08.21;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.053 c
3-1120751559
Alex77777
2005-07-07 19:52
2005.08.21
Поиск значения при вводе


4-1120065211
serko
2005-06-29 21:13
2005.08.21
Нажать на кнопки!


1-1122847553
wp2
2005-08-01 02:05
2005.08.21
Очередная ошибка точности???!!!


14-1122620383
syte_ser78
2005-07-29 10:59
2005.08.21
посоветуйте украинский интернет магазин


8-1112738740
Alex Romasnkiy
2005-04-06 02:05
2005.08.21
Как убрать тормоза при выводе битмапа?