0

假设可以实际打开和读取 NTFS 卷上的目录。但是,我尝试这个的代码不起作用,所以我尝试了谷歌,它找到了我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);

看起来很直截了当。不幸的是,它不起作用。

CreateFile和两者GetFileSize都有效(句柄不是 INVALID_HANDLE_VALUE,非零且合理的文件大小),但ReadFile返回 FALSE,dwBytesRead 为零,GetLastError 返回 1(“函数不正确”)。嗯。

当我输入这个问题时,“类似问题”提示向我显示了这个。关于使用AdjustTokenPrivileges的业务很有意义。然而,它没有帮助。在该示例中添加 ReadFile(并使用 c:\temp)会产生相同的行为。仔细阅读CreateFile 文档表明,即使没有 SE_BACKUP_NAME 权限,由于管理员权限,我也应该能够打开文件。

我尝试了许多排列:

  • 指定目录名称的不同方式(c:\tempc:\temp\\\.\c:\temp\\?\c:\temp\等)。
  • 不同的目录
  • 不同的驱动器
  • 不同的共享选项(0、FILE_SHARE_READ、FILE_SHARE_READ | FILE_SHARE_WRITE)
  • 不同的访问权限(GENERIC_READ, FILE_LIST_DIRECTORY, FILE_LIST_DIRECTORY + FILE_READ_EA + FILE_READ_ATTRIBUTES, FILE_LIST_DIRECTORY + FILE_READ_EA + FILE_READ_ATTRIBUTES + FILE_TRAVERSE
  • 除了 FILE_FLAG_BACKUP_SEMANTICS (我认为这是必需的)之外,我看不到任何可能适用的标志,但我尝试了 FILE_FLAG_NO_BUFFERING 和 4096 字节对齐的缓冲区。没有。

我(目前)正在尝试 152 种排列,但没有一个 ReadFiles 正在工作。我错过了什么?

我最初的假设是不正确的吗?真的不可能从目录中“读取”吗?还是我仍然缺少一些技巧?

我还应该提到什么?

  • 我以管理员身份运行,并且可以在卷上执行 CreateFile。
  • 我的程序是 64 位的,专为 unicode 构建的。
  • 视窗 7 x64
  • NTFS 3.1 卷
  • 外面多云(嘿,你永远不知道什么是重要的......)
4

2 回答 2

0

如果要打开流,则需要包含流名称和/或类型作为路径的一部分:

  • c:\foo:bar又名c:\foo:bar:$DATA
  • c:\foo::$INDEX_ALLOCATION

如果您不指定流,则使用默认的 $DATA 流。$DATA 存储文件“普通数据”。

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

于 2017-03-08T03:47:18.340 回答
0

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

简而言之:“你可以打开一个目录的句柄来做某些事情,但调用 ReadFile 不是其中之一。”

什么东西? 这些东西。此列表包括:

  • 备份读取
  • 备份搜索
  • 备份写入
  • 按句柄获取文件信息
  • 获取文件大小
  • 获取文件时间
  • 获取文件类型
  • 读取目录更改W
  • 设置文件时间

总结:虽然您可以“打开”目录并“读取”有关它们的某些信息,但实际上不能使用 ReadFile。如果要读取DirName::$INDEX_ALLOCATION信息,则必须使用不同的方法。

于 2017-03-13T03:12:27.677 回答