Subversion Repositories recyclebinunit

Compare Revisions

Regard whitespace Rev 100 → Rev 101

/trunk/FORMAT.md
9,6 → 9,7
- Windows 95+IE4, 98SE: `C:\RECYCLED\INFO2` (with ANSI records, folder deletion is possible, format `04 00 00 00`)
- Windows Me: `C:\RECYCLED\INFO2` (with ANSI records, folder deletion is possible, format `05 00 00 00`)
- Windows Vista+: `C:\$RECYCLE.BIN\$I...`
- Windows 95 (Beta 58s) `<WinDir>\DESKTOP\RECYCLE.BIN` (a normal folder with the deleted files. No index, no renamed files). In beta build 122, the recycle bin was removed and re-added in beta build 180 with the INFO-format we know from the RTM release.
 
### NTFS drives:
 
24,64 → 25,53
 
Since some Windows version combinations mix up ANSI records and Unicode records (e.g. Win95+IE4 and Win2000), these Windows versions break the recycle bin information file of each other.
 
INFO and INFO2 is the index file containing all information about the deleted files. The data files are renamed to `Dxy.ext` (`x` replaced with the drive letter, `y` being a dynamic length integer, `ext` being replaced with the file name extension).
INFO and INFO2 is the index file containing all information about the deleted files. The data files are renamed to `Dxyyy.ext` (`x` replaced with the drive letter, `yyy` being a dynamic length integer, `ext` being replaced with the file name extension).
 
### Header
 
type
PRbInfoHeader = ^TRbInfoHeader;
TRbInfoHeader = packed record
format: DWORD; // Version of the info file
// Win95 (without IE4): 00 00 00 00
// Win NT4: 02 00 00 00 (Win96/Cairo?)
// Win95 (with IE4), 98: 04 00 00 00
// Win Me, 2000, XP: 05 00 00 00 (NT4+IE4, NT5?)
totalEntries: DWORD; // Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons
nextPossibleID: DWORD; // Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons
recordLength: DWORD; // 0x181 = ANSI records
// 0x320 = Unicode records
totalSize: DWORD; // sum of all "originalSize" values;
// Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons
end;
| offset (hex) | size (dec) | type | description |
|--------------|------------|-------|-------------|
| 0000 | 4 | DWORD | Version of the info file<br>`00 00 00 00` = Win95 (without IE4)<br>`02 00 00 00` = Win NT4 (Win96/Cairo?)<br>`04 00 00 00` = Win95 (with IE4), Win98<br>`05 00 00 00` = Win Me, 2000, WinXP (NT4+IE4, NT5?) |
| 0004 | 4 | DWORD | Total entries. Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons. |
| 0008 | 4 | DWORD | Next possible ID. Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons. |
| 000C | 4 | DWORD | Item record length<br>0x118 = ANSI records<br>0x320 = Unicode records |
| 0010 | 4 | DWORD | Total size (sum of all original sizes of the files). Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons. |
 
### ANSI record (Win95, Win98, WinMe)
 
When a file is deleted, the first byte of `sourceAnsi` will be filled with a zero byte,
When a file is deleted, the first byte of the original filename will be set to a zero byte,
making the zero-terminated string empty. This way, the record is marked as deleted
and the INFO/INFO2 file does not need to be reorganized.
 
type
// Windows 95: INFO file with TRbInfoRecordA; Folder deletion NOT possible
// Windows 95 +IE4: INFO2 file with TRbInfoRecordA; Folder deletion possible
PRbInfoRecordA = ^TRbInfoRecordA;
TRbInfoRecordA = packed record
sourceAnsi: array[0..MAX_PATH-1] of AnsiChar; // 260 characters (including NUL terminator)
recordNumber: DWORD;
sourceDrive: DWORD; // 0=A, 1=B, 2=C, ..., Z=25, @=26 (@ is the "Network home drive" of the Win95 time)
deletionTime: FILETIME;
originalSize: DWORD; // Size occupied on disk. Not the actual file size.
// INFO2, for folders: The whole folder size with contents
end;
Windows 95: INFO file with ANSI record; Folder deletion NOT possible
Windows 95 +IE4: INFO2 file with ANSI record; Folder deletion possible
 
