![]() |
Dateiname zu FileHandle auslesen
mir war zwar so, als wenn's hier mal etwas dazu gab, aber hab irgendwie nichts gefunden -.-''
also, weiß zufällig wer wie ich aus einem FileHandle (CreateFile) den Dateinamen rausbekomm? über MemoryMapping und GetModuleFilename ging's leider nicht. ich wollte meinen Programmcode etwas aufräumen und daher das auskommentierte ![]() aber dafür bräuchte ich eine Möglichkeit um an den Dateinamen ranzukommen um einen Vor-Vista-Ersatz schreiben zu können:
Code:
Und nein, auch noch CreateFile/CloseHandle zu hooken und die Dateinamen/FileHandles zu speichern kommt nicht in Frage ... da laß ich es doch lieber so wie es jetzt ist.
Var ReOpenFileW: Function (hOriginalFile: THandle;
dwDesiredAccess, dwShareMode, dwFlags: LongWord): THandle; StdCall; Function ReOpenFileW_(hOriginalFile: THandle; dwDesiredAccess, dwShareMode, dwFlags: LongWord): THandle; StdCall; Var FileName: WideString; lpSecurityAttributes: PSecurityAttributes; hTemplateFile: THandle; Begin FileName := [color=red]FileHandleToFileName[/color](hOriginalFile); lpSecurityAttributes := nil; // diese Beiden müssen für mich nicht hTemplateFile := 0; // unbedingt ausgelesen werden CloseHandle(hOriginalFile); Result := CreateFileW(PWideChar(FileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, OPEN_EXISTING, dwFlags, hTemplateFile); End; ReOpenFileW := GetProcAddress(GetModuleHandle('kernel32.dll'), 'ReOpenFileW'); If @ReOpenFileW = nil Then ReOpenFileW := @ReOpenFileW_; |
Re: Dateiname zu FileHandle auslesen
|
Re: Dateiname zu FileHandle auslesen
Hallo Frank,
es gibt eine undokumentierte API Funktion namens NTQueryInformationFile() für alle NT-basierten Kernel. Grüße vom marabu |
Re: Dateiname zu FileHandle auslesen
Ich glaub eine Lösung wäre für dich GetModuleFileNameEx. Dazu musst du nur psapi in den uses einbinden.
|
Re: Dateiname zu FileHandle auslesen
Also abgesehn daß ich das mit dem GetMappedFileName noch nicht ganz zum laufen gebracht hatte, ginge es eh nicht, da CreateFileMapping nur mit Dateien funktioniert, welche mindestens über Leserechte verfügen,
aber meine Dateien (wo ich es aktuell bräuchte) sind nur mit Schreibrechten (GENERIC_WRITE) geöffnet/erstellt. :? Bei GetModuleFileNameEx das Selbe. Das mit ![]() |
Re: Dateiname zu FileHandle auslesen
könnte bitte mal jemand den Wert für FileNameInformation posten?
laut MSDN irgendwo in wdm.h. Include wdm.h, ntddk.h oder ntifs.h hab hier leider kein PSDK installiert :cry: ![]() so, hab's jetzt einfach durchprobiert und die 9 brachte gleich eine Lösung :stupid: nur liefert ZwQueryInformationFile leider nur /pfad/datei ohne Laufwerksangabe :cry: |
Re: Dateiname zu FileHandle auslesen
Liste der Anhänge anzeigen (Anzahl: 1)
So, hab inzwischen eine "Lösung" gefunden.
QueryInformationFile gibt mir Pfad+Dateiname GetFileInformationByHandle rückt die Partition (VolumeSerialNumber) raus dann werden noch die (hoffentlich alle nötigen) Laufwerke durchforstes und die Gewünschten über ihre VolumeSerialNumber ausgewählt. FileHandleToFileName ist eine eigene Funktion, welche den Dateinamen zurückgibt. (KO, ein Array mit eventuell Mehreren, da eine Partition mehrfach gemountet sein kann und es auf diese Weise keine eindeutige Zuordnung gibt)
Delphi-Quellcode:
im Angang ist 'nen Testprogramm mit
Function _ReOpenFileW(hOriginalFile: THandle; dwDesiredAccess, dwShareMode, dwFlags: LongWord): THandle; StdCall;
Var ioSB: IO_STATUS_BLOCK; FNI: FILE_NAME_INFORMATION; BHFI: BY_HANDLE_FILE_INFORMATION; FileName, S, S2, S3: WideString; FileDrives: Array of WideString; lpSecurityAttributes: PSecurityAttributes; hTemplateFile: THandle; W, W2: LongWord; i: Integer; Sh: THandle; Begin Result := hOriginalFile; ZeroMemory(@FNI, SizeOf(FNI)); If QueryInformationFile(hOriginalFile, ioSB, @FNI, SizeOf(FNI), FileNameInformation) <> STATUS_SUCCESS Then Exit; If not GetFileInformationByHandle(hOriginalFile, BHFI) Then Exit; FileName := Copy(FNI.FileName, 1, FNI.FileNameLength div 2); FileDrives := nil; SetLength(S, 1024); GetLogicalDriveStringsW(255, PChar(S)); S := Trim(S); While S <> '' do Begin S2 := PWideChar(S); Delete(S, 1, Length(S2)); S := Trim(S); If not GetVolumeInformationW(PWideChar(S2), nil, 0, @W, W2, W2, nil, 0) or (W <> BHFI.dwVolumeSerialNumber) Then Continue; i := Length(FileDrives); SetLength(FileDrives, i + 1); FileDrives[i] := S2; End; SetLength(S, MAX_PATH - 1); Sh := FindFirstVolumeW(PWideChar(S), MAX_PATH); If Sh <> INVALID_HANDLE_VALUE Then Repeat S := PWideChar(S); If not GetVolumeInformationW(PWideChar(S), nil, 0, @W, W2, W2, nil, 0) or (W <> BHFI.dwVolumeSerialNumber) Then Continue; W := 1024; GetVolumePathNamesForVolumeNameW(PWideChar(S), nil, 0, @W); SetLength(S2, W); If GetVolumePathNamesForVolumeNameW(PWideChar(S), PWideChar(S2), W + 1, @W) Then Begin SetLength(S2, W - 2); While S2 <> '' do Begin S3 := PWideChar(S2); Delete(S2, 1, Length(S3)); S2 := Trim(S2); i := Length(FileDrives); SetLength(FileDrives, i + 1); FileDrives[i] := S3; End; End; i := Length(FileDrives); SetLength(FileDrives, i + 1); FileDrives[i] := S; SetLength(S, MAX_PATH - 1); Until not FindNextVolumeW(Sh, PWideChar(S), MAX_PATH); FindVolumeClose(Sh); lpSecurityAttributes := nil; hTemplateFile := 0; CloseHandle(hOriginalFile); Result := INVALID_HANDLE_VALUE; For i := 0 to High(FileDrives) do Begin Result := CreateFileW(PWideChar(FileDrives[i] + FileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, OPEN_EXISTING, dwFlags, hTemplateFile); If Result <> INVALID_HANDLE_VALUE Then Break; End; End;
Delphi-Quellcode:
Infos:
Function ReOpenFileW(hOriginalFile: THandle; dwDesiredAccess,
dwShareMode, dwFlags: LongWord): THandle; StdCall; Function FileHandleToFileName(hFile: THandle): TDynWideStringArray; ReOpenFile wurde in Vista eingeführt. (die Ersatzfunktion funktioniert hoffentlich schon ab Win2Kpro) FileHandleToFileName gibt den/die vollständigen Dateinamen der Datei (dem Handle) zurück. GetVolumePathNamesForVolumeName wurde in WinXP eingeführt (Ersatzfunktion ist also für Win2Kpro mit enthalten ... hab ich glaub'sch schonmal hier irgendwo veröffentlich :gruebel: ) Achtung lpSecurityAttributes und hTemplateFile wird nicht übernommen, hab noch nicht rausgefunden wie diese ausgelesen werden, aber Meistens werden die eh nicht verwendet *duck* Und dann weiß ich noch nicht ob der Dateizeiger in Vista übernommen wird. Also wenn das mal bitte wer testen könnte? Hab derzeit kein Vista installiert -.-'' > Testprogramm starten und auf die Ausgabe achten (da wird eine Testdatei ausgelesen und die Zeigerpositionen angezeigt) PS: die CompilerWarnung GetLogicalDriveStringsW+PAnsiChar einfach ignorieren ... ist schon richtig so > Delphi - Bugreports > ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz