AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Papierkorb INFO2: Originaldateiname & -pfad ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Papierkorb INFO2: Originaldateiname & -pfad ermitteln

Ein Thema von blackdrake · begonnen am 12. Aug 2007 · letzter Beitrag vom 17. Aug 2007
Antwort Antwort
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#1

Papierkorb INFO2: Originaldateiname & -pfad ermitteln

  Alt 12. Aug 2007, 02:28
Hallo zusammen.

Nachdem ich durch http://www.delphipraxis.net/internal...t.php?t=115973 eine Lösung meines Unicode-Problemes gefunden habe, kann ich hier meine neue Funktion veröffentlichen, die in meiner neuen Version meiner Verschlüsselungssoftware (OpenSource) verwendet wird. Diese Funktion ermittelt den Originaldateinamen einer Datei im Windows-Papierkorb. Angegeben werden muss der komplette und korrekte Pfad der physikalischen Datei auf der Festplatte. Durch Auslesung aus der Datei INFO2 wird dann der Originalpfad und -dateiname ermittelt.

Delphi-Quellcode:
// get_recycler_filename_unicode von Daniel Marschall
// Gibt den Originaldateinamen einer gelöschten Datei wieder

// Erwartete Eingaben
// NTFS: ?:\Recycler\<SID>\D?*.*
// FAT: ?:\Recycled\D?*.*

// Info: Wenn nur der Originaldateiname - ohne Pfad - herausgefunden werden
// soll, so muss man extractfilename() zusätzlich anwenden.

// Nicht Vista-Fähig

// Vollversion der Recycler-Bin-Unit (mit Vista-Support):
// [url]http://www.viathinksoft.de/index.php?page=projektanzeige&seite=download&id=124[/url]

