NTFS文件系统的UsnJrnl对于FileReference的处理
1. 背景
http://stackoverflow.com/q/20418694/941650
这里面临的一个核心问题是,如果MFT Reference相等,能够表明这些记录代表的是同一个文件吗?
对于这个问题,我们可以采取实验的方式来验证。
2. 实验环境
在实验设备Windows 7操作系统下,D盘是NTFS格式,而且打开了UsnJrnl功能。
使用fsutil usn工具来获取到关于UsnJrnl的信息:
1: C:\Windows\system32>fsutil usn
2: ---- USN Commands Supported ----
3:
4: createjournal Create a USN journal
5: deletejournal Delete a USN journal
6: enumdata Enumerate USN data
7: queryjournal Query the USN data for a volume
8: readdata Read the USN data for a file
1: C:\Windows\system32>fsutil usn queryjournal D:
2: Usn Journal ID : 0x01cd6ad7d5cd624e
3: First Usn : 0x0000000028100000
4: Next Usn : 0x000000002a38bc50
5: Lowest Valid Usn : 0x0000000000000000
6: Max Usn : 0x7fffffffffff0000
7: Maximum Size : 0x0000000002000000
8: Allocation Delta : 0x0000000000400000
1: fsutil usn readdata 1 0 0x7fffffffffff0000 D:
3. 实验
1. 创建一个文档daniel.txt
1: File Ref# : 0x00050000000c6c3f
2: ParentFile Ref# : 0x0005000000000005
3: Usn : 0x000000002a38a7c8
4: SecurityId : 0x00000000
5: Reason : 0x00000000
6: Name (020) : daniel.txt
可以看到它的File Ref为
File Ref# : 0x00050000000c6c3f
里面分解为更新号0x0005以及Mft Reference号0x0000000c6c3f
将daniel.txt文件删除后,
1: File Ref# : 0x00050000000c6c3f
2: ParentFile Ref# : 0x003c00000000002a
3: Usn : 0x000000002a38afa0
4: SecurityId : 0x00000000
5: Reason : 0x00000000
6: Name (024) : $R2QW90X.txt
仍然可以找到这个文件的记录,因为只是放到了回收站而已。
再在相同的位置创建一个同名的文件
1: File Ref# : 0x00040000000c6c43
2: ParentFile Ref# : 0x0005000000000005
3: Usn : 0x000000002a38b050
4: SecurityId : 0x00000000
5: Reason : 0x00000000
6: Name (020) : daniel.txt
可以看到这时文件名和位置虽然一致,但是File Reference号已经不同了。
我们到回收站里将daniel.txt复原,
选择覆盖,
1: File Ref# : 0x00050000000c6c3f
2: ParentFile Ref# : 0x0005000000000005
3: Usn : 0x000000002a38b3c0
4: SecurityId : 0x00000000
5: Reason : 0x00000000
6: Name (020) : daniel.txt
这时的记录就和刚刚创建的时候一致了。
我们这次将daniel.txt完成删除(不放到回收站里),再创建一个同名的文件
1: File Ref# : 0x00040000000c6c48
2: ParentFile Ref# : 0x0005000000000005
3: Usn : 0x000000002a38cf48
4: SecurityId : 0x00000000
5: Reason : 0x00000000
6: Name (020) : daniel.txt
这回记录不一样了,但是我们发现了下面的一条记录
1: File Ref# : 0x00060000000c6c3f
2: ParentFile Ref# : 0x0005000000000005
3: Usn : 0x000000002a38bbf0
4: SecurityId : 0x00000000
5: Reason : 0x00000000
6: Name (034) : journal_dump4.txt
可见,MFT表里的位置是很珍贵的,不能随便浪费,因此会不断地复用。
所以添加了一个更新号来区分究竟是不是同一个文件,只有当File Reference整体都相同时,才有可能是同一个文件。