问题标签 [ntfs-mft]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
file - 了解 NTFS 中的 $ATTRIBUTE_LIST
我正在检查 NTFS(新技术文件系统)并陷入了一个循环,试图找出 $ATTRIBUTE_LIST 属性。在本文档中,遇到 $ATTRIBUTE_LIST 是不常见的,它们仅在 MFT 表空间不足时使用。但是,通过查看以下解析器,我发现他们确实解析了它:
- Ntfs文件提取器
- 由 icaleo 提供的 ntfs
- zenwinx
- JkDefrag v3.36 源代码(使用谷歌搜索找到)
通过查看这些,我提出了以下流程图:
(“Has $ATTRIBUTE_LIST”右边应该有一个yes)
我想参考流程图右侧的2个过程。是否正确:
- 仅当 FRN 与包含属性列表 FRN 的文件不同时才解析该属性?
- 属性被添加到文件中,其 FRN 列在属性中,而不是 FRN 包含属性列表?或者,属性中列出的 FRN 是否仅用于此文件记录的属性(而不是真正的文件)?
c++ - 加速 NTFS 文件枚举(使用 FSCTL_ENUM_USN_DATA 和 NTFS MFT / USN 日志)
我通过查看 NTFS MFT / USN 日志来枚举 NTFS 硬盘分区的文件:
FindFirstFile
它有效,它比通常的枚举技术快得多。但我认为它还不是最优的:
在我的 700k 文件
C:\
中,需要 21 秒。(此措施必须在重启后进行,否则会因为缓存不正确)。我见过另一个索引软件(不是 Everything,另一个)能够
C:\
在 < 5 秒内(在 Windows 启动后测量)进行索引,而无需读取 .db 文件中预先计算的数据库(或其他可以加快速度的类似技巧! )。本软件不使用FSCTL_ENUM_USN_DATA
,而是使用低级 NTFS 解析。
我试图提高性能的方法:
使用另一个标志打开文件,例如
FILE_FLAG_SEQUENTIAL_SCAN
,FILE_FLAG_RANDOM_ACCESS
或FILE_FLAG_NO_BUFFERING
: 相同的结果: 21 秒读取查看Estimate the number of USN records on NTFS volume,为什么在 VB.NET 中使用 DeviceIoControl 进行文件枚举比在 C++ 中更快? 我已经深入研究过它们,但它并没有为这个实际问题提供答案。
测试另一个编译器:MinGW64 而不是 VC++ Express 2013:相同的性能结果,没有区别
在 VC++ 上,我已经切换到
Release
而不是Debug
:是否有其他项目属性/选项可以加快程序的速度?
问题:
是否有可能提高性能DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, ...)
?
或者是提高性能的唯一方法是对 NTFS 进行低级手动解析?
注意:根据测试,DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, ...)
我的 700k 文件在这些过程中要读取的总大小仅为84MB。读取 84MB 的 21 秒仅为 4 MB/秒(我确实有 SSD!)。可能还有一些性能提升的空间,你不这么认为吗?
c++ - 在执行 FSCTL_ENUM_USN_DATA 之前了解文件/目录的数量
在进行 USN 日志/NTFS MFT 文件枚举之前
我想知道文件/目录的数量(“保留”一个 std::vector:v.reserve(...)
以及其他原因)。
我FSCTL_QUERY_USN_JOURNAL
之前考虑过使用,它提供了USN_JOURNAL_DATA_V0
有关音量的包含信息。
不幸的是,FirstUsn
不要提供此信息。即使我的卷上有 100k 个文件,例如可以是 1000 万个,所以它没有给出正确的数量级。NextUsn
MaxUsn
NextUsn
如何在执行 FSCTL_ENUM_USN_DATA 之前获取文件/目录的数量?
c# - 枚举 NTFS MFT:FSCTL_ENUM_USN_DATA 和 USN_RECORD_V3 支持
我正在使用FSCTL_ENUM_USN_DATA枚举 NTFS MFT,以便我可以基于 USN_RECORD FileReferenceNumbers 构建目录数据库。我正在构建这个数据库,以便我可以通过使用 NTFS USN 更改日志并读取 USN_RECORD(使用引用目录数据库的 FileReferenceNumber 和 ParentFileReferenceNumber)来监视 NTFS 驱动器上的文件更改。有关执行此操作的信息,请参见此处。
我的问题与 USN Record 版本有关。如果您看一下,USN_RECORD_V2支持的 FileReferenceNumbers (DWORDLONG) 数据类型与USN_RECORD_V3 (FILE_ID_128) 不同。这很好,如果 FSCTL_ENUM_USN_DATA 支持 USN_RECORD_V3。问题是在 Windows 10 中使用了 USN_RECORD_V3,而在 Windows 7 中使用了 USN_RECORD_V2。
FSCTL_ENUM_USN_DATA 将MFT_ENUM_DATA_V1或MFT_ENUM_DATA_V0作为其输入缓冲区。我假设 V1 支持 FILE_ID_128 FileReferenceNumbers,但事实证明这个假设是不正确的。似乎不支持 USN_RECORD_V3 及其关联的 FileReferenceNumber 数据类型。因此,在使用 USN_RECORD_V3 或更高版本的 Windows 版本上使用 NTFS 更改日志监视 NTFS 驱动器上的更改现在是一个大问题。
我找到了一个临时解决方案!在 Windows 10 上枚举 MFT 时,FSCTL_READ_ENUM_DATA 仅返回 USN_RECORD_V2,给出 DWORDLONG 类型的 FileReferenceNumbers。反过来,我被迫将这些 DWORDLONG FileReferenceNumbers 移位到 128 位缓冲区中,以便目录缓存与FSCTL_READ_USN_JOURNAL调用返回的 USN_RECORD_V3 匹配。
然而,我不禁觉得我错过了一些东西。有没有人对此问题有任何其他解决方案,或者可以采取任何替代方法?请记住,监视程序未运行时对驱动器所做的更改对于我的项目至关重要。
filesystems - FAT 和 NTFS 文件系统比较说明
我开始研究文件系统,尤其是 FAT* 和 NTFS。
在 FAT 文件系统中,簇可能是 Data 或 Directory 簇,并且根目录的起始簇号始终是已知的,因为在 FAT32 之前它在格式化时是固定的,并且与 FAT32 一样,在引导的扩展 BIOS 块中可以找到部门。
另一方面,NTFS 组织主文件表下的所有内容,并为系统中的每个文件和目录提供 MFT 记录。主文件表的第 27 个位置标记为保留,第一个索引由 $MFT 记录组成,它描述了 MFT 本身。
我了解 NTFS 如何通过常驻/非常驻数据属性跟踪数据,而 FAT 使用目录条目来查找集群链的第一个集群并参考文件分配表进行进一步处理。
现在我的头脑发现很难“处理”这些事情。
我在哪里可以找到 NTFS 中的根目录?
MFT 记录中的目录如何表示?常驻和非常驻方式,如何通过当前 MFT 记录找到子目录 MFT 记录?
如果 MFT 记录后半部分中指定的集群运行超出 1024 字节限制怎么办?(我理解这意味着一个严重碎片化的文件)
windows - 在 Windows Server 2008、2012 等中进行卷克隆后,操作系统分区以 RAW 格式出现
我在磁盘克隆上遇到问题。(即)克隆完成后,操作系统分区将作为 RAW 而不是 NTFS 文件系统出现。
我使用FSCTL_GET_VOLUME_BITMAP设备 IO 控制 API 来获取音量位图缓冲区。使用此卷位图,我只从源磁盘克隆了使用过的集群,并写入目标磁盘的相同偏移量。在空闲簇位置保持原样。
仅使用集群克隆会导致任何问题吗?
体积位图中的常驻和非常驻内容是否正确?因为我没有考虑非常驻属性。简单地说,我使用以下代码克隆了只使用过的集群。
我只在 Windows 服务器计算机上遇到这个问题。
请任何人提出解决我问题的方法。找到下面的代码片段。
查找使用过的集群
获取音量位图:
hex - 索引记录之间的最后一个索引条目,但资源管理器仍然能够显示所有文件
我正在为 NTFS 文件系统编写解析器。我有一个关于 INDX 记录的问题。我已经浏览了 stackoverflow 问题“NTFS 硬盘上 $I30 的 INDX 条目无效”以及其中提供的链接。请参考下图。
在解析INDX记录时,当我们遇到字节序列
00 00 00 00 00 00 00 00 10 00 00 00 02 00 00 00
文档时,表明应该将其视为索引条目列表的最后一个条目。但是,正如您所见,在此之后还有更多条目,Windows 资源管理器会显示所有条目。我无法在 ;last 条目之后继续解析,因为后续条目的结构与 INDX 条目记录的规定结构不匹配,如下所示。请建议我是否在这里遗漏任何内容以及如何解决。
winapi - LockFileEx 可以与卷句柄一起使用吗?
我正在试验FSCTL_MOVE_FILE
. 大多数情况下,一切都按预期工作。但是,有时如果我尝试重新读取(通过FSCTL_GET_NTFS_FILE_RECORD
)我刚刚移动的 Mft 记录,我会得到一些错误的数据。
具体来说,如果文件记录说 $ATTRIBUTE_LIST 属性是非常驻的,我使用我的卷句柄从磁盘读取数据,我发现那里的数据内部不一致(记录长度大于数据的实际长度) .
我一看到这种情况,原因就很清楚了:我在 Ntfs 驱动程序完成写入之前读取记录。调试支持这一理论。但是知道这并不能帮助我解决它。我正在使用同步方法进行FSCTL_MOVE_FILE
调用,但显然文件系统仍然可以在后台更新内容。唔。
在普通文件中,我会考虑LockFileEx
使用共享锁(因为我只是在阅读)。但我不确定这对音量句柄有什么意义?而且我更不确定 Ntfs 在内部使用这种机制来确保一致性。
不过,这似乎是一个开始的地方。但是我LockFileEx
对音量句柄的调用正在返回ERROR_INVALID_PARAMETER
。我没有看到哪个参数可能出错,除非它是音量句柄本身。也许他们只是不支持锁?CreateFile
或者也许在打开音量手柄时我应该设置一些特殊的标志?我尝试启用SE_BACKUP_NAME
and FILE_FLAG_BACKUP_SEMANTICS
,但错误保持不变。
展望未来,我可以在这里看到一些替代方案:
- 弄清楚如何使用卷句柄锁定部分(并希望 Ntfs 驱动程序也这样做)。在这一点上似乎很可疑。
- 弄清楚如何刷新我刚刚移动的文件的元数据(nb:MOVE_FILE_DATA.FileHandle 的 FlushFileBuffers 没有帮助。也许刷新卷句柄?)。
- 是否有一些“官方”方法可以读取不涉及
ReadFile
卷句柄的非常驻数据?我没有找到,但也许我错过了。 - 移动数据后稍等片刻,让驱动程序完成更新所有内容。呸。
FWIW,这是一些针对卷句柄执行 LockFileEx 的测试代码。请注意,您必须以管理员身份运行才能锁定卷句柄。我正在使用J:
,因为那是我的闪存驱动器。50000 是随机挑选的,但应该小于闪存驱动器的大小。
查看坏数据的代码……相当复杂。然而,它很容易重现。当它失败时,我最终尝试读取长度为“0”的可变长度 $ATTRIBUTE_LIST 条目,这会导致无限循环,因为看起来我从未完成读取整个缓冲区。如果长度为零,我正在通过退出来解决它,但我担心缓冲区中的“剩余垃圾”而不是干净的零。检测到这是不可能的,所以我希望有更好的解决方案。
毫不奇怪,关于这方面的信息并不多。因此,如果有人在这里有一些经验,我可以使用一些见解。
编辑1:
更多不太有效的事情:
- LockFileEx 仍然没有运气。
- 我尝试冲洗音量手柄(如保罗建议的那样)。虽然这有效,但它使我的执行时间增加了一倍以上。而且,严格来说,它仍然不能解决问题。仍然不能保证 Ntfs 不会在 FlushFileBuffers 和 FSCTL_GET_NTFS_FILE_RECORD / ReadFile 之间做出更多改变。
- 我想知道 $STANDARD_INFORMATION 属性的“RecordChanged”时间戳。但是,由于对 ATTRIBUTE_LIST 的这些更改,它没有被更改。
- 对文件进行分段最终会导致添加一个 ATTRIBUTE_LIST,并且随着分段的不断增加,更多的 DATA 记录将添加到该列表中。添加 DATA 记录后,UpdateSequenceNumber(不是 MFT_SEGMENT_REFERENCE 的一部分,另一个)会更新。不幸的是,有一系列事件可以执行此更新。显然,ATTRIBUTE_LIST 缓冲区“长度”在“UpdateSequenceNumber”之前更新。因此,查看“UpdateSequenceNumber”是否已更改无助于避免读取(可能)错误信息。
我的下一个最佳想法是看看 Ntfs 是否总是在更新记录长度之前将新字节归零(或者可能每当记录长度缩小时?)。如果我可以依赖记录长度为零(而不是任何剩余数据可能占用这些字节),我可以假装称之为固定。
filesystems - NTFS 更改日志 - 文件更改跟踪
我正在开发一个更改跟踪软件来监视特定卷的文件。我尝试了 FileSystemWatcher (.NET) 和 AlternateDataStreams,但它们都有一些限制(即,更改跟踪软件必须 24/7,备用数据流不能用于 ReadOnly 文件等)。
经过一番调查,我认为我可以直接阅读 NTFS 更改日志。如果在同一卷上移动/重命名文件等,这将非常有用。为了识别文件,我使用了文件参考号。
但是如果文件被移动到另一个卷,文件参考号自然会改变。
我的问题:是否有一个唯一的 ID(GUID 或其他东西)即使文件移动到另一个卷也不会改变?
python - NTFS 是否存储每个 inode/文件的哈希或 CRC32,如何访问它?
我知道如何读取文件,将这些字节传递给哈希算法,例如 MD5SUM、SHA256 或 CRC32,然后获取哈希。
在这里,我要问一些稍微不同的问题:
每次我们在 NTFS 分区上写入/修改文件时,它是否会重新计算哈希或 CRC32 并将此信息存储在 NTFS 元数据/FAT/MFT(主文件表)中(我不记得确切的名称)?
注意:重要的是我只想读取存储在文件系统中的存储哈希/CRC(即读取几个字节,最多应该是几毫秒),而不是重新计算哈希(对于 10 GB 文件)。
如果是这样,如何使用 Python 访问特定文件的 CRC 或哈希?有没有类似的东西: