Сейчас на форуме: tyns777, zds (+3 невидимых)

 eXeL@B —› Программирование —› Получить имя файла по его хэндлу
Посл.ответ Сообщение

Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 04 декабря 2009 00:35
· Личное сообщение · #1

Всем привет. Столкнулся с такой вот бедой ...
Нужно из хэндла файла (который выдаёт CreateFile) получить его имя.

вот как бы примерный код, который нормально работает именно на файлах:
(ахтунг! код на говно-дэлфи)
Code:
  1. function GetFileNameFromHandle(hFile: THandle): string;
  2. var
  3.  pszFilename: array[0..255] of Char;
  4.  hFileMap: THandle;
  5.  pMem: Pointer;
  6. begin
  7.  result:='';
  8.  hFileMap:=CreateFileMapping(hFile,nil,PAGE_READONLY,0,0,nil);
  9.  pMem:=MapViewOfFile(hFileMap,FILE_MAP_READ,0,0,1);
  10.  if pMem<>nil then begin
  11.   if GetMappedFileName(GetCurrentProcess(),pMem,Filename,sizeof(Filename))< >0 then begin
  12.    result:=FileName;
  13.   end;
  14.  end;
  15. end;
  16.  
  17. procedure TForm1.FormCreate(Sender: TObject);
  18. var
  19.  hFile: THandle;
  20.  str: string;
  21. begin
  22.  hFile:=CreateFile('c:\boot.ini',GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
  23.  str:=GetFileNameFromHandle(hFile);
  24. end;

для файла "c:\boot.ini" оно нормально получает хэндл и строку вида "\Device\HarddiskVolume1\boot.ini"

Проблема вот в чём. Если был создан хэндл для "\.\PhysicalDrive0" (через этот идентификатор DeviceIoControl читает серийник HDD) - этот код уже не работает.
CreateFileMapping возвращает 0. GetLastError() показывает что произошла ошибка 193 (ERROR_BAD_EXE_FORMAT = 193)

Подскажите, может быть есть какие-нибудь другие варианты получения имени из хэндлов?
код не обязательно приводить именно на дэлфи, думаю с других языков смогу перевести.



Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 04 декабря 2009 00:47
· Личное сообщение · #2

Гугл же... ZwQuerySystemInformation.

-----
Shalom ebanats!




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 04 декабря 2009 00:49
· Личное сообщение · #3

SLV пишет:
Гугл же... ZwQuerySystemInformation.

MSDN ZwQueryInformationFile

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 04 декабря 2009 00:53 · Поправил: tihiy_grom
· Личное сообщение · #4

SLV
я похучил DeviceIoControl. Мне надо из передаваемого ей хэндла получить имя
саму прогу не трогаю

ntldr
спасибо, будем пробовать



Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 04 декабря 2009 00:59
· Личное сообщение · #5

Сори протупил, забыл что процесс свой и условия задачи)

-----
Shalom ebanats!




Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 04 декабря 2009 20:00
· Личное сообщение · #6

ntldr
К сожалению тоже не получилось

