Subversion Repositories delphiutils

Compare Revisions

No changes between revisions

Regard whitespace Rev HEAD → Rev 1

/trunk/_Common/DropFiles.pas
File deleted
/trunk/_Common/DropFiles.dfm
File deleted
/trunk/_Common/AdoConnHelper.pas
File deleted
/trunk/Zeiterfassung/clock.ico
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Zeiterfassung/Zeiterfassung.dproj
File deleted
\ No newline at end of file
/trunk/Zeiterfassung/Zeiterfassung.ini
File deleted
\ No newline at end of file
/trunk/Zeiterfassung/Zeiterfassung.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Zeiterfassung/delwaste.bat
File deleted
/trunk/Zeiterfassung/Zeiterfassung.dpr
File deleted
/trunk/Zeiterfassung/SQL/TAGE.sql
File deleted
/trunk/Zeiterfassung/SQL/REGELARBEITSZEIT.sql
File deleted
/trunk/Zeiterfassung/ZeiterfassungMain.pas
File deleted
/trunk/Zeiterfassung/Zeiterfassung.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Zeiterfassung/ZeiterfassungMain.dfm
File deleted
/trunk/Zeiterfassung
Property changes:
Deleted: svn:ignore
-*.dcu
-*.~*
-*.ddp
-*.exe
-*.map
-*.bak
-*.obj
-*.dsk
-*.err
-*.log
-*.tmp
-*.identcache
-*.tvsconfig
-__history
-__recovery
-ModelSupport*
-*.local
-*.drc
-*.lib
-*.bpi
-*.hpp
/trunk/Readme.md
File deleted
/trunk/ShortcutSearchReplace/ShortcutSearchReplace.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/ShortcutSearchReplace/ShortcutSearchReplace.dpr
File deleted
/trunk/ShortcutSearchReplace/Unit1.pas
File deleted
/trunk/ShortcutSearchReplace/ShortcutSearchReplace.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/ShortcutSearchReplace/Unit1.dfm
File deleted
/trunk/ShortcutSearchReplace/ShortcutSearchReplace.dproj
File deleted
/trunk/Signaturen.txt
File deleted
/trunk/Create Shortcut/Shortcut.dpr
File deleted
/trunk/Create Shortcut/Shortcut.dproj
File deleted
\ No newline at end of file
/trunk/Create Shortcut/Shortcut.cfg
File deleted
/trunk/Create Shortcut/Shortcut.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Create Shortcut/Shortcut.bdsproj
File deleted
/trunk/Delphi Code/DragNDropDlgs/DlgExtended.dof
File deleted
/trunk/Delphi Code/DragNDropDlgs/Manifest.RES
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Delphi Code/DragNDropDlgs/DlgExtended.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Delphi Code/DragNDropDlgs/WindowsCompat.pas
File deleted
/trunk/Delphi Code/DragNDropDlgs/DlgExtended.cfg
File deleted
/trunk/Delphi Code/DragNDropDlgs/Main.pas
File deleted
/trunk/Delphi Code/DragNDropDlgs/DlgExtended.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Delphi Code/DragNDropDlgs/MethodPtr.pas
File deleted
/trunk/Delphi Code/DragNDropDlgs/Main.dfm
File deleted
/trunk/Delphi Code/DragNDropDlgs/Manifest.rc
File deleted
/trunk/Delphi Code/DragNDropDlgs/DlgExtended.bdsproj
File deleted
/trunk/Delphi Code/DragNDropDlgs/DlgExtended.dpr
File deleted
/trunk/Delphi Code/DragNDropDlgs/DlgExtended.exe.manifest
File deleted
/trunk/Delphi Code/DragNDropDlgs/DragDropOpenDlg.pas
File deleted
/trunk/Delphi Code/QuerySystemMenu/Main.dfm
File deleted
/trunk/Delphi Code/QuerySystemMenu/Demo.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Delphi Code/QuerySystemMenu/WindowsCompat.pas
File deleted
/trunk/Delphi Code/QuerySystemMenu/QuerySystemMenu.pas
File deleted
/trunk/Delphi Code/QuerySystemMenu/Demo.cfg
File deleted
/trunk/Delphi Code/QuerySystemMenu/Demo.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Delphi Code/QuerySystemMenu/Demo.bdsproj
File deleted
/trunk/Delphi Code/QuerySystemMenu/Main.pas
File deleted
/trunk/Delphi Code/QuerySystemMenu/Demo.dpr
File deleted
/trunk/Delphi Code/QuerySystemMenu/MethodPtr.pas
File deleted
/trunk/Delphi Code/ParamUtils/DemoMain.pas
File deleted
/trunk/Delphi Code/ParamUtils/Demo.dof
File deleted
/trunk/Delphi Code/ParamUtils/Demo.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Delphi Code/ParamUtils/DemoMain.dfm
File deleted
/trunk/Delphi Code/ParamUtils/DemoMain.ddp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Delphi Code/ParamUtils/Demo.cfg
File deleted
/trunk/Delphi Code/ParamUtils/ParamUtils.pas
File deleted
/trunk/Delphi Code/ParamUtils/Demo.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Delphi Code/ParamUtils/Demo.bdsproj
File deleted
/trunk/Delphi Code/ParamUtils/Demo.dpr
File deleted
/trunk/Delphi Code/ParamUtils/Functions.pas
File deleted
/trunk/FileReadChecker/FileReadChecker.dproj
File deleted
\ No newline at end of file
/trunk/FileReadChecker/FileReadChecker.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/FileReadChecker/FileReadChecker_Icon.ico
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/FileReadChecker/FileReadChecker.dpr
File deleted
/trunk/FileReadChecker/FileReadCheckerMain.pas
File deleted
/trunk/FileReadChecker/FileReadChecker.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/FileReadChecker/FileReadCheckerMain.dfm
File deleted
/trunk/Batch-Working-Directory/bwd.dof
File deleted
/trunk/Batch-Working-Directory/bwd.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Batch-Working-Directory/bwd.cfg
File deleted
/trunk/Batch-Working-Directory/bwd.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Batch-Working-Directory/bwd.dpr
File deleted
/trunk/Ideen.txt
File deleted
\ No newline at end of file
/trunk/Units/AsciiTable.pas
File deleted
/trunk/Units/BitOps.pas
File deleted
/trunk/Units/HighPerfFileComparator.pas
File deleted
/trunk/Units/md5.pas
File deleted
/trunk/Stoppuhren-Verwaltung/Stoppuhren.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Stoppuhren-Verwaltung/Main.dfm
File deleted
/trunk/Stoppuhren-Verwaltung/Stoppuhren.dpr
File deleted
/trunk/Stoppuhren-Verwaltung/about.pas
File deleted
/trunk/Stoppuhren-Verwaltung/MDIAPP.bdsproj
File deleted
/trunk/Stoppuhren-Verwaltung/Stoppuhren.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Stoppuhren-Verwaltung/about.dfm
File deleted
/trunk/Stoppuhren-Verwaltung/MDIAPP.ICO
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Stoppuhren-Verwaltung/ChildWin.pas
File deleted
/trunk/Stoppuhren-Verwaltung/Stoppuhren.dproj
File deleted
\ No newline at end of file
/trunk/Stoppuhren-Verwaltung/ChildWin.dfm
File deleted
/trunk/Stoppuhren-Verwaltung/Main.pas
File deleted
/trunk/Umlaut-Ersetzer/Umlautersetzer.bdsproj
File deleted
/trunk/Umlaut-Ersetzer/Umlautersetzer.dpr
File deleted
/trunk/Umlaut-Ersetzer/UmlautersetzerMain.pas
File deleted
/trunk/Umlaut-Ersetzer/Umlautersetzer.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Umlaut-Ersetzer/UmlautersetzerMain.dfm
File deleted
/trunk/Umlaut-Ersetzer/Umlautersetzer.cfg
File deleted
/trunk/Umlaut-Ersetzer/Umlautersetzer.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/_PostBuild.bat
File deleted
/trunk/_PreBuild.bat
File deleted
/trunk/FileExtCh/FileExtChMain.dfm
File deleted
/trunk/FileExtCh/FileExtCh.cfg
File deleted
/trunk/FileExtCh/FileExtCh.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/FileExtCh/FileExtCh.bdsproj
File deleted
/trunk/FileExtCh/FileExtCh.dpr
File deleted
/trunk/FileExtCh/FileExtCh.dof
File deleted
/trunk/FileExtCh/FileExtChMain.pas
File deleted
/trunk/FileExtCh/FileExtCh.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/SignExample/Example.bdsproj
File deleted
/trunk/SignExample/Example.dpr
File deleted
/trunk/SignExample/Example.cfg
File deleted
/trunk/SignExample/Example.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Kalenderersatz/Calender.dpr
File deleted
/trunk/Kalenderersatz/Calender.dof
File deleted
/trunk/Kalenderersatz/TimeDate.ico
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Kalenderersatz/Calender.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Kalenderersatz/Main.pas
File deleted
/trunk/Kalenderersatz/NoDoubleStart.pas
File deleted
/trunk/Kalenderersatz/Main.dfm
File deleted
/trunk/Kalenderersatz/Main.ddp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Kalenderersatz/Functions.pas
File deleted
\ No newline at end of file
/trunk/Kalenderersatz/Calender.cfg
File deleted
/trunk/Kalenderersatz/Calender.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Kalenderersatz/Calender.bdsproj
File deleted
/trunk/Kalenderersatz/FullYearCalendar.pas
File deleted
/trunk/Base-Converter/Main.dfm
File deleted
/trunk/Base-Converter/BaseConverter.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Base-Converter/BaseConverter.cfg
File deleted
/trunk/Base-Converter/BaseConverter.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Base-Converter/BaseConverter.bdsproj
File deleted
/trunk/Base-Converter/BaseConverter.dpr
File deleted
/trunk/Base-Converter/Main.pas
File deleted
/trunk/_Batch/processDir.bat
File deleted
/trunk/_Batch/cleanDir.bat
File deleted
/trunk/_Batch/signExe.bat
File deleted
/trunk/SmartDelphiTools.bdsgroup
File deleted
/trunk/LICENSE
File deleted
/trunk/DosLineConv/PosEx.pas
File deleted
/trunk/DosLineConv/DosLineConv.cfg
File deleted
/trunk/DosLineConv/BinarySafeReplace.pas
File deleted
/trunk/DosLineConv/DosLineConv.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/DosLineConv/DosLineConv.bdsproj
File deleted
/trunk/DosLineConv/DosLineConv.dpr
File deleted
/trunk/DosLineConv/DosLineConv.dof
File deleted
/trunk/DosLineConv/DosLineConv.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Dreisatz/Dreisatz.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Dreisatz/Dreisatz.cfg
File deleted
/trunk/Dreisatz/Dreisatz.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/Dreisatz/Main.pas
File deleted
/trunk/Dreisatz/Dreisatz.bdsproj
File deleted
/trunk/Dreisatz/Main.dfm
File deleted
/trunk/Dreisatz/Dreisatz.dpr
File deleted
/trunk/FileMD5/FileMD5.bdsproj
File deleted
/trunk/FileMD5/md5.pas
File deleted
/trunk/FileMD5/FileMD5.dpr
File deleted
/trunk/FileMD5/FileMD5.dof
File deleted
/trunk/FileMD5/FileMD5Main.pas
File deleted
/trunk/FileMD5/FileMD5.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/FileMD5/FileMD5Main.dfm
File deleted
/trunk/FileMD5/FileMD5Main.ddp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/trunk/FileMD5/FileMD5.cfg
File deleted
/trunk/FileMD5/FileMD5.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/Recycle Bin Unit/Recycler.dof
0,0 → 1,84
[FileVersion]
Version=6.0
[Compiler]
A=8
B=0
C=1
D=1
E=0
F=0
G=1
H=1
I=1
J=0
K=0
L=1
M=0
N=1
O=1
P=1
Q=0
R=0
S=0
T=0
U=0
V=1
W=0
X=1
Y=1
Z=1
ShowHints=1
ShowWarnings=1
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
[Linker]
MapFile=0
OutputObjs=0
ConsoleApp=1
DebugInfo=0
RemoteSymbols=0
MinStackSize=16384
MaxStackSize=1048576
ImageBase=4194304
ExeDescription=
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
Packages=vcl;rtl;vclx;VclSmp;vclshlctrls
Conditionals=
DebugSourceDirs=
UsePackages=0
[Parameters]
RunParams=
HostApplication=
Launcher=
UseLauncher=0
DebugCWD=
[Version Info]
IncludeVerInfo=1
AutoIncBuild=0
MajorVer=2
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=ViaThinkSoft
FileDescription=Delphi Recycle Bin Unit Demo
FileVersion=2.0.0.0
InternalName=RecyclerBinDemo
LegalCopyright=© Copyright 2007 - 2010 ViaThinkSoft
LegalTrademarks=Keine
OriginalFilename=Recycler.exe
ProductName=Delphi Recycle Bin Unit
ProductVersion=2010.01.21
Projektleiter=Daniel Marschall - www.daniel-marschall.de
Webseite=www.viathinksoft.de
/Recycle Bin Unit/RecyclerFunctions.pas
0,0 → 1,2654
////////////////////////////////////////////////////////////////////////////////////
// RECYCLE-BIN-FUNCTIONS BY DANIEL MARSCHALL //
// E-MAIL: info@daniel-marschall.de //
// WEB: www.daniel-marschall.de //
////////////////////////////////////////////////////////////////////////////////////
// Revision: 14 JUN 2010 //
// This unit is freeware, but please link to my website if you are using it! //
////////////////////////////////////////////////////////////////////////////////////
// Successful tested with: //
// Windows 95b, 95b + IE4, 98-SE, XP-SP2, 2000-SP4, 2003-SRV-EE-SP1, VISTA //
////////////////////////////////////////////////////////////////////////////////////
// //
// Needs Delphi 4 or higher. If you are using Delphi 4 or 5, you can not use the //
// RecyclerGetDateTime() functions, because the unit "DateUtils" is missing. //
// Warning! This is a platform unit. //
// //
// To do! Can you help? //
// - WideString-Support (input/output) //
// - GetLoginNameW: Really 255 maximum? //
// - Always do EOF before reading anything? //
// - Is it possible to identify a Vista-file that is not named $Ixxxxxx.ext? //
// - RecyclerGetInfofiles() check additionally for removable device? //
// RecyclerIsValid() is false. //
// - Function to get current state of recycle-bin (full, empty) //
// - Make functions to get the correct icons of full, empty, current //
// //
// Unknown! Do you know the answer? //
// - How does Windows 9x/NT manage the daylight saving time (if it does)? //
// - How does Windows Vista react to a RECYCLER\ folder on a NTFS device? //
// - How does Windows Vista react to a RECYCLED\ folder on a FAT device? //
// //
// Not analyzed yet! Please send me your trash folder contents for analyzing! //
// - Windows NT //
// - Windows CE? //
// - Windows 7 //
// //
// Thanks to all these who have helped me solving coding problems. //
// Thanks to SEBA for sending in the Windows Vista trash structure files. //
// Thanks to OMATA for testing the unit with Delphi 4. //
// Thanks to DEITYSOU for making a bugfix of DriveExists() //
// //
////////////////////////////////////////////////////////////////////////////////////
 
