【发布时间】:2017-11-09 05:41:57
【问题描述】:
我正在读取带有ReadFile 的卷(逻辑驱动器)。我正在使用 DeviceIoControl 和 FSCTL_ALLOW_EXTENDED_DASD_IO 代码,因为我想访问所有(包括最后一个)字节并且在尝试读取最后 512 个字节时遇到问题(ReadFile 成功,但报告读取了 0 个字节)并看到了使用它的建议。不幸的是,在调用DeviceIoControl 之后调用ReadFile 失败。
在代码中它看起来像这样(为简洁起见,省略了所有成功检查):
HANDLE fd;
DWORD junk;
int lenToBeRead = 0x1000;
DWORD nread;
char* alignedBuf = new char[lenToBeRead];
fd = CreateFile("path to volume", FILE_READ_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL)) //success
DeviceIoControl(fd, FSCTL_ALLOW_EXTENDED_DASD_IO,
NULL, 0, NULL, 0, &junk, (LPOVERLAPPED) NULL) //success
ReadFile(fd, alignedBuf, (DWORD) lenToBeRead, &nread, NULL)
// fails with 0x57 code, ERROR_INVALID_PARAMETER
所有使用 fd 句柄的工作都是同步的。
编辑。我解决了这个问题。我试图读取最后一个字节。所以我的成交量是L = 0x...200 的长度,我掌握了pos = L - 0x200 的位置。我在做 FSCTL_ALLOW_EXTENDED_DASD_IO 之前所做的事情 - 我剪切 lenToBeRead 以适应剩余空间(因此,如果它是 0x1000,它将更改为 0x200),因为我发现 ReadFile 不能保证读取在 lenToBeRead 的情况下到 EOF 的所有字节都大于从当前句柄位置剩余的字节数。这没有帮助,ReadFile 仍然成功返回并读取了 0 个字节。我删除了该修复程序,然后使用FSCTL_ALLOW_EXTENDED_DASD_IO,然后ReadFile 在lenToBeRead = 0x1000 上以ERROR_INVALID_PARAMETER 失败。我完全忘记了第一个修复程序,现在记住了,现在它可以工作了。
【问题讨论】:
-
ERROR_INVALID_PARAMETER更快,因为您尝试读取的lenToBeRead或文件偏移量无效。但是您没有显示此数据 -
您确定您要读取的扇区确实存在吗?当您尝试从物理驱动器而不是逻辑卷读取同一扇区时会发生什么?
-
@RbMm 就是这样。我忘了剪掉
lenToBeRead以适应剩余空间。我已编辑我的问题以添加此数据。谢谢。