![]() |
Papierkorb INFO2: Originaldateiname & -pfad ermitteln
Hallo zusammen.
Nachdem ich durch ![]()
Delphi-Quellcode:
Achtung: Diese Funktion ist unicodesicher. Man sollte unicodesichere Komponenten sowie WideString-Funktionen (copyfilew, movefilew, deletefilew, messageboxw...) verwenden.
// 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; Ein Beispiel zum Herauskopieren einer Datei aus dem Papierkorb an Ihre ursprüngliche Position:
Delphi-Quellcode:
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).
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; Und jetzt noch für alle, die keinen Unicode-Support benötigen. Ausgabe ist ein String.
Delphi-Quellcode:
Die Ausgabe können wir nun auch in eine normale showmessage() einspeißen:
// 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;
Delphi-Quellcode:
Bei copyfilea, movefilea, deletefilea, messageboxa... muss pchar() angewandt werden.
const
testdatei = 'C:\Recycler\S-1-5-21-515967899-1957994488-839522115-1003\Dc5.txt'; begin showmessage(get_recycler_filename(testdatei)); end; 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: ![]() Gruß blackdrake |
Re: Originaldateiname & -pfad einer gelöschten Datei erm
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. |
Re: Originaldateiname & -pfad einer gelöschten Datei erm
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 |
Re: Originaldateiname & -pfad einer gelöschten Datei erm
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 |
Re: Papierkorb INFO2: Originaldateiname & -pfad ermittel
Anmerkung: Diese 2 Funktionen, die ich hier zum Vorschlag gegebenen habe, sind eigenständige Vorgängerversionen meiner neuen Recycle-Bin-Unit (
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:10 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