(*
 
== TODO LISTE ==
 
Wichtig! Windows XP: InfoTip, IntroText und LocalizedString sind Resourcenangaben und müssen ausgelesen werden!
Testen: Wie reagiert Windows, wenn Bitbucket\C existiert, aber kein Wert 'Percent' hat? Mit der Standardeinstellung?
Bug: Windows 2000 bei bestehenden Windows 95 Partition: Recycler Filename ist dann Recycled und nicht Recycler!
bug? w95 recycled file hat immer selben löschzeitpunkt und größe? war die nicht verschieden?
Feature: win7 support
beachtet? bei leerem papierkorb auf fat ist weder info noch info2 vorhanden?
testen: auch möglich, einen vista papierkorb offline öffnen?
Problem: bei win95(ohne ie4) und win2000 gleichzeitiger installation: es existiert info UND info2!!!
Neue Funktionen: GetCurrentRecyclerIcon, GetFullIcon, GetEmptyIcon
Bei Vista gibt es manchmal einen c0000013 Fehler. (Auslesen des ganzen Papierkorbs)
 
- Future -
 
Demoapplikation: Dateien statt als Text als Explorer-Like?
Einzelne Elemente oder alle wiederherstellen oder löschen
Konfiguration für Laufwerke ändern etc
IconString -> TIcon Convertion functions
platzreservierung in mb-angabe berechnen
I don't know if there exists any API function which checks the state at any internal way.
 
*)
 
// TODO: Also include BC++ Versions
{$IFNDEF BCB}
{$DEFINE DEL1UP}
{$IFNDEF VER80}
{$DEFINE DEL2UP}
{$IFNDEF VER90}
{$DEFINE DEL3UP}
{$IFNDEF VER100}
{$DEFINE DEL4UP}
{$IFNDEF VER120}
{$DEFINE DEL5UP}
{$IFNDEF VER130}
{$DEFINE DEL6UP}
{$IFNDEF VER140}
{$DEFINE DEL7UP}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
 
{$IFDEF DEL7UP}
{$WARN UNSAFE_TYPE OFF}
{$WARN UNSAFE_CODE OFF}
{$WARN UNSAFE_CAST OFF}
{$ENDIF}
 
{$IFDEF DEL6UP}
unit RecyclerFunctions platform;
{$ELSE}
unit RecyclerFunctions;
{$ENDIF}
 
// Configuration
 
// If enabled, all functions with parameter "InfofileOrRecycleFolder" will
// also accept files which are not the indexfile (then, a INFO2 or INFO file
// will be searched in this directory).
{.$DEFINE allow_all_filenames}
 
interface
 
uses
Windows, SysUtils, Classes, {$IFDEF DEL6UP}DateUtils,{$ENDIF}
ShellApi{$IFNDEF DEL6UP}, FileCtrl{$ENDIF}, Registry, ShellStateUnit;
 
type
EUnknownState = class(Exception);
EEventCategoryNotDefined = class(Exception);
EAPICallError = class(Exception);
 
PSHQueryRBInfo = ^TSHQueryRBInfo;
TSHQueryRBInfo = packed record
cbSize : dword;
i64Size : int64;
i64NumItems : int64;
end;
 
const
RECYCLER_CLSID = '{645FF040-5081-101B-9F08-00AA002F954E}';
 
{$IFDEF DEL6UP}
function RecyclerGetDateTime(drive: char; fileid: string): tdatetime; overload;
function RecyclerGetDateTime(drive: char; UserSID: string; fileid: string): tdatetime; overload;
function RecyclerGetDateTime(InfofileOrRecycleFolder: string): tdatetime; overload;
function RecyclerGetDateTime(InfofileOrRecycleFolder: string; id: string): tdatetime; overload;
{$ENDIF}
 
function RecyclerGetSourceUnicode(drive: char; fileid: string): WideString; overload;
function RecyclerGetSourceUnicode(drive: char; UserSID: string; fileid: string): WideString; overload;
function RecyclerGetSourceUnicode(InfofileOrRecycleFolder: string): WideString; overload;
function RecyclerGetSourceUnicode(InfofileOrRecycleFolder: string; id: string): WideString; overload;
 
function RecyclerGetSource(drive: char; fileid: string): string; overload;
function RecyclerGetSource(drive: char; UserSID: string; fileid: string): string; overload;
function RecyclerGetSource(InfofileOrRecycleFolder: string): string; overload;
function RecyclerGetSource(InfofileOrRecycleFolder: string; id: string): string; overload;
 
procedure RecyclerListIndexes(drive: char; result: TStringList); overload;
procedure RecyclerListIndexes(drive: char; UserSID: string; result: TStringList); overload;
procedure RecyclerListIndexes(InfofileOrRecycleFolder: string; result: TStringList); overload;
 
function RecyclerGetSourceDrive(drive: char; fileid: string): char; overload;
function RecyclerGetSourceDrive(drive: char; UserSID: string; fileid: string): char; overload;
function RecyclerGetSourceDrive(InfofileOrRecycleFolder: string): char; overload;
function RecyclerGetSourceDrive(InfofileOrRecycleFolder: string; id: string): char; overload;
 
function RecyclerOriginalSize(drive: char; fileid: string): integer; overload;
function RecyclerOriginalSize(drive: char; UserSID: string; fileid: string): integer; overload;
function RecyclerOriginalSize(InfofileOrRecycleFolder: string): integer; overload;
function RecyclerOriginalSize(InfofileOrRecycleFolder: string; id: string): integer; overload;
 
function RecyclerIsValid(drive: char): boolean; overload;
function RecyclerIsValid(drive: char; UserSID: string): boolean; overload;
function RecyclerIsValid(InfofileOrRecycleFolder: string): boolean; overload;
 
function RecyclerCurrentFilename(drive: char; fileid: string): string; overload;
function RecyclerCurrentFilename(drive: char; UserSID: string; fileid: string): string; overload;
function RecyclerCurrentFilename(InfofileOrRecycleFolder: string): string; overload;
function RecyclerCurrentFilename(InfofileOrRecycleFolder: string; id: string): string; overload;
 
function RecyclerGetPath(drive: char; UserSID: string; IncludeInfofile: boolean; fileid: string): string; overload;
function RecyclerGetPath(drive: char; UserSID: string; IncludeInfofile: boolean): string; overload;
function RecyclerGetPath(drive: char; IncludeInfofile: boolean): string; overload;
function RecyclerGetPath(drive: char; UserSID: string): string; overload;
function RecyclerGetPath(drive: char): string; overload;
 
procedure RecyclerGetInfofiles(drive: char; UserSID: string; IncludeInfofile: boolean; fileid: string; result: TStringList); overload;
procedure RecyclerGetInfofiles(drive: char; UserSID: string; IncludeInfofile: boolean; result: TStringList); overload;
procedure RecyclerGetInfofiles(drive: char; IncludeInfofile: boolean; result: TStringList); overload;
procedure RecyclerGetInfofiles(drive: char; UserSID: string; result: TStringList); overload;
procedure RecyclerGetInfofiles(drive: char; result: TStringList); overload;
 
function RecyclerCurrentFilenameAndPath(drive: char; UserSID: string; fileid: string): string; overload;
function RecyclerCurrentFilenameAndPath(drive: char; fileid: string): string; overload;
function RecyclerCurrentFilenameAndPath(InfofileOrRecycleFolder: string; id: string): string; overload;
 
function RecyclerRemoveItem(drive: char; UserSID: string; fileid: string): boolean; overload;
function RecyclerRemoveItem(drive: char; fileid: string): boolean; overload;
function RecyclerRemoveItem(InfofileOrRecycleFolder: string; id: string): boolean; overload;
 
procedure RecyclerGetAllRecyclerDrives(result: TStringList);
 
function RecyclerEmptyRecycleBin(flags: cardinal): boolean; overload;
function RecyclerEmptyRecycleBin(sound, progress, confirmation: boolean): boolean; overload;
 
function RecyclerAddFileOrFolder(FileOrFolder: string; confirmation: boolean): boolean; overload;
function RecyclerAddFileOrFolder(FileOrFolder: string): boolean; overload;
 
function RecyclerConfirmationDialogEnabled: boolean;
 
function RecyclerGetCurrentIconString: string;
function RecyclerGetDefaultIconString: string;
function RecyclerGetEmptyIconString: string;
function RecyclerGetFullIconString: string;
 
function RecyclerGetName: string;
function RecyclerGetInfoTip: string;
function RecyclerGetIntroText: string;
 
function RecyclerEmptyEventGetName: string;
function RecyclerEmptyEventGetCurrentSound: string;
function RecyclerEmptyEventGetDefaultSound: string;
procedure RecyclerEmptyEventGetSoundCategories(AStringList: TStringList);
function RecyclerEmptyEventGetSound(ACategory: string): string;
 
