NTFS期刊USN_REASON_HARD_LINK_CHANGE事件



我编写了一个程序来读取NTFS索引和日志,类似于这里描述的内容:
http://ejrh.wordpress.com/2012/07/06/using-the-ntfs-journal-for-backups/而且效果相当不错。
除了正常的日记事件USN_REASON_CLOSEUSN_REASON_FILE_CREATEUSN_REASON_FILE_DELETE等,我收到一个原因USN_REASON_HARD_LINK_CHANGE的事件。我希望能够根据此事件更新目录索引,但我找不到有关它的任何信息。唯一的文档是:

NTFS 文件系统硬链接添加到文件或从文件中删除,或 目录。NTFS 文件系统硬链接,类似于 POSIX 硬链接 链接,是看到同一文件或 目录。

这是什么意思? 硬链接是在哪里创建的? 还是被删除了? 如何获取有关所发生情况的更多信息?

我知道

这是古老的,但我在研究相关问题时偶然发现了这个。 以下是我的发现:在阅读USN时,硬链接是一个复杂的因素。 您可以通过创建的任何硬链接所做的更改来获取描述对单个文件参考编号的更改的日记帐分录。 通常,对于原始问题,硬链接是可以访问单个文件的替代目录条目。 因此,每个链接共享文件的所有特征(名称和父文件参考编号除外)。 从技术上讲,您无法分辨哪个条目是原始条目,哪个是链接。

确实存在细微的差异,如果您查询主文件表(使用 DeviceIOControl 和 Fsctl_Enum_Usn_Data),则会表现出来。 无论存在多少个链接,查询都将仅返回一个代表性文件。您可以使用 NtQueryInformationFile 查询链接,查询FILE_HARD_LINK_INFORMATION。 我认为MFT查询返回的条目是主条目,而NtQueryInformation文件返回的项目是链接...但是,主条目可能会被删除,其中一个链接将被提升......所以这只是一个管家的想法,别无他物。

请注意,移动或重命名其中一个硬链接时会出现问题。 在这种情况下,重命名或移动的日志条目反映了受影响链接的文件名和父文件参考号。 如果您仅要求摘要"关闭"记录,则会出现问题。在这种情况下,您将永远不会看到USN_REASON_RENAME_OLD_NAME记录...因为该 USN 条目永远不会获得与其关联的关联REASON_CLOSE。 如果没有这个花絮,您将无法轻松确定哪个链接的名称或位置已更改。 您必须读取 usn,并将 ReadOnlyOnClose 设置为 Read_Usn_Journal_Data_V0 0。 这是一个更健谈的查询,但如果没有它,您无法准确地将更改与一个链接或另一个链接相关联。

与USN一样,我希望您需要经历一些试验和错误才能使其正常工作。 我希望这些观察/猜测可能会有所帮助:

删除文件的最后一个硬链接

时,该文件将被删除;因此,如果最后一个硬链接已删除,则应看到USN_REASON_FILE_DELETE而不是USN_REASON_HARD_LINK_CHANGE。 我相信每个参考编号都是指一个文件(或目录,但NTFS不支持指向目录AFAIK的多个硬链接)而不是硬链接。 因此,至少在记录事件后,文件参考编号应立即仍然有效,并指向文件的另一个名称。

如果文件仍然存在,您可以按参考编号查找,并使用FindFirstFileNameW和朋友查找当前链接。 将此与有问题的事件记录以及任何相关的后续事件进行比较应该会为您提供足够的信息,但如果删除和/或创建了同一文件的多个硬链接,您可能无法重建发生这种情况的顺序,并且如果您没有足够的关于文件系统先前状态的信息,您可能无法识别已删除的硬链接。 我不知道这对你来说是否重要。

如果该文件不再存在,您仍应能够通过删除该文件的 USN 记录来识别它。 同样,考虑到所有相关事件,并有足够的关于先前状态的信息,你应该能够重建大部分发生的事情,如果不是顺序的话。

有一些

希望我们可以做得更好:事件记录中的文件名和/或 ParentFile参考号可能是指已创建或删除的硬链接,而不是指向该文件的任意链接。 在这种情况下,您将拥有有关事件序列的所有相关信息,除了任何特定事件是创建还是删除,您应该能够通过查看文件的当前状态并反向处理记录来计算这些信息。

我假设您已经查找了可能包含其他信息的附近更改记录? 例如,创建硬链接时没有生成USN_REASON_RENAME_NEW_NAME记录,删除硬链接时没有USN_REASON_RENAME_OLD_NAME? 还是成对USN_REASON_HARD_LINK_CHANGE记录,一个用于文件,一个用于包含受影响的文件硬链接的目录? (我期待是一厢情愿的想法,但看起来不会有什么坏处!

出于测试目的,您可以使用 mklink 命令创建硬链接。

相关内容

  • 没有找到相关文章