如何真正通过报告的“文件记录段”地址来识别文件chkdsk
?
发生了停电,我的驱动器的文件系统损坏了,硬件和操作系统文件没有问题,我已经做了彻底的检查,但我先做了一件愚蠢的事,运行chkdsk /f X:
它处理了 107855 个数据文件。
我能够访问 System Volume Information 文件夹并在其中的 Chkdsk 文件夹中找到日志。日志大小为 11.2MiB,我已将其上传到Google 云端硬盘。
我正在尝试以编程方式抓取日志文件并识别受其影响的所有文件。编写程序对我来说非常简单,我知道自己在做什么。
我想检查受影响的文件并删除损坏的文件,并可能重新下载它们。该驱动器包含数万亿字节的下载盗版游戏和我创建的数万亿字节的数据。我不想进行数据恢复之类的工作。
问题是,所使用的术语chkdsk
不一致且令人困惑:
Checking file system on D:
The type of the file system is NTFS.
Chkdsk cannot run because the volume is in use by another
process. Chkdsk may run if this volume is dismounted first.
ALL OPENED HANDLES TO THIS VOLUME WOULD THEN BE INVALID.
Would you like to force a dismount on this volume? (Y/N) Volume dismounted. All opened handles to this volume are now invalid.
Volume label is Tremillia.
Stage 1: Examining basic file system structure ...
Attribute record of type 0x80 and instance tag 0x4 is cross linked
starting at 0x9383fc2 for possibly 0xfe clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x4
in file 0x46c4 is already in use.
Deleting corrupt attribute record (0x80, "")
from file record segment 0x46C4.
Attribute record of type 0x80 and instance tag 0x4 is cross linked
starting at 0x93840c0 for possibly 0x95 clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x4
in file 0x46c5 is already in use.
Deleting corrupt attribute record (0x80, "")
from file record segment 0x46C5.
Attribute record of type 0x80 and instance tag 0x4 is cross linked
starting at 0x9384489 for possibly 0xc5 clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x4
in file 0x4706 is already in use.
Deleting corrupt attribute record (0x80, "")
from file record segment 0x4706.
Attribute record of type 0x80 and instance tag 0x4 is cross linked
starting at 0x938454e for possibly 0x90 clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x4
in file 0x470b is already in use.
Deleting corrupt attribute record (0x80, "")
from file record segment 0x470B.
Attribute record of type 0x80 and instance tag 0x3 is cross linked
starting at 0x93799ea for possibly 0x40 clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x3
in file 0x4f3f is already in use.
...
十六进制地址有 3 种类型,分别称为“文件记录段”、“文件”和“簇”。你马上就会发现簇地址一开始就很大,比“文件”和“文件记录段”的地址大得多。
然后你可以看到“文件”和“文件记录段”地址的范围相似,并且相同的地址被称为“文件”和“文件记录段”。所以很明显,“文件”和“文件记录段”是同一个东西。
我尝试在 Google 上搜索如何通过文件记录段识别文件,但大多数结果都完全不相关,排名靠前的结果是一些可疑软件公司为销售其产品而制作的无用教程。诸如“如何修复”、“文件记录段无法读取时该怎么办”之类的内容……
Google 完全没用,结果根本不是我想要的,我想通过“文件记录段”编号来识别文件。
我发现唯一相关的是这个帖子。
好吧,我终于有机会尝试一些基于 Linux 的 ntfs 实用程序。我不确定它们是来自 ntfs-3g、ntfsprogs 还是 ntfsutils,但任何拥有最喜欢的 Linux 发行版的人都应该能够启动它并轻松获取我需要的信息。这些数字是 inode 编号,两个命令非常有用。这个提供了我所需要的:
ntfscluster -I <inode 编号 / 文件记录段编号>
它包含了相关文件的完整路径和很少的其他信息。>这个命令提供了大量我不需要的信息:
ntfsinfo -i <inode #/文件记录段#>
它没有提供路径,但提供了父目录的 inode 编号,因此您可以通过反复使用此命令对路径进行逆向工程。
NTFSCluster 是一个 Linux 实用程序,搜索后ntfscluster windows
会显示有关 NTFS 文件系统及其簇大小的结果,并显示“您是不是要查找:ntfs 簇窗口”的消息。唯一相关的是第三个结果:Windows 版 NtfsProgs - GnuWin32 - SourceForge,结果显示这是一个 2004 年的老程序,下载时缺少 libintl3.dll 和 libiconv2.dll。将 .dll 粘贴到文件夹后,它不起作用:
PS C:\Users\Xeni> C:\Users\Xeni\Downloads\ntfsprogs-1.9.0-bin\bin\ntfscluster.exe -I 154681282 D:
Failed to set locale, using default '(null)'.
win32_io.c(199): ntfs_device_win32_open The handle is invalid.
ioctl failed
Couldn't mount device 'D:': Invalid argument
NTFSInfo 来自系统内部似乎没有提供通过文件记录段。
在寻找替代品后,我发现nfi.exe
它更古老,是 1999 年的!它确实有效:
PS C:\Users\Xeni> nfi.exe D: 0x937950
NTFS File Sector Information Utility.
Copyright (C) Microsoft Corporation 1999. All rights reserved.
***Logical sector 9664848 (0x937950) on drive D is in file number 312188.
\Games\SPACEE~1\data\textures\galaxies\GALAXI~1.PAK
$DATA (nonresident)
logical sectors 8738944-10045631 (0x855880-0x9948bf)
但它需要逻辑扇区号作为参数而不是文件记录段:
PS C:\Users\Xeni> nfi.exe /?
NTFS File Sector Information Utility.
Copyright (C) Microsoft Corporation 1999. All rights reserved.
Dumps information about an NTFS volume, and optionally determines
which volume and file contains a particular sector.
Usage: D:\CliExec\nfi.exe drive-letter [logical-sector-number]
Drive-letter can be a single character or a character followed
by a colon (i.e., C or C: are acceptable).
Logical-sector-number is a decimal or 0x-prefixed hex
number, specifying a sector number relative to the volume
whose drive letter is given by drive-letter. If not
specified, then information about every file on the volume
is dumped.
D:\CliExec\nfi.exe NT-device-path physical-sector-number
Determines which volume a given physical sector on a drive is
within, and then which file on the volume it is in.
NT-device-path is the NT-style path to a physical device.
It must not include a partition specification.
Physical-sector-number is a decimal or 0x-prefixed hex
number, specifying a sector number relative to the physical
drive whose device path is given by NT-device-path.
D:\CliExec\nfi.exe full-win32-path
Dumps information about a particular file. full-win32-path
must start with a drive letter and a colon.
我想逻辑扇区号和文件记录段是同一件事,但看起来它们并不是:
PS C:\Users\Xeni> fsutil fsinfo ntfsInfo D:
NTFS Volume Serial Number : 0xfc2bea5043264555
NTFS Version : 3.1
LFS Version : 2.0
Total Sectors : 7,810,824,157 ( 3.6 TB)
Total Clusters : 976,353,019 ( 3.6 TB)
Free Clusters : 275,935,695 ( 1.0 TB)
Total Reserved Clusters : 36,875 (144.0 MB)
Reserved For Storage Reserve : 0 ( 0.0 KB)
Bytes Per Sector : 512
Bytes Per Physical Sector : 512
Bytes Per Cluster : 4096
Bytes Per FileRecord Segment : 1024
Clusters Per FileRecord Segment : 0
Mft Valid Data Length : 2.14 GB
Mft Start Lcn : 0x0000000000000002
Mft2 Start Lcn : 0x000000000a31f5fd
MFT Zone Size : 200.13 MB
Max Device Trim Extent Count : 0
Max Device Trim Byte Count : 0
Max Volume Trim Extent Count : 62
Resource Manager Identifier : E548A579-8A28-11EB-BA87-F4B52033630B
看起来文件记录段是 1024 字节,逻辑扇区号是 512 字节,所以也许我需要将数字翻倍才能获得实际引用的文件。但这很可能是错误的,因为簇号非常高。
那么我实际上如何通过文件记录段识别文件呢?
更新
我使用了一些 Google-fu,并想出了这个残酷的搜索关键字:"file record segment" -unreadable -fix -corrupt
我终于找到了有用的东西:
文件记录段:主文件表中的记录,包含 NTFS 卷上特定文件的属性。文件记录段的大小始终为 1,024 字节 (1 千字节)。
仅包含关键信息的两句话。就是这样。结果是最佳结果,其他所有结果均无关紧要。
现在我需要找到一种方法来以编程方式查询主文件表,并希望我不会意外破坏它,这相当于更加徒劳的 Google 搜索......
答案1
我看到您已经发现 LBA 扇区号与文件记录段的关系为零。
所以:
十六进制地址有 3 种类型,称为“文件记录段”、“文件”和“簇”。
MFT 基本上由 1024 个字节的编号记录组成。编号是您的文件记录段 (FRS)。此编号与文件相同。
(来源:https://flatcap.github.io/linux-ntfs/ntfs/concepts/file_record.html)
簇是分配给文件的实际扇区组。扇区是 LBA 地址,从 0 开始计数 = 物理驱动器的第一个扇区。簇从 0 开始计数 @ 卷或文件系统的第一个扇区。因此,要将簇号转换为 LBA 扇区地址,我们需要 LBA 偏移量到卷 + (簇 * (每个簇的扇区数))
我从文件恢复的角度来处理这个问题,因为这就是我所做的,所以我使用 CreateFile 打开驱动器,解释引导扇区以找到 MFT(MFT 第一个簇与簇因子(每个簇的扇区数)一样给出)。MFT 是自引用的,所以第一个 FRS 为我们提供分配给 MFT 的所有簇,然后我从那里“解析”文件记录段并将关键信息填充到数组中。FRS 197571 只是第 197571 个数组元素,您可以从中确定文件名。
当然,这只给您一个文件名,要确定完整路径,您需要解析 $File_Name 属性来确定“父级”,转到该 FRS,确定文件名等。
最好的在线资源是:https://flatcap.github.io/linux-ntfs/ntfs/
DMDE 是一款查看 RAW 数据和 FRS 等解释数据的绝佳工具(更多示例说明那):
也许更直接的方法是,虽然我从未尝试过,但通过文件 ID 打开文件: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfilebyid?redirectedfrom=MSDN,更多提示@https://www.codeproject.com/Questions/273746/Given-an-NTFS-File-ID-is-there-any-official-way-to