function RecyclerGlobalGetPercentUsage: integer;
function RecyclerSpecificGetPercentUsage(Drive: Char): integer;
function RecyclerGetPercentUsageAutoDeterminate(Drive: Char): integer;
 
function RecyclerGlobalIsNukeOnDelete: boolean;
function RecyclerSpecificIsNukeOnDelete(Drive: Char): boolean;
function RecyclerIsNukeOnDeleteAutoDeterminate(Drive: Char): boolean;
 
function RecyclerHasGlobalSettings: boolean;
 
function RecyclerIsEmpty: boolean; overload;
function RecyclerIsEmpty(Drive: Char): boolean; overload;
 
function RecyclerGetNumItems: int64; overload;
function RecyclerGetNumItems(Drive: Char): int64; overload;
 
function RecyclerGetSize: int64; overload;
function RecyclerGetSize(Drive: Char): int64; overload;
 
function RecyclerGetAPIInfo(Drive: Char): TSHQueryRBInfo; overload;
function RecyclerGetAPIInfo(Path: String): TSHQueryRBInfo; overload;
 
function RecyclerGetCLSID: string;
 
// Diese Funktion ist false, wenn sie z.B. unter Windows 95 ohne Internet Explorer
// 4.0 Shell Extension ausgeführt wird. Wenn abwärtskompatibler Code geschrieben
// werden soll, sollte RecyclerQueryFunctionAvailable() verwendet werden, da
// unter Windows 95 folgende Funktionalitäten NICHT vorhanden sind:
// - RecyclerIsEmpty
// - RecyclerGetNumItems
// - RecyclerGetSize
// - RecyclerGetAPIInfo
function RecyclerQueryFunctionAvailable: boolean;
 
function RecyclerLibraryVersion: string;
 
implementation
 
const
{$IFDEF MSWINDOWS}
shell32 = 'shell32.dll';
advapi32 = 'advapi32.dll';
{$ENDIF}
{$IFDEF LINUX}
shell32 = 'libshell32.borland.so';
advapi32 = 'libwine.borland.so';
{$ENDIF}
 
// **********************************************************
// COMPATIBILITY FUNCTIONS
// **********************************************************
 
{$IFNDEF DEL5UP}
function IncludeTrailingBackslash(str: string): string;
begin
if Copy(str, length(str), 1) = '\' then // TODO? Gibt es PathDelim in Delphi 4?
Result := str
else
Result := str + '\';
end;
{$ENDIF}
 
// **********************************************************
// INTERNALLY USED FUNCTIONS
// **********************************************************
 
type
TNibble = $0..$F;
TBitPos = 0..7;
 
resourcestring
LNG_UNEXPECTED_STATE = 'Cannot determinate state of "%s" because of an unknown value in the configuration of your operation system. Please contact the developer of the Recycler Bin Unit and help improving the determination methods!';
LNG_API_CALL_ERROR = 'Error while calling the API. Additional information: "%s".';
 
function _GetBit(B: Byte; BitPos: TBitPos): boolean; overload;
var
p: byte;
begin
p := 1 shl BitPos; // 2 ^ BitPos
result := B and p = p;
end;
 
function _GetBit(B: Char; BitPos: TBitPos): boolean; overload;
begin
result := _GetBit(Ord(B), BitPos);
end;
 
function _DriveNum(Drive: Char): Byte;
// a->0, ..., z->25
var
tmp: string;
begin
tmp := LowerCase(Drive);
result := Ord(tmp[1])-Ord('a');
end;
 
function _registryReadDump(AReg: TRegistry; AName: string): string;
const
// Win2000 RegEdit has set the max input length of a REG_BINARY to $3FFF.
// Probably its the longest possible binary string and not just a GUI limit.
BufMax = $3FFF;
var
buf: array[0..BufMax] of byte;
i: integer;
realsize: integer;
begin
realsize := AReg.ReadBinaryData(AName, buf, SizeOf(buf));
 
for i := 0 to realsize-1 do
begin
result := result + chr(buf[i]);
end;
end;
 
function _LowerNibble(B: Byte): TNibble;
begin
result := B and 15 {00001111};
end;
 
(* function _UpperNibble(B: Byte): TNibble;
begin
result := B and 240 {11110000};
end;
 
function _MakeByte(UpperNibble, LowerNibble: TNibble): Byte;
begin
result := LowerNibble + UpperNibble * $10;
end; *)
 
function _GetStringFromDLL(filename: string; num: integer): string;
const
// http://www.eggheadcafe.com/forumarchives/vcmfc/sep2005/post23917443.asp
MAX_BUF = 4097; // OK?
var
hLib: THandle;
buf: array[0..MAX_BUF] of char;
begin
hLib := LoadLibrary(PChar(filename));
try
LoadString(hLib, num, buf, sizeof(buf));
result := buf;
finally
FreeLibrary(hLib);
end;
end;
 
// http://www.delphi-library.de/topic_Umgebungsvariable+in+einem+String+aufloesen_20516,0.html
function _ExpandEnvStr(const szInput: string): string;
const
MAXSIZE = 32768; // laut PSDK sind 32k das Maximum
begin
SetLength(Result,MAXSIZE);
SetLength(Result,ExpandEnvironmentStrings(pchar(szInput),
@Result[1],length(Result))-1); //-1 um abschließendes #0 zu verwerfen
end;
 
// Beispiele
// Papierkorb -- Windows 95
// @C:\WINNT\system32\shell32.dll,-8964@1031,Papierkorb -- Windows 2000
 
function _DecodeReferenceString(s: string): string;
var
dll, id, lang, cache: string;
sl, sl2: tstringlist;
begin
if Copy(s, 1, 1) = '@' then
begin
// Referenz auf eine DLL
// @<dll>,-<id>[@<lang>][,<cache>]
 
sl := TStringList.Create;
try
// '@' am Anfang entfernen
s := Copy(s, 2, length(s)-1);
 
// Nach ',' auftrennen
// sl[0] --> dll
// sl[1] --> -id@lang
// sl[2] --> cache
sl.CommaText := s;
 
if sl.Count > 2 then
begin
// Das Ergebnis ist bereits im Klartext vorhanden und muss nicht extrahiert werden
// Ist bei Windows 2000 der Fall
cache := sl[2];
result := cache;
exit;
end;
 
if sl.Count > 1 then
begin
dll := sl[0];
 
sl2 := TStringList.Create;
try
// Nach '@' auftrennen
// sl2[0] --> id
// sl2[1] --> lang
sl2.CommaText := StringReplace(sl[1], '@', ',', [rfReplaceAll]);
 
id := sl2[0];
 
if sl2.Count > 1 then
begin
// ToDo: In Zukunft beachten, sofern möglich
lang := sl2[1];
end;
 
// Umgebungsvariablen erkennen und Minuszeichen entfernen
result := _GetStringFromDLL(_ExpandEnvStr(dll), -StrToInt(id));
finally
sl2.Free;
end;
end
else
begin
// Zu wenige Informationen!
 
result := '';
end;
finally
sl.Free;
end;
end
else
begin
// Kein Hinweis auf eine Referenz
result := s;
end;
end;
 
function _readInt8(const Stream: TStream): byte;
var
I: integer;
begin
i := 0;
Stream.ReadBuffer(i, 1);
Result := i;
end;
 
function _readInt32(const Stream: TStream): Longword;
var
I: integer;
begin
i := 0;
Stream.ReadBuffer(i, 4);
Result := i;
end;
 
function _readInt64(const Stream: TStream): int64;
var
I: int64;
begin
i := 0;
Stream.ReadBuffer(i, 8);
Result := i;
end;
 
function _readChar(const Stream: TStream): char;
var
C: Char;
begin
C := #0;
Stream.ReadBuffer(C, 1);
Result := C;
end;
 
