Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.062 c
1-1122616300
Shlomo
2005-07-29 09:51
2005.08.21
QuickReport, внедрить один отчёт в другой?


3-1120865175
igorek2003
2005-07-09 03:26
2005.08.21
Справочник и Jpeg


3-1121251687
AKiM
2005-07-13 14:48
2005.08.21
ввод даты в MySQL


4-1119797610
Толян
2005-06-26 18:53
2005.08.21
Форматирования диска


1-1122281961
VadimX
2005-07-25 12:59
2005.08.21
Прозрачность картинки через Canvas.Draw





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский