NTFS 目录上的 CreateFile 在 ReadFile 上失败

CreateFile on Directory in NTFS fails on ReadFile

据说可以实际打开和读取 NTFS 卷上的目录。但是,我尝试此操作的代码不起作用,所以我尝试了 google,它找到了我 this.

这里的关键观察结果似乎是您必须使用 FILE_FLAG_BACKUP_SEMANTICS。所以,把它剪下来,我基本上得到:

HANDLE hFile = CreateFile(L"C:\temp", GENERIC_READ, FILE_SHARE_READ,
    0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);

DWORD dwFileSize = GetFileSize(hFile, 0);
char* buf = new char[dwFileSize];

DWORD dwBytesRead = 0;
BOOL b = ReadFile(hFile, buf, dwFileSize, &dwBytesRead, 0);

看起来很简单。不幸的是,它不起作用。

CreateFileGetFileSize 都有效(句柄不是 INVALID_HANDLE_VALUE,非零且合理的文件大小),但 ReadFile returns FALSE,dwBytesRead 为零,GetLastError returns 1 ("Incorrect function")。嗯

当我输入这个问题时,'Similar Questions' 提示显示 this. That business about using AdjustTokenPrivileges made a lot of sense. However, it didn't help. Adding ReadFile (and using c:\temp) to that example gives the same behavior. A closer reading of the CreateFile docs 显示即使没有 SE_BACKUP_NAME 权限,由于管理员权限,我应该能够打开文件.

我尝试了多种排列方式:

我(目前)正在尝试 152 个排列,并且 none 的 ReadFiles 正在工作。我错过了什么?

我原来的假设不正确吗?从目录中 'read' 真的不可能吗?还是我仍然缺少一些技巧?

我还应该提到什么?

如果要打开流,则需要在路径中包含流名称 and/or 类型:

  • c:\foo:barA.K.A。 c:\foo:bar:$DATA
  • c:\foo::$INDEX_ALLOCATION

如果您不指定流,则使用默认的 $DATA 流。 $DATA 存储一个文件 "normal data".

如果你想要目录中的文件列表,那么你可以使用 GetFileInformationByHandleEx(FileIdBothDirectoryInfo)(在旧系统上使用 NtQueryDirectoryFile)。

看来乔纳森·波特给出了正确答案。尽管有提示,他还是选择不 post 他的评论作为答案。因此,我将根据他的回答创建一个以结束问题。

简而言之:"You can open a handle to a directory to do certain things, but calling ReadFile on it isn't one of them."

什么东西? These things。此列表包括:

  • 备份读取
  • 备份搜索
  • 备份写入
  • 通过句柄获取文件信息
  • 获取文件大小
  • 获取文件时间
  • 获取文件类型
  • ReadDirectoryChangesW
  • 设置文件时间

总结:虽然您可以 "open" 目录和 "read" 关于它们的某些信息,但实际上您不能使用 ReadFile。如果您想阅读 DirName::$INDEX_ALLOCATION 信息,则必须使用不同的方法。