function _readNullTerminatedString(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;
 
// http://www.delphipraxis.net/post761928.html#761928
function _readNullTerminatedWideString(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;
 
// http://www.delphipraxis.net/post340194.html#340194
function _nowUTC: TDateTime;
var
SystemTime: TSystemTime;
begin
GetSystemTime(SystemTime);
with SystemTime do
begin
Result := EncodeDate(wYear, wMonth, wDay) +
EncodeTime(wHour, wMinute, wSecond, wMilliseconds);
end;
end;
 
{$IFDEF DEL6UP}
function _getGMTDifference(): extended;
begin
result := - (datetimetounix(_nowUTC())-datetimetounix(Now())) / 3600;
end;
 
function _fileTimeToDateTime(FileTime: int64): TDateTime;
begin
// http://www.e-fense.com/helix/Docs/Recycler_Bin_Record_Reconstruction.pdf
// UnixTime = 0.0000001 * NTTime + 11644473600
// This is wrong! The correct formula is:
// UnixTime = 0.0000001 * NTTime - 11644473600 + c * 3600
// c = GMT-Difference (MEZ = 1) inclusive daylight saving time (+3600 seconds)
result := unixtodatetime(FileTime div 10000000 - 11644473600 + round(_getGMTDifference() * 3600));
end;
{$ENDIF}
 
// http://www.delphipraxis.net/post471470.html
function _getAccountSid(const Server, User: WideString; var Sid: PSID): DWORD;
var
dwDomainSize, dwSidSize: DWord;
R: LongBool;
wDomain: WideString;
Use: DWord;
begin
Result := 0;
SetLastError(0);
dwSidSize := 0;
dwDomainSize := 0;
R := LookupAccountNameW(PWideChar(Server), PWideChar(User), nil, dwSidSize,
nil, dwDomainSize, Use);
if (not R) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
begin
SetLength(wDomain, dwDomainSize);
Sid := GetMemory(dwSidSize);
R := LookupAccountNameW(PWideChar(Server), PWideChar(User), Sid,
dwSidSize, PWideChar(wDomain), dwDomainSize, Use);
if not R then
begin
FreeMemory(Sid);
Sid := nil;
end;
end
else
Result := GetLastError;
end;
 
// Template:
// http://www.latiumsoftware.com/en/pascal/0014.php
function _getLoginNameW: widestring;
var
Buffer: array[0..255] of widechar;
Size: dword;
begin
Size := 256;
if GetUserNameW(Buffer, Size) then
Result := Buffer
else
Result := 'User';
end;
 
function _Dyn_ConvertSidToStringSidA(SID: PSID; var strSID: LPSTR): boolean;
type
DllReg = function(SID: PSID; var StringSid: LPSTR): Boolean; stdcall;
var
hDll: THandle;
dr: DllReg;
begin
result := false;
hDll := LoadLibrary(advapi32);
if hDll <> 0 then
begin
@dr := GetProcAddress(hDll, 'ConvertSidToStringSidA');
if assigned(dr) then
begin
result := dr(SID, strSID);
end;
end;
end;
 
// http://www.delphipraxis.net/post471470.html
// Changed
function _getMySID(): string;
var
SID: PSID;
strSID: PAnsiChar;
s: String;
err: DWORD;
begin
SID := nil;
 
err := _getAccountSid('', _getLoginNameW(), SID);
 
if err = 0 then
begin
if _Dyn_ConvertSidToStringSidA(SID, strSID) then
s := string(strSID)
else
s := SysErrorMessage(err);
end
else
s := SysErrorMessage(err);
 
result := s;
end;
 
// Originalcode aus http://www.delphipraxis.net/post2933.html
function _DriveExists(DriveByte: Byte): Boolean; overload;
begin
Result := GetLogicalDrives and (1 shl DriveByte) <> 0;
end;
 
function _driveExists(Drive: Char): Boolean; overload;
var
DriveByte: Byte;
tmp: string;
begin
// Make drive letter upper case (for older Delphi versions)
tmp := UpperCase(Drive);
Drive := tmp[1];
 
DriveByte := Ord(Drive) - Ord('A');
Result := _DriveExists(DriveByte);
end;
 
function _isFAT(drive: char): boolean;
var
Dummy2: DWORD;
Dummy3: DWORD;
FileSystem: array[0..MAX_PATH] of char;
VolumeName: array[0..MAX_PATH] of char;
s: string;
begin
result := false;
if _driveExists(drive) then
begin
s := drive + DriveDelim + PathDelim; // ohne die Auslagerung in einen String kommt es zu einer AV in ntdll
GetVolumeInformation(PChar(s), VolumeName,
SizeOf(VolumeName), nil, Dummy2, Dummy3, FileSystem, SizeOf(FileSystem));
result := uppercase(copy(FileSystem, 0, 3)) = 'FAT';
end;
end;
 
// http://www.delphipages.com/tips/thread.cfm?ID=294
// Changed
(* function IsWin95: boolean;
var
OS: TOSVersionInfo;
begin
ZeroMemory(@OS, SizeOf(OS));
OS.dwOSVersionInfoSize := SizeOf(OS);
GetVersionEx(OS);
// http://www.gaijin.at/lstwinver.php
Result := (OS.dwMajorVersion = 4) and (OS.dwMinorVersion <= 3) and
(OS.dwPlatformId=VER_PLATFORM_WIN32_WINDOWS);
end; *)
 
// http://www.delphipages.com/tips/thread.cfm?ID=294
// Changed
function _isVista: boolean;
var
OS: TOSVersionInfo;
begin
ZeroMemory(@OS, SizeOf(OS));
OS.dwOSVersionInfoSize := SizeOf(OS);
GetVersionEx(OS);
// http://www.gaijin.at/lstwinver.php
Result := (OS.dwMajorVersion = 6) and (OS.dwMinorVersion = 0) and
(OS.dwPlatformId=VER_PLATFORM_WIN32_NT);
end;
 
// **********************************************************
// VISTA FUNCTIONS, INTERNAL USED
// **********************************************************
 
function _isFileVistaRealfile(filename: string): boolean;
begin
result := uppercase(copy(extractfilename(filename), 0, 2)) = '$R';
end;
 
function _isFileVistaIndexfile(filename: string): boolean;
begin
result := uppercase(copy(extractfilename(filename), 0, 2)) = '$I';
end;
 
function _isFileVistaNamed(filename: string): boolean;
begin
result := _isFileVistaIndexfile(filename) or
_isFileVistaRealfile(filename);
end;
 
function _VistaChangeRealfileToIndexfile(realfile: string): string;
begin
if _isFileVistaRealfile(realfile) then
begin
result := extractfilepath(realfile)+'$I'+
copy(extractfilename(realfile), 3, length(extractfilename(realfile))-2);
end
else
result := realfile; // ignore, even if it is not a vista recycle-file
end;
 
function _VistaChangeIndexfileToRealfile(indexfile: string): string;
begin
if _isFileVistaIndexfile(indexfile) then
begin
result := extractfilepath(indexfile)+'$R'+
copy(extractfilename(indexfile), 3, length(extractfilename(indexfile))-2);
end
else
result := indexfile; // ignore, even if it is not a vista recycle-file
end;
 
procedure _VistaListIndexes(recyclerpath: string; result: TStringList);
var
sr: TSearchRec;
r: Integer;
tmp: string;
begin
tmp := recyclerpath;
tmp := IncludeTrailingBackslash(tmp);
 
if not directoryexists(tmp) then exit;
 
r := FindFirst(tmp+PathDelim + '$I*', faAnyFile, sr);
while r = 0 do
begin
if (sr.Name <> '.') and (sr.Name <> '..') then
begin
if sr.Size = $220 then
begin
result.Add(copy(sr.name, 3, length(sr.name)-2));
end;
end;
r := FindNext(sr);
end;
 
FindClose(sr);
end;
 
function _VistaCurrentFilename(infofilename: string): string;
begin
result := extractfilename(infofilename);
 
if _isFileVistaRealfile(result) then
begin
exit;
end;
 
if _isFileVistaIndexfile(result) then
begin
result := _VistaChangeIndexfileToRealfile(result);
exit;
end;
 
result := copy(result, 3, length(result)-2);
result := '$R'+result;
end;
 
function _VistaGetSourceDrive(infofile: string): char;
var
fs: TFileStream;
tmp: string;
const
drive_vista_position = $18;
begin
result := #0;
 
tmp := infofile;
tmp := _VistaChangeRealfileToIndexfile(tmp);
if not fileexists(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(drive_vista_position, soFromBeginning);
result := _readChar(fs);
finally
fs.free;
end;
end;
 
{$IFDEF DEL6UP}
function _VistaGetDateTime(infofile: string): TDateTime;
var
fs: TFileStream;
tmp: string;
const
timestamp_vista_position = $10;
begin
result := EncodeDateTime(1601, 1, 1, 0, 0, 0, 0);
 
tmp := infofile;
tmp := _VistaChangeRealfileToIndexfile(tmp);
if not fileexists(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(timestamp_vista_position, soFromBeginning);
result := _fileTimeToDateTime(_readInt64(fs));
finally
fs.free;
end;
end;
{$ENDIF}
 
function _VistaGetSourceUnicode(infofile: string): string;
var
fs: TFileStream;
tmp: string;
const
unicode_vista_position = $18;
begin
result := '';
 
tmp := infofile;
tmp := _VistaChangeRealfileToIndexfile(tmp);
if not fileexists(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(unicode_vista_position, soFromBeginning);
result := _readNullTerminatedWideString(fs);
finally
fs.free;
end;
end;
 
function _VistaOriginalSize(infofile: string): integer;
var
fs: TFileStream;
tmp: string;
const
size_vista_position = $8;
begin
result := -1;
 
tmp := infofile;
tmp := _VistaChangeRealfileToIndexfile(tmp);
if not fileexists(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(size_vista_position, soFromBeginning);
result := _readInt32(fs);
finally
fs.free;
end;
end;
 
function _checkInfo1or2File(filename: string): boolean;
var
fs: TStream;
record_length: integer;
const
length_position = $C;
empty_size = 20;
begin
fs := TFileStream.Create(filename, fmOpenRead);
try
fs.seek(length_position, soFromBeginning);
record_length := _readInt32(fs);
 
// Check the file length
if record_length = 0 then
result := false
else
result := (fs.size - empty_size) mod record_length = 0;
finally
fs.free;
end;
end;
 
function _VistaIsValid(infofile: string): boolean;
var
fs: TFileStream;
tmp: string;
const
vista_valid_size = $220;
begin
result := false;
 
tmp := infofile;
tmp := _VistaChangeRealfileToIndexfile(tmp);
if not fileexists(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
// Check the file length
result := fs.size = vista_valid_size;
finally
fs.free;
end;
end;
 
// **********************************************************
// PUBLIC FUNCTIONS
// **********************************************************
 
{$IFDEF DEL6UP}
 
function RecyclerGetDateTime(InfofileOrRecycleFolder: string): tdatetime; overload;
begin
result := RecyclerGetDateTime(InfofileOrRecycleFolder, '');
end;
 
function RecyclerGetDateTime(drive: char; fileid: string): tdatetime; overload;
begin
result := RecyclerGetDateTime(drive, '', fileid);
end;
 
function RecyclerGetDateTime(drive: char; UserSID: string; fileid: string): tdatetime; overload;
var
infofile: string;
begin
infofile := RecyclerGetPath(drive, UserSID, true, fileid);
result := RecyclerGetDateTime(infofile, fileid);
end;
 
function RecyclerGetDateTime(InfofileOrRecycleFolder: string; id: string): tdatetime; overload;
var
fs: TFileStream;
i, record_length: integer;
tmp: string;
const
length_position = $C;
unique_index_position = $118;
timestamp_position = $120;
begin
// FILETIME does start at 01.01.1601 00:00:00 (GMT)
result := EncodeDateTime(1601, 1, 1, 0, 0, 0, 0);
 
tmp := InfofileOrRecycleFolder;
 
if _isFileVistaNamed(tmp) then
begin
result := _VistaGetDateTime(tmp);
exit;
end;
 
{$IFDEF allow_all_filenames}
if not RecyclerIsValid(tmp) and fileexists(tmp) then
begin
if fileexists(extractfilepath(tmp)+'INFO2') then
tmp := extractfilepath(tmp)+'INFO2'
else if fileexists(extractfilepath(tmp)+'INFO') then
tmp := extractfilepath(tmp)+'INFO';
end;
{$ENDIF}
 
if directoryexists(tmp) then
begin
tmp := IncludeTrailingBackslash(tmp);
 
if fileexists(tmp+'$I'+id) then
begin
result := _VistaGetDateTime(tmp+'$I'+id);
exit;
end
else if fileexists(tmp+'INFO2') then tmp := tmp+'INFO2'
else if fileexists(tmp+'INFO') then tmp := tmp+'INFO';
end;
 
if not fileexists(tmp) then exit;
if not RecyclerIsValid(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(length_position, soFromBeginning);
record_length := _readInt32(fs);
 
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);
if inttostr(_readInt32(fs)) = id then
begin
fs.seek(timestamp_position+i*record_length, soFromBeginning);
result := _fileTimeToDateTime(_readInt64(fs));
break;
end;
until false;
finally
fs.free;
end;
end;
 
{$ENDIF}
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerGetSourceUnicode(InfofileOrRecycleFolder: string): WideString; overload;
begin
result := RecyclerGetSourceUnicode(InfofileOrRecycleFolder, '');
end;
 
function RecyclerGetSourceUnicode(drive: char; fileid: string): WideString; overload;
begin
result := RecyclerGetSourceUnicode(drive, '', fileid);
end;
 
function RecyclerGetSourceUnicode(drive: char; UserSID: string; fileid: string): WideString; overload;
var
infofile: string;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
infofile := RecyclerGetPath(drive, UserSID, true, fileid);
result := RecyclerGetSourceUnicode(infofile, fileid);
end
else
begin
// Windows 9x does not support unicode
result := RecyclerGetSource(drive, UserSID, fileid);
end;
end;
 
function RecyclerGetSourceUnicode(InfofileOrRecycleFolder: string; id: string): WideString; overload;
var
fs: TFileStream;
i, record_length: integer;
tmp: string;
const
length_position = $C;
unique_index_position = $118;
unicode_source_position = $12C;
begin
result := '';
 
tmp := InfofileOrRecycleFolder;
 
if _isFileVistaNamed(tmp) then
begin
// Vista only gives unicode names
result := _VistaGetSourceUnicode(tmp);
exit;
end;
 
{$IFDEF allow_all_filenames}
if not RecyclerIsValid(tmp) and fileexists(tmp) then
begin
if fileexists(extractfilepath(tmp)+'INFO2') then
tmp := extractfilepath(tmp)+'INFO2'
else if fileexists(extractfilepath(tmp)+'INFO') then
tmp := extractfilepath(tmp)+'INFO';
end;
{$ENDIF}
 
if directoryexists(tmp) then
begin
tmp := IncludeTrailingBackslash(tmp);
 
if fileexists(tmp+'$I'+id) then
begin
// Vista only gives unicode names
result := _VistaGetSourceUnicode(tmp+'$I'+id);
exit;
end
else if fileexists(tmp+'INFO2') then tmp := tmp+'INFO2'
else if fileexists(tmp+'INFO') then tmp := tmp+'INFO';
end;
 
if not fileexists(tmp) then exit;
if not RecyclerIsValid(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(length_position, soFromBeginning);
record_length := _readInt32(fs);
 
if record_length <> $118 then
begin
// Windows NT
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);
if inttostr(_readInt32(fs)) = id then
begin
fs.seek(unicode_source_position+i*record_length, soFromBeginning);
result := _readNullTerminatedWideString(fs);
break;
end;
until false;
end;
finally
fs.free;
end;
 
if record_length = $118 then
begin
// Windows 9x has no unicode support
result := RecyclerGetSource(tmp, id);
end;
end;
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerGetSource(InfofileOrRecycleFolder: string): string; overload;
begin
result := RecyclerGetSource(InfofileOrRecycleFolder, '');
end;
 
function RecyclerGetSource(drive: char; fileid: string): string; overload;
begin
result := RecyclerGetSource(drive, '', fileid);
end;
 
function RecyclerGetSource(drive: char; UserSID: string; fileid: string): string; overload;
var
infofile: string;
begin
infofile := RecyclerGetPath(drive, UserSID, true, fileid);
result := RecyclerGetSource(infofile, fileid);
end;
 
function RecyclerGetSource(InfofileOrRecycleFolder: string; id: string): string; overload;
var
fs: TFileStream;
i, record_length: integer;
tmp: string;
alternativ: string;
const
length_position = $C;
unique_index_position = $118;
source_position = $14;
begin
result := '';
 
tmp := InfofileOrRecycleFolder;
 
if _isFileVistaNamed(tmp) then
begin
// Vista only gives unicode names
result := _VistaGetSourceUnicode(tmp);
exit;
end;
 
{$IFDEF allow_all_filenames}
if not RecyclerIsValid(tmp) and fileexists(tmp) then
begin
if fileexists(extractfilepath(tmp)+'INFO2') then
tmp := extractfilepath(tmp)+'INFO2'
else if fileexists(extractfilepath(tmp)+'INFO') then
tmp := extractfilepath(tmp)+'INFO';
end;
{$ENDIF}
 
if directoryexists(tmp) then
begin
tmp := IncludeTrailingBackslash(tmp);
 
if fileexists(tmp+'$I'+id) then
begin
// Vista only gives unicode names
result := _VistaGetSourceUnicode(tmp+'$I'+id);
exit;
end
else if fileexists(tmp+'INFO2') then tmp := tmp+'INFO2'
else if fileexists(tmp+'INFO') then tmp := tmp+'INFO';
end;
 
if not fileexists(tmp) then exit;
if not RecyclerIsValid(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(length_position, soFromBeginning);
record_length := _readInt32(fs);
 
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);
if inttostr(_readInt32(fs)) = id then
begin
fs.seek(source_position+i*record_length, soFromBeginning);
alternativ := _readChar(fs);
 
if alternativ = #0 then
begin
fs.seek(source_position+i*record_length+1, soFromBeginning);
result := _readNullTerminatedString(fs);
end
else
begin
fs.seek(source_position+i*record_length, soFromBeginning);
result := _readNullTerminatedString(fs);
end;
 
break;
end;
until false;
finally
fs.free;
end;
 
// In some cases the ansi-source-name is [Null]:\...\
if alternativ = #0 then
begin
result := RecyclerGetSourceDrive(InfofileOrRecycleFolder, id) + result;
end;
end;
 
////////////////////////////////////////////////////////////////////////////////
 
procedure RecyclerListIndexes(drive: char; result: TStringList); overload;
begin
RecyclerListIndexes(drive, '', result);
end;
 
procedure RecyclerListIndexes(drive: char; UserSID: string; result: TStringList); overload;
var
infofile: string;
begin
infofile := RecyclerGetPath(drive, UserSID, false);
RecyclerListIndexes(infofile, result);
end;
 
procedure RecyclerListIndexes(InfofileOrRecycleFolder: string; result: TStringList); overload;
var
fs: TFileStream;
i, record_length: integer;
tmp: string;
const
length_position = $C;
unique_index_position = $118;
begin
tmp := InfofileOrRecycleFolder;
 
if _isFileVistaNamed(tmp) then
begin
_VistaListIndexes(extractfilepath(tmp), result);
exit;
end;
 
{$IFDEF allow_all_filenames}
if not RecyclerIsValid(tmp) and fileexists(tmp) then
begin
if fileexists(extractfilepath(tmp)+'INFO2') then
tmp := extractfilepath(tmp)+'INFO2'
else if fileexists(extractfilepath(tmp)+'INFO') then
tmp := extractfilepath(tmp)+'INFO';
end;
{$ENDIF}
 
if directoryexists(tmp) then
begin
tmp := IncludeTrailingBackslash(tmp);
 
if fileexists(tmp+'INFO2') then tmp := tmp+'INFO2'
else if fileexists(tmp+'INFO') then tmp := tmp+'INFO'
else
begin
// Last try: is it a vista-directory?
_VistaListIndexes(tmp, result);
exit;
end;
end;
 
if not fileexists(tmp) then exit;
if not RecyclerIsValid(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(length_position, soFromBeginning);
record_length := _readInt32(fs);
 
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);
 
result.Add(inttostr(_readInt32(fs)));
until false;
finally
fs.free;
end;
end;
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerGetSourceDrive(InfofileOrRecycleFolder: string): char; overload;
begin
result := RecyclerGetSourceDrive(InfofileOrRecycleFolder, '');
end;
 
function RecyclerGetSourceDrive(drive: char; fileid: string): char; overload;
begin
result := RecyclerGetSourceDrive(drive, '', fileid);
end;
 
function RecyclerGetSourceDrive(drive: char; UserSID: string; fileid: string): char; overload;
var
infofile: string;
begin
infofile := RecyclerGetPath(drive, UserSID, true, fileid);
result := RecyclerGetSourceDrive(infofile, fileid);
end;
 
function RecyclerGetSourceDrive(InfofileOrRecycleFolder: string; id: string): char; overload;
var
fs: TFileStream;
i, record_length: integer;
tmp: string;
const
length_position = $C;
unique_index_position = $118;
source_drive_position = $11C;
begin
result := #0;
 
tmp := InfofileOrRecycleFolder;
 
if _isFileVistaNamed(tmp) then
begin
result := _VistaGetSourceDrive(tmp);
exit;
end;
 
{$IFDEF allow_all_filenames}
if not RecyclerIsValid(tmp) and fileexists(tmp) then
begin
if fileexists(extractfilepath(tmp)+'INFO2') then
tmp := extractfilepath(tmp)+'INFO2'
else if fileexists(extractfilepath(tmp)+'INFO') then
tmp := extractfilepath(tmp)+'INFO';
end;
{$ENDIF}
 
if directoryexists(tmp) then
begin
tmp := IncludeTrailingBackslash(tmp);
 
if fileexists(tmp+'$I'+id) then
begin
result := _VistaGetSourceDrive(tmp+'$I'+id);
exit;
end
else if fileexists(tmp+'INFO2') then tmp := tmp+'INFO2'
else if fileexists(tmp+'INFO') then tmp := tmp+'INFO';
end;
 
if not fileexists(tmp) then exit;
if not RecyclerIsValid(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(length_position, soFromBeginning);
record_length := _readInt32(fs);
 
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);
if inttostr(_readInt32(fs)) = id then
begin
fs.seek(source_drive_position+i*record_length, soFromBeginning);
result := chr(ord('A') + _readInt8(fs));
break;
end;
until false;
finally
fs.free;
end;
end;
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerOriginalSize(InfofileOrRecycleFolder: string): integer; overload;
begin
result := RecyclerOriginalSize(InfofileOrRecycleFolder, '');
end;
 
function RecyclerOriginalSize(drive: char; fileid: string): integer; overload;
begin
result := RecyclerOriginalSize(drive, '', fileid);
end;
 
function RecyclerOriginalSize(drive: char; UserSID: string; fileid: string): integer; overload;
var
infofile: string;
begin
infofile := RecyclerGetPath(drive, UserSID, true, fileid);
result := RecyclerOriginalSize(infofile, fileid);
end;
 
function RecyclerOriginalSize(InfofileOrRecycleFolder: string; id: string): integer; overload;
var
fs: TFileStream;
i, record_length: integer;
tmp: string;
const
length_position = $C;
unique_index_position = $118;
original_size_position = $128;
begin
result := -1;
 
tmp := InfofileOrRecycleFolder;
 
if _isFileVistaNamed(tmp) then
begin
result := _VistaOriginalSize(tmp);
exit;
end;
 
{$IFDEF allow_all_filenames}
if not RecyclerIsValid(tmp) and fileexists(tmp) then
begin
if fileexists(extractfilepath(tmp)+'INFO2') then
tmp := extractfilepath(tmp)+'INFO2'
else if fileexists(extractfilepath(tmp)+'INFO') then
tmp := extractfilepath(tmp)+'INFO';
end;
{$ENDIF}
 
if directoryexists(tmp) then
begin
tmp := IncludeTrailingBackslash(tmp);
 
if fileexists(tmp+'$I'+id) then
begin
result := _VistaOriginalSize(tmp+'$I'+id);
exit;
end
else if fileexists(tmp+'INFO2') then tmp := tmp+'INFO2'
else if fileexists(tmp+'INFO') then tmp := tmp+'INFO';
end;
 
if not fileexists(tmp) then exit;
if not RecyclerIsValid(tmp) then exit;
 
fs := TFileStream.Create(tmp, fmOpenRead);
try
fs.seek(length_position, soFromBeginning);
record_length := _readInt32(fs);
 
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);
if inttostr(_readInt32(fs)) = id then
begin
fs.seek(original_size_position+i*record_length, soFromBeginning);
result := _readInt32(fs);
break;
end;
until false;
finally
fs.free;
end;
end;
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerIsValid(drive: char): boolean; overload;
begin
result := RecyclerIsValid(drive, '');
end;
 
function RecyclerIsValid(drive: char; UserSID: string): boolean; overload;
var
infofile: string;
begin
infofile := RecyclerGetPath(drive, UserSID, false);
result := RecyclerIsValid(infofile);
end;
 
function RecyclerIsValid(InfofileOrRecycleFolder: string): boolean; overload;
var
tmp: string;
x: TStringList;
i: integer;
eine_fehlerhaft: boolean;
begin
result := false;
 
tmp := InfofileOrRecycleFolder;
 
if _isFileVistaNamed(tmp) then
begin
result := _VistaIsValid(tmp);
exit;
end;
 
{$IFDEF allow_all_filenames}
if not RecyclerIsValid(tmp) and fileexists(tmp) then
begin
if fileexists(extractfilepath(tmp)+'INFO2') then
tmp := extractfilepath(tmp)+'INFO2'
else if fileexists(extractfilepath(tmp)+'INFO') then
tmp := extractfilepath(tmp)+'INFO';
end;
{$ENDIF}
 
if directoryexists(tmp) then
begin
tmp := IncludeTrailingBackslash(tmp);
 
if fileexists(tmp+'INFO2') then
begin
result := _checkInfo1or2File(tmp+'INFO2');
end;
 
if not result and fileexists(tmp+'INFO') then
begin
result := _checkInfo1or2File(tmp+'INFO');
end;
 
if not result then
begin
// Complete vista-directory declared?
eine_fehlerhaft := false;
x := TStringList.Create;
try
_VistaListIndexes(tmp, x);
for i := 0 to x.Count - 1 do
begin
if not _VistaIsValid(tmp+'$I'+x.Strings[i]) then
begin
eine_fehlerhaft := true;
end;
end;
finally
x.Free;
end;
result := not eine_fehlerhaft;
end;
end;
 
if not fileexists(tmp) then exit;
 
result := _checkInfo1or2File(tmp);
end;
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerCurrentFilename(InfofileOrRecycleFolder: string): string; overload;
begin
result := RecyclerCurrentFilename(InfofileOrRecycleFolder, '');
end;
 
function RecyclerCurrentFilename(drive: char; fileid: string): string; overload;
begin
result := RecyclerCurrentFilename(drive, '', fileid);
end;
 
function RecyclerCurrentFilename(drive: char; UserSID: string; fileid: string): string; overload;
var
infofile: string;
begin
infofile := RecyclerGetPath(drive, UserSID, true, fileid);
result := RecyclerCurrentFilename(infofile, fileid);
end;
 
function RecyclerCurrentFilename(InfofileOrRecycleFolder: string; id: string): string; overload;
var
a, c: string;
tmp: string;
begin
result := '';
 
tmp := InfofileOrRecycleFolder;
 
if _isFileVistaNamed(tmp) then
begin
result := _VistaCurrentFilename(tmp);
exit;
end;
 
{$IFDEF allow_all_filenames}
if not RecyclerIsValid(tmp) and fileexists(tmp) then
begin
if fileexists(extractfilepath(tmp)+'INFO2') then
tmp := extractfilepath(tmp)+'INFO2'
else if fileexists(extractfilepath(tmp)+'INFO') then
tmp := extractfilepath(tmp)+'INFO';
end;
{$ENDIF}
 
if directoryexists(tmp) then
begin
tmp := IncludeTrailingBackslash(tmp);
 
if fileexists(tmp+'$I'+id) then
begin
result := _VistaCurrentFilename(tmp+'$I'+id);
exit;
end
else if fileexists(tmp+'INFO2') then tmp := tmp+'INFO2'
else if fileexists(tmp+'INFO') then tmp := tmp+'INFO';
end;
 
a := RecyclerGetSourceDrive(tmp, id);
c := extractfileext(RecyclerGetSourceUnicode(tmp, id));
if (a <> '') then
begin
result := 'D' + a + id + c;
end;
end;
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerGetPath(drive: char; UserSID: string; IncludeInfofile: boolean; fileid: string): string; overload;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
RecyclerGetInfofiles(drive, UserSID, IncludeInfofile, fileid, sl);
if sl.Count > 0 then
result := ExtractFilePath(sl.Strings[0])
else
result := '';
finally
sl.free;
end;
end;
 
function RecyclerGetPath(drive: char; UserSID: string; IncludeInfofile: boolean): string; overload;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
RecyclerGetInfofiles(drive, UserSID, IncludeInfofile, sl);
if sl.Count > 0 then
result := ExtractFilePath(sl.Strings[0])
else
result := '';
finally
sl.free;
end;
end;
 
function RecyclerGetPath(drive: char; IncludeInfofile: boolean): string; overload;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
RecyclerGetInfofiles(drive, IncludeInfofile, sl);
if sl.Count > 0 then
result := ExtractFilePath(sl.Strings[0])
else
result := '';
finally
sl.free;
end;
end;
 
function RecyclerGetPath(drive: char; UserSID: string): string; overload;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
RecyclerGetInfofiles(drive, UserSID, sl);
if sl.Count > 0 then
result := ExtractFilePath(sl.Strings[0])
else
result := '';
finally
sl.free;
end;
end;
 
function RecyclerGetPath(drive: char): string; overload;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
RecyclerGetInfofiles(drive, sl);
if sl.Count > 0 then
result := ExtractFilePath(sl.Strings[0])
else
result := '';
finally
sl.free;
end;
end;
 
////////////////////////////////////////////////////////////////////////////////
 
procedure RecyclerGetInfofiles(drive: char; UserSID: string; IncludeInfofile: boolean; fileid: string; result: TStringList); overload;
var
dir: string;
begin
(* if Win32Platform = VER_PLATFORM_WIN32_NT then
begin *)
if _isVista() then
begin
if _isFAT(drive) then
begin
dir := drive + DriveDelim + PathDelim + '$recycle.bin' + PathDelim;
if IncludeInfofile and (fileid <> '') then
begin
if fileExists(dir + '$I'+fileid) then
result.Add(dir + '$I'+fileid);
end
else
begin
if directoryExists(dir) then
result.Add(dir);
end;
end
else
begin
if UserSID <> '' then
begin
dir := drive + DriveDelim + PathDelim + '$recycle.bin'+PathDelim+UserSID+PathDelim;
if IncludeInfofile and (fileid <> '') then
begin
if fileExists(dir + '$I'+fileid) then
result.Add(dir + '$I'+fileid);
end
else
begin
if directoryExists(dir) then
result.Add(dir);
end;
end
else
begin
dir := drive + DriveDelim + PathDelim + '$recycle.bin'+PathDelim+_getMySID()+PathDelim;
if IncludeInfofile and (fileid <> '') then
begin
if fileExists(dir + '$I'+fileid) then
result.Add(dir + '$I'+fileid);
end
else
begin
if directoryExists(dir) then
result.Add(dir);
end;
end;
end;
end
else
begin
if _isFAT(drive) then
begin
dir := drive + DriveDelim + PathDelim + 'Recycled' + PathDelim;
if IncludeInfofile then
begin
// Both "recycle bins" are possible if you have multiboot (but do overwrite themselfes if you empty them)
if fileExists(dir + 'INFO2') then
result.Add(dir + 'INFO2'); // Windows 95 with Internet Explorer 4 Extension or higher Windows versions
if fileExists(dir + 'INFO') then
result.Add(dir + 'INFO'); // Windows 95 native
end
else
begin
if directoryExists(dir) then
result.Add(dir);
end;
end
else
begin
if UserSID <> '' then
begin
dir := drive + DriveDelim + PathDelim + 'Recycler'+PathDelim+UserSID+PathDelim;
if IncludeInfofile then
begin
if fileExists(dir + 'INFO2') then
result.Add(dir + 'INFO2');
end
else
begin
if directoryExists(dir) then
result.Add(dir);
end;
end
else
begin
dir := drive + DriveDelim + PathDelim + 'Recycler'+PathDelim+_getMySID()+PathDelim;
if IncludeInfofile then
begin
if fileExists(dir + 'INFO2') then
result.Add(dir + 'INFO2');
end
else
begin
if directoryExists(dir) then
result.Add(dir);
end;
end;
end;
end;
(* end;
else
begin
if isWin95() then
begin
result := drive + DriveDelim + PathDelim + 'Recycled' + PathDelim;
if IncludeInfofile then result := result + 'INFO';
end
else
begin
result := drive + DriveDelim + PathDelim + 'Recycled' + PathDelim;
if IncludeInfofile then result := result + 'INFO2';
end;
end; *)
end;
 
procedure RecyclerGetInfofiles(drive: char; UserSID: string; IncludeInfofile: boolean; result: TStringList); overload;
begin
RecyclerGetInfofiles(drive, UserSID, IncludeInfofile, '', result);
end;
 
procedure RecyclerGetInfofiles(drive: char; IncludeInfofile: boolean; result: TStringList); overload;
begin
RecyclerGetInfofiles(drive, '', IncludeInfofile, '', result);
end;
 
procedure RecyclerGetInfofiles(drive: char; UserSID: string; result: TStringList); overload;
begin
RecyclerGetInfofiles(drive, UserSID, false, '', result);
end;
 
procedure RecyclerGetInfofiles(drive: char; result: TStringList); overload;
begin
RecyclerGetInfofiles(drive, '', false, '', result);
end;
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerCurrentFilenameAndPath(drive: char; UserSID: string; fileid: string): string; overload;
begin
result := RecyclerGetPath(drive, UserSID, false, fileid) +
RecyclerCurrentFilename(drive, UserSID, fileid);
end;
 
function RecyclerCurrentFilenameAndPath(drive: char; fileid: string): string; overload;
begin
result := RecyclerCurrentFilenameAndPath(drive, '', fileid);
end;
 
function RecyclerCurrentFilenameAndPath(InfofileOrRecycleFolder: string; id: string): string; overload;
begin
if RecyclerIsValid(InfofileOrRecycleFolder) then
begin
result := extractfilepath(InfofileOrRecycleFolder) +
RecyclerCurrentFilename(InfofileOrRecycleFolder, id);
end
else
result := '';
end;
 
////////////////////////////////////////////////////////////////////////////////
 
function RecyclerRemoveItem(drive: char; UserSID: string; fileid: string): boolean; overload;
var
tmp: string;
begin
tmp := RecyclerCurrentFilenameAndPath(drive, UserSID, fileid);
if fileexists(tmp) then
begin
deletefile(tmp);
result := fileexists(tmp);
end
else
begin
directoryexists(tmp);
result := directoryexists(tmp);
end;
end;
 
function RecyclerRemoveItem(drive: char; fileid: string): boolean; overload;
begin
result := RecyclerRemoveItem(drive, '', fileid);
end;
 
function RecyclerRemoveItem(InfofileOrRecycleFolder: string; id: string): boolean; overload;
var
tmp: string;
begin
tmp := RecyclerCurrentFilenameAndPath(InfofileOrRecycleFolder, id);
if fileexists(tmp) then
begin
deletefile(tmp);
result := fileexists(tmp);
end
else
begin
directoryexists(tmp);
result := directoryexists(tmp);
end;
end;
 
procedure RecyclerGetAllRecyclerDrives(result: TStringList);
var
x: char;
begin
for x := 'C' to 'Z' do
begin
if RecyclerIsValid(x) then
begin
result.Add(x);
end;
end;
end;
 
////////////////////////////////////////////////////////////////////////////////
 
// http://www.dsdt.info/tipps/?id=176
function RecyclerEmptyRecycleBin(flags: cardinal): boolean; overload;
type
TSHEmptyRecycleBin = function (Wnd: HWND;
pszRootPath: PChar;
dwFlags: DWORD):
HRESULT; stdcall;
var
SHEmptyRecycleBin: TSHEmptyRecycleBin;
LibHandle: THandle;
begin
result := true;
LibHandle := LoadLibrary(shell32) ;
try
if LibHandle <> 0 then
begin
@SHEmptyRecycleBin:= GetProcAddress(LibHandle, 'SHEmptyRecycleBinA');
if @SHEmptyRecycleBin <> nil then
begin
SHEmptyRecycleBin(hInstance, nil, flags);
end
else
result := false;
end
else
result := false;
finally
@SHEmptyRecycleBin := nil;
FreeLibrary(LibHandle);
end;
end;
 
function RecyclerEmptyRecycleBin(sound, progress, confirmation: boolean): boolean; overload;
const
SHERB_NOCONFIRMATION = $00000001;
SHERB_NOPROGRESSUI = $00000002;
SHERB_NOSOUND = $00000004;
var
flags: cardinal;
begin
flags := 0;
 
if not progress then
flags := flags or SHERB_NOPROGRESSUI;
if not confirmation then
flags := flags or SHERB_NOCONFIRMATION;
if not sound then
flags := flags or SHERB_NOSOUND;
 
result := RecyclerEmptyRecycleBin(flags);
end;
 
////////////////////////////////////////////////////////////////////////////////
 
// Template
// http://www.dsdt.info/tipps/?id=116
function RecyclerAddFileOrFolder(FileOrFolder: string; confirmation: boolean): boolean; overload;
var
Operation: TSHFileOpStruct;
begin
with Operation do
begin
Wnd := hInstance; // OK?
wFunc := FO_DELETE;
pFrom := PChar(FileOrFolder + #0);
pTo := nil;
fFlags := FOF_ALLOWUNDO;
if not confirmation then fFlags := fFlags or FOF_NOCONFIRMATION;
end;
Result := SHFileOperation(Operation) = 0;
end;
 
function RecyclerAddFileOrFolder(FileOrFolder: string): boolean; overload;
begin
result := RecyclerAddFileOrFolder(FileOrFolder, false);
end;
 
function RecyclerConfirmationDialogEnabled: boolean;
var
lpss: SHELLSTATE;
bNoConfirmRecycle: boolean;
begin
ZeroMemory(@lpss, SizeOf(lpss));
SHGetSetSettings(lpss, SSF_NOCONFIRMRECYCLE, False);
bNoConfirmRecycle := (lpss.Flags1 and 4) = 4; // fNoConfirmRecycle
 
result := not bNoConfirmRecycle;
end;
 
function RecyclerGetCurrentIconString: string;
begin
if RecyclerIsEmpty then
result := RecyclerGetEmptyIconString
else
result := RecyclerGetFullIconString;
end;
 
function RecyclerGetDefaultIconString: string;
var
reg: TRegistry;
begin
// Please note: The "default" icon is not always the icon of the
// current recycle bin in its current state (full, empty)
// At Windows 95b, the registry value actually did change every time the
// recycle bin state did change, but at Windows 2000 I could not see any
// update, even after reboot. So, the registry value is possible fixed as
// default = empty on newer OS versions.
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CLASSES_ROOT;
if reg.OpenKeyReadOnly('CLSID\'+RECYCLER_CLSID+'\DefaultIcon') then
begin
result := reg.ReadString('');
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerGetEmptyIconString: string;
var
reg: TRegistry;
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CLASSES_ROOT;
if reg.OpenKeyReadOnly('CLSID\'+RECYCLER_CLSID+'\DefaultIcon') then
begin
result := reg.ReadString('Empty');
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerGetFullIconString: string;
var
reg: TRegistry;
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CLASSES_ROOT;
if reg.OpenKeyReadOnly('CLSID\'+RECYCLER_CLSID+'\DefaultIcon') then
begin
result := reg.ReadString('Full');
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerGetName: string;
var
reg: TRegistry;
begin
// Windows 95b:
// Change of CLSID\{645FF040-5081-101B-9F08-00AA002F954E} will change the desktop name of the recycle bin.
 
// Windows 2000: If LocalizedString is available, the 3rd argument will be parsed
// (if the third argument will removed, it will be read out from the DLL resource string automatically)
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CLASSES_ROOT;
if reg.OpenKeyReadOnly('CLSID\'+RECYCLER_CLSID) then
begin
if reg.ValueExists('LocalizedString') then
begin
result := reg.ReadString('LocalizedString');
result := _DecodeReferenceString(result);
end
else
begin
result := reg.ReadString('');
end;
 
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerGetInfoTip: string;
var
reg: TRegistry;
begin
// Not available in some older versions of Windows
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CLASSES_ROOT;
if reg.OpenKeyReadOnly('CLSID\'+RECYCLER_CLSID) then
begin
result := reg.ReadString('InfoTip');
result := _DecodeReferenceString(result);
 
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerGetIntroText: string;
var
reg: TRegistry;
begin
// Not available in some older versions of Windows
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CLASSES_ROOT;
if reg.OpenKeyReadOnly('CLSID\'+RECYCLER_CLSID) then
begin
result := reg.ReadString('IntroText');
result := _DecodeReferenceString(result);
 
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerEmptyEventGetName: string;
var
reg: TRegistry;
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CURRENT_USER;
if reg.OpenKeyReadOnly('AppEvents\EventLabels\EmptyRecycleBin') then
begin
result := reg.ReadString('');
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerEmptyEventGetCurrentSound: string;
begin
result := RecyclerEmptyEventGetSound('.Current');
end;
 
function RecyclerEmptyEventGetDefaultSound: string;
begin
result := RecyclerEmptyEventGetSound('.Default');
end;
 
procedure RecyclerEmptyEventGetSoundCategories(AStringList: TStringList);
var
reg: TRegistry;
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CURRENT_USER;
if reg.OpenKeyReadOnly('AppEvents\Schemes\Apps\Explorer\EmptyRecycleBin') then
begin
reg.GetKeyNames(AStringList);
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerEmptyEventGetSound(ACategory: string): string;
var
reg: TRegistry;
resourcestring
LNG_SND_EVENT_CAT_ERROR = 'The category "%s" is not available for the notification event "%s".';
begin
// Outputs an filename or empty string for no sound defined.
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CURRENT_USER;
if reg.OpenKeyReadOnly('AppEvents\Schemes\Apps\Explorer\EmptyRecycleBin') then
begin
if reg.OpenKeyReadOnly(ACategory) then
begin
result := reg.ReadString('');
reg.CloseKey;
end
else
raise EEventCategoryNotDefined.CreateFmt(LNG_SND_EVENT_CAT_ERROR, [ACategory, 'EmptyRecycleBin']);
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerGlobalGetPercentUsage: integer;
var
reg: TRegistry;
dump: string;
const
RES_DEFAULT = 10;
begin
result := -1;
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
 
if reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\BitBucket') then
begin
if reg.ValueExists('Percent') then
begin
// Windows 2000 - Informationen liegen aufgeschlüsselt in der Registry
 
result := reg.ReadInteger('Percent');
end
else if reg.ValueExists('PurgeInfo') then
begin
// Windows 95 - Verschlüsselte Informationen liegen in PurgeInfo
 
dump := _registryReadDump(reg, 'PurgeInfo');
result := Ord(dump[63]);
end
else
begin
// Windows 95 - Standardwerte sind gegeben, deswegen existiert kein PurgeInfo
 
result := RES_DEFAULT; // Standardeinstellung bei Windows
end;
 
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerSpecificGetPercentUsage(Drive: Char): integer;
var
reg: TRegistry;
dump: string;
const
RES_DEFAULT = 10;
begin
result := -1;
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
 
if reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\BitBucket') then
begin
if reg.OpenKeyReadOnly(Drive) then
begin
if reg.ValueExists('Percent') then
begin
// Windows 2000 - Informationen liegen aufgeschlüsselt in der Registry
 
result := reg.ReadInteger('Percent');
end
else
begin
result := RES_DEFAULT;
end;
reg.CloseKey;
end
else
begin
if reg.ValueExists('PurgeInfo') then
begin
// Windows 95 - Verschlüsselte Informationen liegen in PurgeInfo
 
dump := _registryReadDump(reg, 'PurgeInfo');
 
// NOT tested, only theoretical! My idea about the possible structure is:
// 0x08 = Drive A
// 0x0a = Drive B
// 0x0c = Drive C (validated)
// 0x0e = Drive D
// ...
 
result := Ord(dump[9+_DriveNum(Drive)*2]);
end
else
begin
// Windows 95 - Standardwerte sind gegeben, deswegen existiert kein PurgeInfo
 
result := RES_DEFAULT; // Standardeinstellung bei Windows
end;
end;
 
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerGetPercentUsageAutoDeterminate(Drive: Char): integer;
begin
if RecyclerHasGlobalSettings then
result := RecyclerGlobalGetPercentUsage
else
result := RecyclerSpecificGetPercentUsage(Drive);
end;
 
function RecyclerGlobalIsNukeOnDelete: boolean;
var
reg: TRegistry;
dump: string;
const
RES_DEFAULT = false;
begin
result := false;
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
 
if reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\BitBucket') then
begin
if reg.ValueExists('NukeOnDelete') then
begin
// Windows 2000 - Informationen liegen aufgeschlüsselt in der Registry
 
result := reg.ReadBool('NukeOnDelete');
end
else if reg.ValueExists('PurgeInfo') then
begin
// Windows 95 - Verschlüsselte Informationen liegen in PurgeInfo
 
// See comment at RecyclerSpecificIsNukeOnDelete()
 
dump := _registryReadDump(reg, 'PurgeInfo');
result := _GetBit(dump[68], 3);
end
else
begin
// Windows 95 - Standardwerte sind gegeben, deswegen existiert kein PurgeInfo
 
result := RES_DEFAULT; // Standardeinstellung bei Windows
end;
 
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerSpecificIsNukeOnDelete(Drive: Char): boolean;
var
reg: TRegistry;
dump: string;
d: Byte;
const
RES_DEFAULT = false;
begin
result := false;
 
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
 
if reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\BitBucket') then
begin
if reg.OpenKeyReadOnly(Drive) then
begin
if reg.ValueExists('NukeOnDelete') then
begin
// Windows 2000 - Informationen liegen aufgeschlüsselt in der Registry
 
result := reg.ReadBool('NukeOnDelete');
end;
reg.CloseKey;
end
else
begin
if reg.ValueExists('PurgeInfo') then
begin
// Windows 95 - Verschlüsselte Informationen liegen in PurgeInfo
 
dump := _registryReadDump(reg, 'PurgeInfo');
 
// NOT tested, only theoretical! My idea about the possible structure is:
//
// Byte 0x40 0x41 0x42 0x43
// Bit 76543210 76543210 76543210 76543210
// -------- -------- -------- --------
// Meaning hgfedcba ponmlkji xwvutsrq ????G?zy
//
// a..z = Drives
// G = global settings
//
// Already validated:
// 0x64 = 04 (00000100)
// 0x67 = 08 (00001000)
 
d := _DriveNum(Drive);
result := _GetBit(dump[65+(d div 7)], d mod 7);
end
else
begin
// Windows 95 - Standardwerte sind gegeben, deswegen existiert kein PurgeInfo
 
result := RES_DEFAULT; // Standardeinstellung bei Windows
end;
end;
 
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerIsNukeOnDeleteAutoDeterminate(Drive: Char): boolean;
begin
if RecyclerHasGlobalSettings then
result := RecyclerGlobalIsNukeOnDelete
else
result := RecyclerSpecificIsNukeOnDelete(Drive);
end;
 
function RecyclerHasGlobalSettings: boolean;
var
reg: TRegistry;
dump: string;
begin
result := false;
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
 
if reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\BitBucket') then
begin
if reg.ValueExists('UseGlobalSettings') then
begin
// Windows 2000 - Informationen liegen aufgeschlüsselt in der Registry
 
result := reg.ReadBool('UseGlobalSettings');
end
else if reg.ValueExists('PurgeInfo') then
begin
// Windows 95 - Verschlüsselte Informationen liegen in PurgeInfo
// TODO: Gibt es ein offizielles Dokument oder ein API, indem PurgeInfo
// offiziell entschlüsselbar ist?
 
dump := _registryReadDump(reg, 'PurgeInfo');
if dump[5] = #$01 then
result := true
else if dump[5] = #$00 then
result := false
else
raise EUnknownState.Create(Format(LNG_UNEXPECTED_STATE, ['PurgeInfo']));
end
else
begin
// Windows 95 - Standardwerte sind gegeben, deswegen existiert kein PurgeInfo
 
result := true; // Standardeinstellung bei Windows
end;
 
reg.CloseKey;
end;
finally
reg.Free;
end;
end;
 
function RecyclerIsEmpty: boolean;
var
Drive: Char;
begin
result := true;
for Drive := 'A' to 'Z' do
begin
if not RecyclerIsEmpty(Drive) then
begin
result := false;
exit;
end;
end;
end;
 
function RecyclerIsEmpty(Drive: Char): boolean;
begin
result := RecyclerGetAPIInfo(Drive).i64NumItems = 0;
end;
 
function RecyclerGetNumItems: int64;
var
Drive: Char;
begin
result := 0;
for Drive := 'A' to 'Z' do
begin
result := result + RecyclerGetNumItems(Drive);
end;
end;
 
function RecyclerGetNumItems(Drive: Char): int64;
begin
result := RecyclerGetAPIInfo(Drive).i64NumItems;
end;
 
function RecyclerGetSize: int64;
var
Drive: Char;
begin
result := 0;
for Drive := 'A' to 'Z' do
begin
result := result + RecyclerGetSize(Drive);
end;
end;
 
function RecyclerGetSize(Drive: Char): int64;
begin
result := RecyclerGetAPIInfo(Drive).i64Size;
end;
 
function RecyclerGetAPIInfo(Drive: Char): TSHQueryRBInfo;
begin
result := RecyclerGetAPIInfo(Drive + ':\');
end;
 
const
C_SHQueryRecycleBin = 'SHQueryRecycleBinA';
 
type
TSHQueryRecycleBin = function(pszRootPath: LPCTSTR;
var pSHQueryRBInfo: TSHQueryRBInfo): HRESULT; stdcall;
 
function RecyclerGetAPIInfo(Path: String): TSHQueryRBInfo;
var
SHQueryRecycleBin: TSHQueryRecycleBin;
RBHandle: THandle;
res: HRESULT;
resourcestring
LNG_NOT_CALLABLE = '%s not callable';
LNG_ERROR_CODE = '%s returns error code %s';
begin
SHQueryRecycleBin := nil;
 
// Ref: http://www.delphipraxis.net/post1291.html
 
RBHandle := LoadLibrary(shell32);
if(RBHandle <> 0) then
begin
SHQueryRecycleBin := GetProcAddress(RBHandle, C_SHQueryRecycleBin);
if(@SHQueryRecycleBin = nil) then
begin
FreeLibrary(RBHandle);
RBHandle := 0;
end;
end;
 
fillchar(result, SizeOf(TSHQueryRBInfo),0);
result.cbSize := SizeOf(TSHQueryRBInfo);
 
if (RBHandle <> 0) and (Assigned(SHQueryRecycleBin)) then
begin
res := SHQueryRecycleBin(PChar(Path), result);
// if Succeeded(res) then
if res = S_OK then
begin
// Alles OK, unser result hat nun die gewünschten Daten.
end
else
raise EAPICallError.CreateFmt(LNG_API_CALL_ERROR, [Format(LNG_ERROR_CODE, [C_SHQueryRecycleBin, '0x'+IntToHex(res, 2*SizeOf(HRESULT))])]);
end
else
raise EAPICallError.CreateFmt(LNG_API_CALL_ERROR, [Format(LNG_NOT_CALLABLE, [C_SHQueryRecycleBin])]);
 
if (RBHandle <> 0) then FreeLibrary(RBHandle);
end;
 
function RecyclerGetCLSID: string;
begin
result := RECYCLER_CLSID;
end;
 
// Windows 95 without Internet Explorer 4 has not SHQueryRecycleBinA.
function RecyclerQueryFunctionAvailable: boolean;
var
RBHandle: THandle;
SHQueryRecycleBin: TSHQueryRecycleBin;
begin
RBHandle := LoadLibrary(shell32);
if(RBHandle <> 0) then
begin
SHQueryRecycleBin := GetProcAddress(RBHandle, C_SHQueryRecycleBin);
if(@SHQueryRecycleBin = nil) then
begin
FreeLibrary(RBHandle);
RBHandle := 0;
end;
end;
 
result := RBHandle <> 0;
end;
 
function RecyclerLibraryVersion: string;
begin
result := 'ViaThinkSoft Recycle Bin Unit [14 JUN 2010]';
end;
 
end.
/Recycle Bin Unit/Recycler.dproj
0,0 → 1,108
 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{0BBA6E20-691E-4D2F-A209-AFF45FC4539C}</ProjectGuid>
<MainSource>Recycler.dpr</MainSource>
<Config Condition="'$(Config)'==''">Debug</Config>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<ProjectVersion>12.0</ProjectVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_SymbolReferenceInfo>1</DCC_SymbolReferenceInfo>
<DCC_DependencyCheckOutputName>Recycler.exe</DCC_DependencyCheckOutputName>
<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>
<DCC_Platform>x86</DCC_Platform>
<DCC_N>true</DCC_N>
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_F>false</DCC_F>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>false</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="Recycler.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Main.pas">
<Form>MainForm</Form>
</DCCReference>
<BuildConfiguration Include="Basis">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">Recycler.dpr</Source>
</Source>
<Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1031</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName">ViaThinkSoft</VersionInfoKeys>
<VersionInfoKeys Name="FileDescription">Recycler Bin Example</VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName">RecyclerBinExample</VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright">(C) Copyright 2007 ViaThinkSoft</VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename">Recycler.exe</VersionInfoKeys>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="Website">www.viathinksoft.de</VersionInfoKeys>
</VersionInfoKeys>
</Delphi.Personality>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
</Project>
/Recycle Bin Unit/clean.bat
0,0 → 1,12
@echo off
del *.dcu
del *.~*
del *.identcache
del *.local
rd /s /q __history
cd "Windows 95 Bit Bucket Reader"
del *.dcu
del *.~*
del *.identcache
del *.local
rd /s /q __history
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/BitBucketReader.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/Unit1.pas
0,0 → 1,80
unit Unit1;
 
interface
 
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, registry, ExtCtrls;
 
type
TForm1 = class(TForm)
Memo1: TMemo;
Timer1: TTimer;
Memo2: TMemo;
Splitter1: TSplitter;
procedure Timer1Timer(Sender: TObject);
private
procedure GetDump;
end;
 
var
Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
uses
Functions;
 
procedure TForm1.GetDump;
var
reg: tregistry;
i: integer;
oldr, r: string;
lw: char;
begin
reg := tregistry.create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\BitBucket') then
begin
oldr := memo1.text;
 
if reg.ValueExists('PurgeInfo') then
r := 'PurgeInfo = ' + BinaryStringToHexDump(RegistryReadDump(reg, 'PurgeInfo'))
else
r := 'No PurgeInfo';
 
for lw := 'A' to 'Z' do
begin
if reg.ValueExists(lw) then
begin
r := r + #13#10#13#10 + lw + ' = ' + BinaryStringToHexDump(RegistryReadDump(reg, lw));
end;
end;
 
if oldr <> '' then
begin
for i := 1 to length(oldr) do
begin
if oldr[i] <> r[i] then
memo2.Lines.Add(inttostr(i)+': '+oldr[i]+' -> '+r[i]);
end;
end;
 
memo1.Text := r;
reg.CloseKey;
end;
finally
reg.free;
end;
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
GetDump;
end;
 
end.
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/BitBucketReader.dpr
0,0 → 1,14
program BitBucketReader;
 
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Functions in 'Functions.pas';
 
{$R *.res}
 
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/Unit1.dfm
0,0 → 1,56
object Form1: TForm1
Left = 204
Top = 143
Width = 659
Height = 485
Caption = 'BitBucket Reader'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -14
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 120
TextHeight = 16
object Splitter1: TSplitter
Left = 0
Top = 193
Width = 651
Height = 5
Cursor = crVSplit
Align = alBottom
end
object Memo1: TMemo
Left = 0
Top = 0
Width = 651
Height = 193
Align = alClient
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -25
Font.Name = 'Courier'
Font.Style = []
ParentFont = False
ReadOnly = True
ScrollBars = ssVertical
TabOrder = 0
end
object Memo2: TMemo
Left = 0
Top = 198
Width = 651
Height = 248
Align = alBottom
ReadOnly = True
ScrollBars = ssVertical
TabOrder = 1
end
object Timer1: TTimer
Interval = 300
OnTimer = Timer1Timer
Left = 16
Top = 16
end
end
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/Project1.cfg
0,0 → 1,35
-$A8
-$B-
-$C+
-$D+
-$E-
-$F-
-$G+
-$H+
-$I+
-$J-
-$K-
-$L+
-$M-
-$N+
-$O+
-$P+
-$Q-
-$R-
-$S-
-$T-
-$U-
-$V+
-$W-
-$X+
-$YD
-$Z1
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00400000
-LE"c:\programme\borland\delphi6\Projects\Bpl"
-LN"c:\programme\borland\delphi6\Projects\Bpl"
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/Unit1.ddp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/BitBucketReader.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/Functions.pas
0,0 → 1,89
unit Functions;
 
(*
Some Delphi Functions
by Daniel Marschall
*)
 
interface
 
uses
SysUtils, Registry;
 
function RegistryReadDump(AReg: TRegistry; AName: string): string;
function BinaryStringToHexDump(ABinaryString: string): string;
 
type
TNibble = $0..$F;
 
function LowerNibble(B: Byte): TNibble;
function UpperNibble(B: Byte): TNibble;
function MakeByte(UpperNibble, LowerNibble: TNibble): Byte;
 
type
TBitPos = 0..7;
 
function GetBit(B: Byte; BitPos: TBitPos): boolean; overload;
function GetBit(B: Char; BitPos: TBitPos): boolean; overload;
 
implementation
 
function RegistryReadDump(AReg: TRegistry; AName: string): string;
const
// Win2000 RegEdit has set the max input length of a REG_BINARY to $3FFF.
// Probably its the longest possible binary string and not just a GUI limit.
BufMax = $3FFF;
var
buf: array[0..BufMax] of byte;
i: integer;
realsize: integer;
begin
realsize := AReg.ReadBinaryData(AName, buf, SizeOf(buf));
 
for i := 0 to realsize-1 do
begin
result := result + chr(buf[i]);
end;
end;
 
function BinaryStringToHexDump(ABinaryString: string): string;
var
i: integer;
begin
for i := 1 to Length(ABinaryString) do
begin
result := result + IntToHex(Ord(ABinaryString[i]), 2);
if i <> Length(ABinaryString) then
result := result + ' ';
end;
end;
 
function LowerNibble(B: Byte): TNibble;
begin
result := B and 15 {00001111};
end;
 
function UpperNibble(B: Byte): TNibble;
begin
result := B and 240 {11110000};
end;
 
function MakeByte(UpperNibble, LowerNibble: TNibble): Byte;
begin
result := LowerNibble + UpperNibble * $10;
end;
 
function GetBit(B: Byte; BitPos: TBitPos): boolean;
var
p: byte;
begin
p := 1 shl BitPos; // 2 ^ BitPos
result := B and p = p;
end;
 
function GetBit(B: Char; BitPos: TBitPos): boolean;
begin
result := GetBit(Ord(B), BitPos);
end;
 
end.
/Recycle Bin Unit/Windows 95 Bit Bucket Reader/Project1.dof
0,0 → 1,83
[FileVersion]
Version=6.0
[Compiler]
A=8
B=0
C=1
D=1
E=0
F=0
G=1
H=1
I=1
J=0
K=0
L=1
M=0
N=1
O=1
P=1
Q=0
R=0
S=0
T=0
U=0
V=1
W=0
X=1
Y=1
Z=1
ShowHints=1
ShowWarnings=1
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
[Linker]
MapFile=0
OutputObjs=0
ConsoleApp=1
DebugInfo=0
RemoteSymbols=0
MinStackSize=16384
MaxStackSize=1048576
ImageBase=4194304
ExeDescription=
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
Packages=
Conditionals=
DebugSourceDirs=
UsePackages=0
[Parameters]
RunParams=
HostApplication=
Launcher=
UseLauncher=0
DebugCWD=
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
/Recycle Bin Unit/PurgeInfo Interpretation Theorety.txt
0,0 → 1,101
Windows 95
PurgeInfo Interpretation Theorety
by Daniel Marschall
 
= Locality =
 
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\BitBucket: PurgeInfo (Binary)
 
= Data structure =
 
Offset 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
Data 48 00 00 00 01 00 00 00 0A 00 0A 00 0A 00 0A 00
Sign ?? ?? ?? ?? GS ?? ?? ?? Pa ?? Pb ?? Pc ?? Pd ??
 
Offset 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
Data 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00
Sign Pe ?? Pf ?? Pg ?? Ph ?? Pi ?? Pj ?? Pk ?? Pl ??
 
Offset 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
Data 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00
Sign Pm ?? Pn ?? Po ?? Pp ?? Pq ?? Pr ?? Ps ?? Pt ??
 
Offset 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
Data 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00 0A 00
Sign Pu ?? Pv ?? Pw ?? Px ?? Py ?? Pz ?? ?? ?? PG ??
 
Offset 40 41 42 43 44 45 46 47
Data 00 00 00 00 04 0D 02 00
Sign N1 N2 N3 N4 ?? ?? ?? ??
 
= Legend =
 
GS
Global settings
0x00 = Individual settings for every drive
0x01 = Global settings for all drives
 
Pa..Pz
Percentage of the drive A..Z
0x00 = 0%
0x64 = 100%
 
PG
Percentage of all drives (Global setting)
0x00 = 0%
0x64 = 100%
 
N1
"Nuke on delete" setting in a bitmask (7..0)
Bit 0 = Flag for device A
Bit 1 = Flag for device B
Bit 2 = Flag for device C
Bit 3 = Flag for device D
Bit 4 = Flag for device E
Bit 5 = Flag for device F
Bit 6 = Flag for device G
Bit 7 = Flag for device H
 
N2
"Nuke on delete" setting in a bitmask (7..0)
Bit 0 = Flag for device I
Bit 1 = Flag for device J
Bit 2 = Flag for device K
Bit 3 = Flag for device L
Bit 4 = Flag for device M
Bit 5 = Flag for device N
Bit 6 = Flag for device O
Bit 7 = Flag for device P
 
N3
"Nuke on delete" setting in a bitmask (7..0)
Bit 0 = Flag for device Q
Bit 1 = Flag for device R
Bit 2 = Flag for device S
Bit 3 = Flag for device T
Bit 4 = Flag for device U
Bit 5 = Flag for device V
Bit 6 = Flag for device W
Bit 7 = Flag for device X
 
N4
"Nuke on delete" setting in a bitmask (7..0)
Bit 0 = Flag for device Y
Bit 1 = Flag for device Z
Bit 2 = Unknown
Bit 3 = Flag for global setting
Bit 4 = Unknown
Bit 5 = Unknown
Bit 6 = Unknown
Bit 7 = Unknown
 
= Already confirmed =
 
Checked with Windows 95b with 1 FAT32 drive.
 
The functionality of following bytes was confirmed:
- GS: Global settings
- Pc: Percentage of drive C
- PG: Percentage of global configuration
- N1: Value 0x04 (0000 0100) and 0x00 (0000 0000) for changes at drive C
- N4: Value 0x08 (0000 1000) and 0x00 (0000 0000) for changes at the global configuration