AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Dateiname zu FileHandle auslesen
Thema durchsuchen
Ansicht
Themen-Optionen

Dateiname zu FileHandle auslesen

Ein Thema von himitsu · begonnen am 2. Dez 2007 · letzter Beitrag vom 3. Jan 2008
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#1

Dateiname zu FileHandle auslesen

  Alt 2. Dez 2007, 19:42
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 MSDN-Library durchsuchenReOpenFile (da erst ab Vista) aktivieren und den Ersatzcode weglassen,
aber dafür bräuchte ich eine Möglichkeit um an den Dateinamen ranzukommen
um einen Vor-Vista-Ersatz schreiben zu können:
Code:
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_;
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.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#2

Re: Dateiname zu FileHandle auslesen

  Alt 2. Dez 2007, 19:54
http://msdn2.microsoft.com/en-us/library/aa366789.aspx

Hilft dir das ggf. ?
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#3

Re: Dateiname zu FileHandle auslesen

  Alt 2. Dez 2007, 20:12
Hallo Frank,

es gibt eine undokumentierte API Funktion namens NTQueryInformationFile() für alle NT-basierten Kernel.

Grüße vom marabu
  Mit Zitat antworten Zitat
Wotan89

Registriert seit: 20. Nov 2007
77 Beiträge
 
Delphi 2005 Personal
 
#4

Re: Dateiname zu FileHandle auslesen

  Alt 2. Dez 2007, 20:20
Ich glaub eine Lösung wäre für dich GetModuleFileNameEx. Dazu musst du nur psapi in den uses einbinden.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

Re: Dateiname zu FileHandle auslesen

  Alt 2. Dez 2007, 20:54
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 MSDN-Library durchsuchenNTQueryInformationFile probier ich grad.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

Re: Dateiname zu FileHandle auslesen

  Alt 2. Dez 2007, 22:27
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


MSDN > ZwQueryInformationFile


so, hab's jetzt einfach durchprobiert und die 9 brachte gleich eine Lösung

nur liefert ZwQueryInformationFile leider nur /pfad/datei ohne Laufwerksangabe
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

Re: Dateiname zu FileHandle auslesen

  Alt 3. Jan 2008, 03:09
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:
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;
im Angang ist 'nen Testprogramm mit
Delphi-Quellcode:
Function ReOpenFileW(hOriginalFile: THandle; dwDesiredAccess,
  dwShareMode, dwFlags: LongWord): THandle; StdCall;

Function FileHandleToFileName(hFile: THandle): TDynWideStringArray;
Infos:
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 )


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 > GetLogicalDriveStringsW und PAnsiChar
Angehängte Dateien
Dateityp: 7z reopenfile_180.7z (26,8 KB, 28x aufgerufen)
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz