据说可以实际打开并读取NTFS卷的目录。但是,我尝试尝试的代码不起作用,所以我尝试了Google,找到了我。
关键观察似乎必须使用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,non-Zero和Polausible文件大小),但是ReadFile
返回false,dwbytesRead为零,getLasterRor返回1(" imporcect函数")。嗯。
当我键入这个问题时,"类似的问题"提示向我展示了这一点。使用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个排列,而没有一个读取文件正在工作。我想念什么?
我原来的假设不正确?是否真的不可能从目录中"阅读"?还是我仍然缺少一些技巧?
我还要提及什么?
- 我作为管理员运行,可以在卷上进行createfile。
- 我的程序为64位,为Unicode构建。
- Windows 7 x64
- NTFS 3.1卷
- 外面多云(嘿,你永远不知道有什么重要的...)
如果要打开流,则需要包含流名和/或键入路径的一部分:
-
c:foo:bar
A.K.A.c:foo:bar:$DATA
-
c:foo::$INDEX_ALLOCATION
如果未指定流,则使用默认$数据流。$数据存储文件"普通数据"。
如果您想要目录中的文件列表,则可以使用GetFileInformationByHandleEx(FileIdBothDirectoryInfo)
(以及旧系统上的NtQueryDirectoryFile
)。
看起来乔纳森·波特给出了正确的答案。尽管有提示,他还是选择不发表评论作为答案。因此,我将根据他的回答来创建一个问题,以解决问题。
简而言之:"您可以打开目录的手柄以执行某些事情,但是在上面召集ReadFile并不是其中之一。"
什么?这些东西。此列表包括:
- 备份
- backupseek
- 备份
- getFileInformationByHandle
- getfilesize
- getfiletime
- getFiletype
- ReadDirectoryChangesw
- setfiletime
总结:虽然您可以"打开"目录并"读取"有关它们的某些信息,但实际上不能使用ReadFile。如果要读取 dirname :: $ index_allocation 信息,则必须使用其他方法。