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 (copyfile
w, movefile
w, deletefile
w, messagebox
w...) 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 copyfile
a, movefile
a, deletefile
a, messagebox
a... 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