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文件系统硬链接添加到文件或目录中或从中删除。 类似于POSIX硬链接的NTFS文件系统硬链接是看到相同文件或目录的几个目录条目之一。

这是什么意思? 硬链接创build在哪里? 还是被删除? 我如何获得更多关于发生的事情的信息?

我知道这是古老的,但是在研究相关问题的时候,我偶然发现了这一点。 以下是我发现的:阅读USN时,硬链接是一个复杂的因素。 您可以通过通过任何已创建的硬链接进行的更改来获取将日记条目描述为单个文件引用号的更改。 一般而言,对于原始问题, 硬链接是可以通过其访问单个文件的备选目录条目 。 因此,所有文件的特征都为每个链接共享(名称和父文件引用号除外)。 从技术上讲,你不能说出哪个是原始的,哪个是链接。

存在细微的差异,并且如果查询主文件表(使用DeviceIOControl和Fsctl_Enum_Usn_Data),则会出现这种差异。 查询将只返回一个代表文件,而不管有多少链接。 您可以使用NtQueryInformationFile查询链接,查询FILE_HARD_LINK_INFORMATION。 我认为MFT查询返回的条目是主条目,NtQueryInformationFile返回的条目是链接…但是,主条目可以被删除,其中一个链接将被提升…所以它只是一个家务管理思想还有一点点

请注意,其中一个硬链接被移动或重命名时出现问题。 在这种情况下,重命名或移动的日记条目反映受影响的链接的文件名和父文件引用号。 如果您仅要求总结“关闭”记录,则会出现问题。 在这种情况下,您永远不会看到USN_REASON_RENAME_OLD_NAME记录…因为该USN条目永远不会获得与其关联的REASON_CLOSE。 没有这个珍闻,你将无法轻易确定哪个链接的名称或位置发生了变化。 您必须在Read_Usn_Journal_Data_V0中将ReadOnlyOnClose设置为0来读取usn。 这是一个非常烦人的查询,但没有它,你不能准确地将这个变化与一个链接或另一个链接联系起来。

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

当最后一个文件的硬链接被删除时,文件被删除; 所以如果最后的硬链接已经被删除,你应该看到USN_REASON_FILE_DELETE而不是USN_REASON_HARD_LINK_CHANGE。 我相信每个引用号是指一个文件(或目录,但NTFS不支持到AFAIK的多个硬链接),而不是硬链接。 因此,在记录事件之后,至少文件引用号应该仍然有效,并指向文件的另一个名称。

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

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

有一些希望,我们可以做得比这更好:事件记录中的文件名和/或ParentFileReference数字可能指的是创建或删除的硬链接,而不是任意链接到文件。 在这种情况下,除了特定事件是否为创建或删除之外,您将获得关于事件顺序的所有相关信息,您应该能够通过查看文件的当前状态并向后记录。

我假设你已经查找了可能包含附加信息的附近更改记录? 例如,在创建硬链接时不会生成USN_REASON_RENAME_NEW_NAME记录,而在删除硬链接时不会生成USN_REASON_RENAME_OLD_NAME记录? 或配对USN_REASON_HARD_LINK_CHANGE记录,一个用于文件,一个用于包含受影响的文件的硬链接的目录? (我的期望值得一想,但看起来不会有什么伤害的!)

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