| offset (hex) | size (dec) | type | description |
|--------------|------------|-----------------|-------------|
| 0000 | 260 | char[MAX_PATH] | Original file name and path in ANSI characters. 260 characters (including NUL terminator). Empty string if file was deleted. |
| 0104 | 4 | DWORD | Record number |
| 0108 | 4 | DWORD | Source drive; 0=A, 1=B, 2=C, ..., Z=25, @=26 (@ is the "Network home drive" of the Win95 times) |
| 010C | 8 | FILETIME | Deletion time |
| 0114 | 4 | DWORD | Size occupied on disk. Not the actual file size.<br>INFO2, for folders: The whole folder size with contents |
 
### Unicode record (WinNT4, Win2000, WinXP)
 
When a file is deleted, the first byte of `sourceAnsi` will be filled with a zero byte,
When a file is deleted, the first byte of the original filename will be set to a zero byte,
making the zero-terminated string empty. This way, the record is marked as deleted
and the INFO/INFO2 file does not need to be reorganized.
 
type
// Windows NT4: INFO file with TRbInfoRecordW; Folder deletion possible
// Windows 2000+: INFO2 file with TRbInfoRecordW; Folder deletion possible
PRbInfoRecordW = ^TRbInfoRecordW;
TRbInfoRecordW = packed record
sourceAnsi: array[0..MAX_PATH-1] of AnsiChar; // 260 characters (including NUL terminator)
recordNumber: DWORD;
sourceDrive: DWORD; // 0=A, 1=B, 2=C, ..., Z=25, @=26 (@ is the "Network home drive" of the Win95 time)
deletionTime: FILETIME;
originalSize: DWORD;
sourceUnicode: array[0..MAX_PATH-1] of WideChar; // 260 characters (including NUL terminator)
end;
Windows NT4: INFO file with Unicode record; Folder deletion possible
Windows 2000+: INFO2 file with Unicode record; Folder deletion possible
 
| offset (hex) | size (dec) | type | description |
|--------------|------------|-----------------|-------------|
| 0000 | 260 | char[MAX_PATH] | Original file name and path in ANSI characters. 260 characters (including NUL terminator). Empty string if file was deleted. |
| 0104 | 4 | DWORD | Record number |
| 0108 | 4 | DWORD | Source drive; 0=A, 1=B, 2=C, ..., Z=25, @=26 (@ is the "Network home drive" of the Win95 times) |
| 010C | 8 | FILETIME | Deletion time |
| 0114 | 4 | DWORD | Original size |
| 0118 | 520 | wchar[MAX_PATH] | Original file name and path in Unicode characters. 260 characters (including NUL terminator) |
 
## $I... files of Windows Vista and above
 
Beginning with Windows Vista, each deleted file gets its own information record. The information record ("index file") has the name `$Ixxxxxx.ext` while the data file is renamed to `$Rxxxxxx.ext` (`xxxxxx` replaced with a random `[0-9A-Z]` string and `ext` replaced with the file name extension).
88,26 → 78,19
 
### Version 1 (Introduced in Windows Vista)
 
type
// Introduced in Windows Vista
PRbVistaRecord1 = ^TRbVistaRecord1;
TRbVistaRecord1 = packed record
version: int64; // Always 01 00 00 00 00 00 00 00
originalSize: int64;
deletionTime: FILETIME;
sourceUnicode: array[0..MAX_PATH-1] of WideChar;
end;
| offset (hex) | size (dec) | type | description |
|--------------|------------|-----------------|-------------|
| 0000 | 8 | int64 | Version, always `01 00 00 00 00 00 00 00` |
| 0008 | 8 | uint64 | Original size |
| 0010 | 8 | FILETIME | Deletion time |
| 0018 | 520 | wchar[MAX_PATH] | Original file name and path in Unicode characters. 260 characters (including NUL terminator) |
 
