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

Papierkorb INFO2: Originaldateiname & -pfad ermitteln

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

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

Papierkorb INFO2: Originaldateiname & -pfad ermitteln

  Alt 12. Aug 2007, 01: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
 

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 00:21 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