Windows Recycle Bin information file binary format

Viewed 512

Programmatic removing of files to Recycle Bin in Windows is a trivial operation.

In short: just move a file to C:\$Recycle.Bin\SID\$R{name}* (for drive C) and create an associated binary file ($I{name}) with meta information about the "deleted" file/folder near it.

* where SID is your OS installation identifier that looks like: S-1-5-21-1234567890-1234567890-1234567890-1001.


But I have two question after researching:

  • What is the algorithm of encoding the deletion date to 64-bit value?
  • Are the file names (in a trash bin) random generated or there is some logic?

The information file structure is follow (based on my research):

const buffer = new Uint8Array([
    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Header
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Size                // 65535 (bytes)
    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xd7, 0x01,  // Deletion date (64-bit value)
    0x0b, 0x00, 0x00, 0x00,                          // Path string length  // `11`
                            0x43, 0x00, 0x3a, 0x00,  // File path + \0      // `C:\1\1.txt`  // `C:\\1\\1.txt\0`
    0x5c, 0x00, 0x31, 0x00, 0x5c, 0x00, 0x31, 0x00,
    0x2e, 0x00, 0x74, 0x00, 0x78, 0x00, 0x74, 0x00,
    0x00, 0x00
]);

Header (always is the same), file size in bytes (which is only visible in File Explorer), 64-bit deletion date value, path string length, and UTF-16 encoded null-terminated path string.

The only questionable part is the date. How is it encoded?

For example:

00 00 00 00 00 29 d7 01 is 2021.04.04 03:10

00 00 00 00 01 29 d7 01 is 2021.04.04 03:17

00 00 00 00 00 30 d7 01 is 2021.04.13 00:57

(The first four hexes is 00 just for convenience.)

For example: 00 00 00 00 00 29 d7 01 is 132619794007457792, but new Date(132619794007457792/100000) is 2012.01.10 12:19:00.

I need to transform 00 00 00 00 00 29 d7 01 bytes to 2021.04.04 03:10.


The "deleted" files in C:\$Recycle.Bin\SID\ have name that is started with $R + [A-Z0-9]{7} + optional .{extension}. For example: $RL6JQMF.txt. And associated meta data file: $IL6JQMF.txt that just starts with $I.

Is there some logic for the naming or it is just a random generated one?

In fact, for example, it works well with both $R___ + $I___, and with $R123456789 abc + $I123456789 abc. So, I think it is just random generated.

Only the $R/$I is required. The extension is needed only just to shows the corresponding icon in the File Explorer.

2 Answers

Okay, I got it.

While 00 00 00 00 00 00 00 00 is 1899.12.30 00:00,

but 00 00 00 00 00 00 01 00 is 1601.11.22 18:44,

so this timestamp is a number of 100-nanosecond intervals since 1601.01.01.

For example, for 00 00 00 00 00 29 d7 01 (132619794007457792) I get the correct date (2021.04.04 03:10) as it shows in File Explorer with:

new Date(132619794007457792 / 10000 + Number(new Date("1601.01.01 Z")))

Anyway, I think this topic would be useful for people.

It's strange that in 2021 I did not found any info about how Recycle Bin in Windows works.

Ive done some extensive research on this, as it seems, surprisingly, there is very few info available online on how Recycle Bin actually implemented.

Everything is not that hard to grasp. When you delete file in the Bin, it is not actually moved to it.

First, lets take a look at the subfolders of $Recycle.Bin:

  • C:\$Recycle.Bin\S-1-5-18 is folder for built-in SYSTEM account
  • C:\$Recycle.Bin\S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-1XXX\, starting from 1000 are non-built in user folders. You should first check which one of them is the one you need by typing whoami /all in command prompt to get your SID, or wmic useraccount get name,sid to get all local accounts SIDs, then choose the folder matching with SID.

If you give security rights to your account to all this folders, Explorer might show your deleted files in every folder, however its just Explorer bug. If you navigate to, say, C:\$Recycle.Bin\S-1-5-18 folder and type dir /a, you will see that its actually empty, and only folder that match with your SID contains your deleted files.

Note that even if you are the only user on the PC, you might still have folder C:\$Recycle.Bin\S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-1000\ that most likely will be empty. Then your actual folder will be ...-1001\. User "1000" seems to be dangling folder for user that was created automatically by Windows on installation or some updates, then deleted. But Recycle.Bin folder wasn't destroyed and just stayed there. I assume that its safe to delete this dangling folder. I'm not so sure about C:\$Recycle.Bin\S-1-5-18, but I'm fairly sure its safe too, as there is no need for OS SYSTEM account to use the Bin, anyway.

So, here is deletion algorithm:

  1. System creates hardlink of the deleted file in C:\$Recycle.Bin\S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-1XXX\ folder with the name $RXXXXXX.<file_ext>, where XXXXXX is 6 symbols HASH calculated based on the file contents, as I assume.
  2. Metadata file is created in the same folder with the name $IXXXXXX.<file_ext>. I will show you the content of this file later.
  3. Original file is deleted, but because of extra hardlink in $Recycle.Bin, actual file's data stays in the same location on the drive as if file where never touched. It is not moved anywhere. This is why each logical volume must have it's own $Recycle.Bin folder, as hardlinks only work within the same volume.

That's about it. Restoration algorithm:

  1. Metadata file is read and hardlink of $RXXXXXX.<file_ext> is created based on $IXXXXXX.<file_ext>'s info in original file location, with original file name.
  2. Both metadata and backup file are deleted from $Recycle.Bin

Pretty simple, ain't it?

Now, the most interesting part is that metadata file:

0000  02 00 00 00 00 00 00 00  <-- File header (QW)
0008  00 7C 0A 00 00 00 00 00  <-- File size (QW)
0010  90 83 72 44 28 9C D8 01  <-- File deletion date (QW)
0018  18 00 00 00|43 00 3A 00  <-- File path string length (DW)
0020  5C 00 24 00 52 00 65 00  
0028  63 00 79 00 63 00 6C 00
0030  65 00 2E 00 42 00 69 00
0038  6E 00 5C 00 66 00 73 00
0040  73 00 2E 00 65 00 78 00
0048  65 00 00 00|             <-- |Null-terminated path string| (wchar_t)

All values are in Little Endian format.

Header is fixed and its identical for all the files. Be warned that some $I files might have some junk bytes FF FE appear before the Header. I have no idea what are this for, so you should check for full header before reading further.

Deletion date is in FILETIME format and can be converted to usual SYSTEMTIME via FileTimeToSystemTime. It represents 100-nanosecond intervals since January 1, 1601 (UTC).

So it's not super complicated file format, but quite interesting design.

I'm planing to use this info myself by creating custom "garbage collector" for Windows, that I will add to task scheduler to launch periodically and scan\delete files that where deleted more than 24 hours ago, etc. I know that Windows 10 has built-in option for this, but it's not flexible and not reliable (it sometimes leaves metadata files, while only deleteing $R files). Also, I think, previous Windows versions doesn't have this feature at all.

I encourage you to experiment with this too! For example, your program might save metadata info of all files it removes into some database, so you would have full history of all files you ever deleted!

Related