### Version 2 (Introduced somewhere in a Windows 10 release)
 
type
// Introduced somewhere in a Win10 release
PRbVistaRecord2Head = ^TRbVistaRecord2Head;
TRbVistaRecord2Head = packed record
version: int64; // Always 02 00 00 00 00 00 00 00
originalSize: int64;
deletionTime: FILETIME;
(* sourceUnicode: BSTR; *)
sourceCountChars: DWORD; // including NUL
//sourceUnicode: array[0..sourceCountChars-1] of WideChar;
end;
| offset (hex) | size (dec) | type | description |
|--------------|------------|-----------------|-------------|
| 0000 | 8 | int64 | Version, always `02 00 00 00 00 00 00 00` |
| 0008 | 8 | uint64 | Original size |
| 0010 | 8 | FILETIME | Deletion time |
| 0018 | 4 | DWORD | Original file name and path: Count of Unicode characters, including NUL terminator |
| 001C | 2*n | wchar[] | Original file name and path: Zero terminated Unicode string |
/trunk/Recycle Bin Unit v2/RecBinUnit2.pas
894,7 → 894,7
end
else
begin
// Not enough space to read a Ansi record!
// Not enough space to read a ANSI record!
// Ignore it
end;
end;
/trunk/Recycle Bin Unit v2/RecBinUnitLowLvl.pas
15,7 → 15,7
// Win Me, 2000, XP: 05 00 00 00 (NT4+IE4, NT5?)
totalEntries: DWORD; // Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons
nextPossibleID: DWORD; // Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons
recordLength: DWORD; // 0x181 = ANSI records
recordLength: DWORD; // 0x118 = ANSI records
// 0x320 = Unicode records
totalSize: DWORD; // sum of all "originalSize" values;
// Only Win95 (without IE4) and Win NT4, other OS versions will use the registry instead and might write information on WM_ENDSESSION for compatibility reasons
64,13 → 64,12
version: int64; // Always 02 00 00 00 00 00 00 00
originalSize: int64;
deletionTime: FILETIME;
(* sourceUnicode: BSTR; *)
sourceCountChars: DWORD; // including NUL
//sourceUnicode: array[0..sourceCountChars-1] of WideChar;
end;
 
type
// Windows 95 (tested with 4.00.950 and Win95b) + Windows NT 4
// Windows 95 (tested with 4.00.180 and above) + Windows NT 4
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\BitBucket: PurgeInfo (Binary)
// TODO: also explain this in FORMAT.md ?
PRbWin95PurgeInfo = ^TRbWin95PurgeInfo;
88,7 → 87,7
// Bit 26: "Network home drive"
// Bit 27: Global
// Bit 28..31 (MSB) unused
dummy: DWORD; // "dummy to force a new size" ?! (TODO: was there a Windows version that had a smaller size (0x44), i.e. a different version of this record?)
dummy: DWORD; // "dummy to force a new size" ?! But the 0x48 format was already in Win95 beta build 180, which is the first known build with this recycle bin implementation!
end;
 
implementation
/trunk/Research/PurgeInfo Analysis.txt
77,9 → 77,9
"Nuke on delete" setting in a bitmask (7..0)
Bit 0 (LSB) = Flag for device Y
Bit 1 = Flag for device Z
Bit 2 = Flag for "homedrive"
Bit 2 = Flag for network home drive
Bit 3 = Flag for global setting
Bit 4 = Unknown
Bit 5 = Unknown
Bit 6 = Unknown
Bit 7 (MSB) = Unknown
Bit 4 = Unused
Bit 5 = Unused
Bit 6 = Unused
Bit 7 (MSB) = Unused