C++ 如何使用WinApi/USN/MasterFileTable为所有磁盘中的所有文件提供唯一ID?

C++ 如何使用WinApi/USN/MasterFileTable为所有磁盘中的所有文件提供唯一ID?,c++,winapi,filesystems,ntfs,usn,C++,Winapi,Filesystems,Ntfs,Usn,我正在使用NTFS MasterFileTable/USN日志,其中包含一些磁盘/分区(C:,D:,E:,F:,等等),我希望为每个文件/目录使用唯一的ID 当我阅读(也称为PUSN_记录)时,有一个int64: DWORDLONG FileReferenceNumber; 这是唯一的文件/目录标识符,至少在当前分区中是唯一的 但可能存在冲突: C:中的文件可能有FileReferenceNumber 1932847 D:中的另一个文件可能也有FileReferenceNumber

我正在使用NTFS MasterFileTable/USN日志,其中包含一些磁盘/分区(C:,D:,E:,F:,等等),我希望为每个文件/目录使用唯一的ID

当我阅读(也称为PUSN_记录)时,有一个int64:

DWORDLONG     FileReferenceNumber;
这是唯一的文件/目录标识符,至少在当前分区中是唯一的

但可能存在冲突:

  • C:中的文件可能有FileReferenceNumber 1932847
  • D:中的另一个文件可能也有FileReferenceNumber 1932847
我希望避免使用像
int128
这样的大东西(即
FileReferenceNumber
+5位的驱动器号C:,d:,E:,…,Z:)

我还希望避免使用成对的
(char DriveLetter,DWORDLONG FileReferenceNumber)
来识别计算机中的文件

如何使用64位整数编码
文件引用编号
+驱动器号?

可能是因为
FileReferenceNumber
有一些空闲的未使用位吗?


如果没有,您将如何处理此问题?

您必须使用一对FileReferenceNumber/FileID和“volume something”。您可以这样做,这样您就不能真正使用驱动器号

理想情况下,“volume something”是最重要的,但如果大小很重要,可以使用卷序列号。注意:并非所有卷都有GUID


对于NTFS,您可以从中获取并构建32位+64位对。对于ref,您需要并构建一个64位+128位对。

只是为了确保:假设我正在枚举
\\的MasterFileTable(
FSCTL\u ENUM\u USN\u DATA
)。\C:
。我将只拥有此卷/分区中文件的FileReferenceNumber,而不是C:\MOUNTEDFOLDER\(如果这是另一个卷,在C中作为文件夹装入),对吗?到目前为止,我使用的是map
std::map
,其中键是
FileReferenceNumber
s,即int64。所以这是非常有效的。如果现在我必须使用成对(卷、文件ID)作为映射键,那么速度会慢得多,你不这么认为吗@Anders?使用整数作为映射键肯定更快。使用卷序列号是相当安全的,但只有GUID保证是唯一的AFAIK。我不知道FSCTL_ENUM_USN_数据的细节,但是如果它在MFT上运行,那么它不应该返回已装入卷的条目,只返回装入卷的文件夹。(这两种方法都很容易测试)。如果性能是一个问题,那么每个卷可以有一个映射,而不是一个使用对作为键的映射。@HarryJohnston我也是这么想的,但在搜索时,它会在卷上添加另一个循环,这在代码的美观方面很烦人;)请注意,使用驱动器号并不一定足够;您可以在同一驱动器号下装入多个卷。@HarryJohnston如何安装?你能举个例子吗?什么是具体的例子?我不知道你在这里所说的“具体”是什么意思。但是我负责一些硬盘上有三个分区的计算机;一个是隐藏的“系统”分区,第二个是C驱动器,第三个安装在
C:\some\path\mount
上。正如安德斯所说,如果你从一个卷中读取MFT,那么你当然只能从该卷中获取条目。因此,在您的情况下,我想唯一的潜在问题是,如果您将自己限制为具有驱动器号的卷,则可能不会包括所有存在的卷。