function get_recycler_filename_unicode(filename: string): WideString;

  function ReadWideString(const Stream: TStream): WideString;
  var
    S: WideString;
    WC: WideChar;
  begin
    S := '';
    repeat
      Stream.ReadBuffer(WC, 2);
      if (WC <> #0) then
        S := S + WC;
    until WC = #0;
    Result := S;
  end;

var
  fs: TFileStream;
  buf: integer;
  suche: string;
  i: integer;
const
  record_length = $320;
  unique_index_position = $118;
  unicode_source_position = $12C;
  info_file = 'INFO2';
begin
  result := '';
  suche := copy(filename, 0, length(filename)-length(extractfileext(filename)));
  suche := extractfilename(suche);
  suche := copy(suche, 3, length(suche)-2);
  fs := TFileStream.Create(extractfilepath(filename)+info_file, fmOpenRead);
  try
    i := -1;
    repeat
      inc(i);
      if unique_index_position+i*record_length > fs.size then break;
      fs.seek(unique_index_position+i*record_length, soFromBeginning);
      fs.ReadBuffer(buf, 4);
      if buf = strtoint(suche) then
      begin
        fs.seek(unicode_source_position+i*record_length, soFromBeginning);
        result := ReadWideString(fs);
        break;
      end;
    until false;
  finally
    fs.free;
  end;
end;
Achtung: Diese Funktion ist unicodesicher. Man sollte unicodesichere Komponenten sowie WideString-Funktionen (copyfilew, movefilew, deletefilew, messageboxw...) verwenden.

Ein Beispiel zum Herauskopieren einer Datei aus dem Papierkorb an Ihre ursprüngliche Position:

Delphi-Quellcode:
const
  wiederherzustelende_datei = 'C:\Recycler\S-1-5-21-515967899-1957994488-839522115-1003\Dc5.txt';
  ueberschreibe_existierende_datei = true;
var
  original_name: string;
begin
  original_name := get_recycler_filename_unicode(wiederherzustelende_datei);
  forcedirectories(extractfilepath(original_name));
  copyfilew(wiederherzustelende_datei, original_name, not ueberschreibe_existierende_datei);
end;
Wichtig: movefilew() oder deletefilew() sollte auf Papierkorbelemente nicht angewendet werden, da dann die INFO2 ungültige Bezüge erhält. Möchte man z.B. eine Papierkorbdatei sicher vernichten (nicht nur löschen), kann man sie mehrmals überschreiben lassen und dann mit Win32-API-Befehlen sauber löschen. Möchte man eine Datei sicher verschieben, so kopiert an sie zuerst, überschreibt dann die Papierkorbdatei und löscht sie dann mit der Win32-API. Windows löscht übrigens fehlerhafte Bezüge in der INFO2 Datei, trotzdem kann der Benutzer bei Anwendung von movefilew() oder deletefilew() ein falsches Papierkorbicon zu Gesicht bekommen (weil Windows aufgrund der INFO2-Informationen denkt, es sei noch was im Papierkorb, obwohl er mittlerweile leer ist).

Und jetzt noch für alle, die keinen Unicode-Support benötigen. Ausgabe ist ein String.

Delphi-Quellcode:
// get_recycler_filename von Daniel Marschall
// Gibt den Originaldateinamen einer gelöschten Datei wieder
// Nicht-Unicode-Sicher!

// Erwartete Eingaben
// NTFS: ?:\Recycler\<SID>\D?*.*
// FAT: ?:\Recycled\D?*.*

// Info: Wenn nur der Originaldateiname - ohne Pfad - herausgefunden werden
// soll, so muss man extractfilename() zusätzlich anwenden.

// Nicht Vista-Fähig

// Vollversion der Recycler-Bin-Unit (mit Vista-Support):
// [url]http://www.viathinksoft.de/index.php?page=projektanzeige&seite=download&id=124[/url]

function get_recycler_filename(filename: string): string;

  function ReadString(const Stream: TStream): String;
  var
    S: String;
    C: Char;
  begin
    S := '';
    repeat
      Stream.ReadBuffer(C, 1);
      if (C <> #0) then
        S := S + C;
    until C = #0;
    Result := S;
  end;

var
  fs: TFileStream;
  buf: integer;
  suche: string;
  i: integer;
const
  record_length = $320;
  unique_index_position = $118;
  source_position = $14;
  info_file = 'INFO2';
begin
  result := '';
  suche := copy(filename, 0, length(filename)-length(extractfileext(filename)));
  suche := extractfilename(suche);
  suche := copy(suche, 3, length(suche)-2);
  fs := TFileStream.Create(extractfilepath(filename)+info_file, fmOpenRead);
  try
    i := -1;
    repeat
      inc(i);
      if unique_index_position+i*record_length > fs.size then break;
      fs.seek(unique_index_position+i*record_length, soFromBeginning);
      fs.ReadBuffer(buf, 4);
      if buf = strtoint(suche) then
      begin
        fs.seek(source_position+i*record_length, soFromBeginning);
        result := ReadString(fs);
        break;
      end;
    until false;
  finally
    fs.free;
  end;
end;
Die Ausgabe können wir nun auch in eine normale showmessage() einspeißen:

Delphi-Quellcode:
const
  testdatei = 'C:\Recycler\S-1-5-21-515967899-1957994488-839522115-1003\Dc5.txt';
begin
  showmessage(get_recycler_filename(testdatei));
end;
Bei copyfilea, movefilea, deletefilea, messageboxa... muss pchar() angewandt werden.

Sollten ausländische Zeichen (z.B. japanische) vorkommen, versucht Windows, in der ANSI-Fassung der Stelle des originalen Dateinamens bei INFO2, einen verkürzten Namen zu finden. Nehmen wir an, wir löschen die Datei Testそしてそれは実際に翻訳するした.txt. Verwenden wir nun die Nicht-Ansi-Funktion, wird die Datei beim Wiederherstellen nur noch Test~1.txt heißen. Außerdem erhalten die Verzeichnisse, die zu dieser Datei hinführen (z.B. "Dokumente und Einstellungen") ebenfalls einen verkürzten Namen mit Tilde. Existieren diese Verzeichnissen nicht, werden sie nicht mit ihrem vollständigen Namen wiederhergestellt.

Weitere Informationen zur INFO2-Datei hier: http://www.e-fense.com/helix/Docs/Re...nstruction.pdf

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.201 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Originaldateiname & -pfad einer gelöschten Datei erm

  Alt 12. Aug 2007, 17:14
Also so kann man das definitiv nicht übernehmen!

Ich habs versucht zum laufen zu bekommen, aber neben den Verwurschtelung von Sting/WideString/P(Wide)Char müssen hier noch weiter Logikfehler vorliegen. Muss erst mal verstehen was überhaupt das PDF darüber aussagt.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Originaldateiname & -pfad einer gelöschten Datei erm

  Alt 12. Aug 2007, 18:04
Hallo.

Logikfehler können hier eigentlich keine vorliegen. Bei mir hat alles funktioniert. Vorraussetzung ist, dass du eine gültige Datei einspeißt. Deine SID muss übereinstimmen und die Testdatei (z.B. DC5.txt) muss tatsächlich sich gerade im Recycler befinden.

Mit der INFO2 ist es ganz einfach:

Jeder Eintrag hat 320h Byte länge.
Bei 14h beginnt der nullterminierte ANSI-Originalpfad.
Bei 12Ch beginnt der nullterminierte UNICODE-Originalpfad.
Und bei 118h beginnt ein 4 Byte Integer Bezeichner, der dem 123 von DC123.txt entspricht.

Bei den "Sting/WideString/P(Wide)Char"-Problemen bräuchte ich noch Unterstützung, weil ich mich mit Pointern nicht auskenne. Bin mir nicht sicher, ob meine Unicodeumwandlung vom Code her sauber ist.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#4

Re: Originaldateiname & -pfad einer gelöschten Datei erm

  Alt 12. Aug 2007, 18:30
Hallo.

Ich hab meinen Eintrag aktualisiert. Jetzt müsste mein Code sauber sein, da ich die Funktionen ReadString() und ReadWideString() verwendet habe. Ich habe nochmal beide Funktionen getestet. Meine INFO2 wird korrekt ausgelesen. Bitte um nochmalige Prüfung.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#5

Re: Papierkorb INFO2: Originaldateiname & -pfad ermittel

  Alt 17. Aug 2007, 02:25
Anmerkung: Diese 2 Funktionen, die ich hier zum Vorschlag gegebenen habe, sind eigenständige Vorgängerversionen meiner neuen Recycle-Bin-Unit (http://www.delphipraxis.net/internal...t.php?t=116393). Diese Unit unterstützt Papierkörbe von 95 bis Vista komplett, die Funktionen können aber nicht ohne die restliche Unit verwendet werden.
Daniel Marschall
  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:37 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