Rev 99 | Rev 101 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
98 | daniel-mar | 1 | |
2 | # Windows Recycle Bin internal format |
||
3 | |||
4 | ## Locations |
||
5 | |||
6 | ### FAT drives: |
||
7 | |||
99 | daniel-mar | 8 | - Windows 95 native: `C:\RECYCLED\INFO` (with ANSI records, folder deletion is NOT possible, format `00 00 00 00`) |
9 | - Windows 95+IE4, 98SE: `C:\RECYCLED\INFO2` (with ANSI records, folder deletion is possible, format `04 00 00 00`) |
||
10 | - Windows Me: `C:\RECYCLED\INFO2` (with ANSI records, folder deletion is possible, format `05 00 00 00`) |
||
11 | - Windows Vista+: `C:\$RECYCLE.BIN\$I...` |
||
98 | daniel-mar | 12 | |
13 | ### NTFS drives: |
||
14 | |||
99 | daniel-mar | 15 | - Windows NT4: `C:\RECYCLER\<UserSID>\INFO` (with Unicode records, folder deletion is possible, format `02 00 00 00`) |
16 | - Windows 2000, XP: `C:\RECYCLER\<UserSID>\INFO2` (with Unicode records, folder deletion is possible, format `05 00 00 00`) |
||
17 | - Windows Vista+: `C:\$RECYCLE.BIN\<UserSID>\$I...` |
||
98 | daniel-mar | 18 | |
19 | ## INFO and INFO2 files |
||
20 | |||
21 | INFO is written by Win95 without IE4 (with ANSI records), and WinNT4 (with Unicode records). |
||
22 | |||
23 | INFO2 is written by Win95 with Internet Explorer 4 shell extensions, Win98, WinMe (with ANSI records), Win2000, and WinXP (with Unicode records). |
||
24 | |||
99 | daniel-mar | 25 | 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. |
98 | daniel-mar | 26 | |
27 | 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). |
||
28 | |||
29 | ### Header |
||
30 | |||
31 | type |
||
32 | PRbInfoHeader = ^TRbInfoHeader; |
||
99 | daniel-mar | 33 | TRbInfoHeader = packed record |
34 | format: DWORD; // Version of the info file |
||
35 | // Win95 (without IE4): 00 00 00 00 |
||
36 | // Win NT4: 02 00 00 00 (Win96/Cairo?) |
||
37 | // Win95 (with IE4), 98: 04 00 00 00 |
||
38 | // Win Me, 2000, XP: 05 00 00 00 (NT4+IE4, NT5?) |
||
100 | daniel-mar | 39 | 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 |
40 | 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 |
||
99 | daniel-mar | 41 | recordLength: DWORD; // 0x181 = ANSI records |
42 | // 0x320 = Unicode records |
||
43 | totalSize: DWORD; // sum of all "originalSize" values; |
||
100 | daniel-mar | 44 | // 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 |
98 | daniel-mar | 45 | end; |
46 | |||
99 | daniel-mar | 47 | ### ANSI record (Win95, Win98, WinMe) |
98 | daniel-mar | 48 | |
100 | daniel-mar | 49 | When a file is deleted, the first byte of `sourceAnsi` will be filled with a zero byte, |
50 | making the zero-terminated string empty. This way, the record is marked as deleted |
||
51 | and the INFO/INFO2 file does not need to be reorganized. |
||
52 | |||
98 | daniel-mar | 53 | type |
54 | // Windows 95: INFO file with TRbInfoRecordA; Folder deletion NOT possible |
||
55 | // Windows 95 +IE4: INFO2 file with TRbInfoRecordA; Folder deletion possible |
||
56 | PRbInfoRecordA = ^TRbInfoRecordA; |
||
99 | daniel-mar | 57 | TRbInfoRecordA = packed record |
58 | sourceAnsi: array[0..MAX_PATH-1] of AnsiChar; // 260 characters (including NUL terminator) |
||
98 | daniel-mar | 59 | recordNumber: DWORD; |
100 | daniel-mar | 60 | sourceDrive: DWORD; // 0=A, 1=B, 2=C, ..., Z=25, @=26 (@ is the "Network home drive" of the Win95 time) |
98 | daniel-mar | 61 | deletionTime: FILETIME; |
62 | originalSize: DWORD; // Size occupied on disk. Not the actual file size. |
||
63 | // INFO2, for folders: The whole folder size with contents |
||
64 | end; |
||
65 | |||
99 | daniel-mar | 66 | ### Unicode record (WinNT4, Win2000, WinXP) |
98 | daniel-mar | 67 | |
100 | daniel-mar | 68 | When a file is deleted, the first byte of `sourceAnsi` will be filled with a zero byte, |
69 | making the zero-terminated string empty. This way, the record is marked as deleted |
||
70 | and the INFO/INFO2 file does not need to be reorganized. |
||
71 | |||
98 | daniel-mar | 72 | type |
73 | // Windows NT4: INFO file with TRbInfoRecordW; Folder deletion possible |
||
74 | // Windows 2000+: INFO2 file with TRbInfoRecordW; Folder deletion possible |
||
75 | PRbInfoRecordW = ^TRbInfoRecordW; |
||
99 | daniel-mar | 76 | TRbInfoRecordW = packed record |
77 | sourceAnsi: array[0..MAX_PATH-1] of AnsiChar; // 260 characters (including NUL terminator) |
||
98 | daniel-mar | 78 | recordNumber: DWORD; |
100 | daniel-mar | 79 | sourceDrive: DWORD; // 0=A, 1=B, 2=C, ..., Z=25, @=26 (@ is the "Network home drive" of the Win95 time) |
98 | daniel-mar | 80 | deletionTime: FILETIME; |
81 | originalSize: DWORD; |
||
99 | daniel-mar | 82 | sourceUnicode: array[0..MAX_PATH-1] of WideChar; // 260 characters (including NUL terminator) |
98 | daniel-mar | 83 | end; |
84 | |||
85 | ## $I... files of Windows Vista and above |
||
86 | |||
99 | daniel-mar | 87 | 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). |
98 | daniel-mar | 88 | |
89 | ### Version 1 (Introduced in Windows Vista) |
||
90 | |||
91 | type |
||
92 | // Introduced in Windows Vista |
||
93 | PRbVistaRecord1 = ^TRbVistaRecord1; |
||
99 | daniel-mar | 94 | TRbVistaRecord1 = packed record |
98 | daniel-mar | 95 | version: int64; // Always 01 00 00 00 00 00 00 00 |
96 | originalSize: int64; |
||
97 | deletionTime: FILETIME; |
||
98 | sourceUnicode: array[0..MAX_PATH-1] of WideChar; |
||
99 | end; |
||
100 | |||
101 | ### Version 2 (Introduced somewhere in a Windows 10 release) |
||
102 | |||
103 | type |
||
104 | // Introduced somewhere in a Win10 release |
||
105 | PRbVistaRecord2Head = ^TRbVistaRecord2Head; |
||
99 | daniel-mar | 106 | TRbVistaRecord2Head = packed record |
98 | daniel-mar | 107 | version: int64; // Always 02 00 00 00 00 00 00 00 |
108 | originalSize: int64; |
||
109 | deletionTime: FILETIME; |
||
110 | (* sourceUnicode: BSTR; *) |
||
111 | sourceCountChars: DWORD; // including NUL |
||
100 | daniel-mar | 112 | //sourceUnicode: array[0..sourceCountChars-1] of WideChar; |
98 | daniel-mar | 113 | end; |