Code:
  1. type
  2.  
  3.  NT_Status = cardinal;
  4.  
  5.  PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
  6.  IO_STATUS_BLOCK = packed record
  7.    Status: NT_STATUS;
  8.    Pointer: pointer;
  9.    Information: DWORD;
  10.  end;
  11.  
  12.  PFILE_NAME_INFORMATION = ^FILE_NAME_INFORMATION;
  13.  FILE_NAME_INFORMATION = packed record
  14.    FileNameLength: ULONG;
  15.    FileName: array [0..MAX_PATH - 1] of WideChar;
  16.  end;
  17.  
  18. const
  19.  FileNameInformation = 9;
  20.  
  21.  function ZwQueryInformationFile(FileHandle: THandle;
  22.     IoStatusBlock: PIO_STATUS_BLOCK; FileInformation: Pointer;
  23.     Length: DWORD; FileInformationClass: DWORD): NT_STATUS; stdcall; external 'ntdll.dll';
  24.  
  25. procedure TForm1.FormCreate(Sender: TObject);
  26. var
  27.  hFile: THandle;
  28.  FileNameInfo: FILE_NAME_INFORMATION;
  29.  IoStatusBlock: IO_STATUS_BLOCK;
  30. begin
  31.  hFile:=CreateFile('\.\PhysicalDrive0',GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
  32.  ZeroMemory(@FileNameInfo, SizeOf(FILE_NAME_INFORMATION));
  33.  ZwQueryInformationFile(hFile,@IoStatusBlock,@FileNameInfo,MAX_PATH * 2, FileNameInformation);
  34. end;

Как и в первом варианте - этот код с файлами работает на ура, а с "\.\PhysicalDrive0" справиться не может.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 04 декабря 2009 20:23
· Личное сообщение · #7

В таком случае только драйвер, в котором будет использоваться связка ObReferenceObjectByHandle / ObQueryNameString. Работает 100%.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 04 декабря 2009 20:28
· Личное сообщение · #8

С дровами не дружу

Есть конечно мысль - хучить ещё и CreateFile, и постоянно следить за именами, которые в неё передаются. Но это как-то не радует.



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 04 декабря 2009 21:04
· Личное сообщение · #9

tihiy_grom
Если речь об аспре, то всё намного проще. Если нет, то вариант следить не за CreateFile, а за стэком чем не устраивает?



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 05 декабря 2009 18:29 · Поправил: HiEndsoft
· Личное сообщение · #10

tihiy_grom
Пробовали
NtQueryObject (hFileHandle,ObjectNameInformation,NULL,0,&size );
NtQueryObject(hFileHandle,ObjectNameInformation,(PVOID)lpBuffer, size, &ret_val ); ?

-----
продавец резиновых утёнков




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 05 декабря 2009 18:34
· Личное сообщение · #11

Кстати, может помочь.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 05 декабря 2009 20:17 · Поправил: tihiy_grom
· Личное сообщение · #12

Аллах акбар, всё получилось

вот код, если кому пригодится
Code:
  1. type
  2.  
  3.  NT_Status = cardinal;
  4.  
  5.  PUNICODE_STRING = ^TUNICODE_STRING;
  6.  TUNICODE_STRING = packed record
  7.    Length : WORD;
  8.    MaximumLength : WORD;
  9.    Buffer : array [0..MAX_PATH - 1] of WideChar;
  10.  end;
  11.  
  12.  POBJECT_NAME_INFORMATION = ^TOBJECT_NAME_INFORMATION;
  13.  TOBJECT_NAME_INFORMATION = packed record
  14.    Name : TUNICODE_STRING;
  15.  end;
  16.  
  17.  
  18. const
  19.  ObjectNameInformation = 1;
  20.  
  21.  function NtQueryObject(ObjectHandle: THandle; ObjectInformationClass: DWORD; ObjectInformation: Pointer;
  22.   ObjectInformationLength: ULONG; ReturnLength: PDWORD): NT_STATUS; stdcall; external 'ntdll.dll';
  23.  
  24.  
  25. procedure TForm1.FormCreate(Sender: TObject);
  26. var
  27.  hFile: THandle;
  28.  ObjectNameInfo: TOBJECT_NAME_INFORMATION;
  29.  res,dwReturn: DWORD;
  30.  handle_name: string;
  31. begin
  32.  hFile:=CreateFile('\.\PhysicalDrive0',GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
  33.  res:=NtQueryObject(hFile,ObjectNameInformation,@ObjectNameInfo,SizeOf(ObjectNameInfo.Name.Buffer),@dwReturn);
  34.  handle_name:='';
  35.  if res = STATUS_SUCCESS then begin
  36.   SetLength(handle_name,MAX_PATH);
  37.   SetLength(handle_name,WideCharToMultiByte(CP_ACP, 0,
  38.    @ObjectNameInfo.Name.Buffer[ObjectNameInfo.Name.MaximumLength -
  39.    ObjectNameInfo.Name.Length],
  40.    ObjectNameInfo.Name.Length div SizeOf(WideChar),
  41.    @handle_name[1],MAX_PATH, nil, nil));
  42.  end;
  43. end;


Всем спасибо за ответы и за помощь.

P.S.
HiEndsoft,теперь ты мой кумир


 eXeL@B —› Программирование —› Получить имя файла по его хэндлу
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати