假设可以实际打开和读取 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:\temp
、c:\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 卷
- 外面多云(嘿,你永远不知道什么是重要的......)