【问题标题】:ReadFile on volume fails with ERROR_INVALID_PARAMETER after FSCTL_ALLOW_EXTENDED_DASD_IO在 FSCTL_ALLOW_EXTENDED_DASD_IO 之后,卷上的 ReadFile 失败并显示 ERROR_INVALID_PARAMETER
【发布时间】: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,然后ReadFilelenToBeRead = 0x1000 上以ERROR_INVALID_PARAMETER 失败。我完全忘记了第一个修复程序,现在记住了,现在它可以工作了。

【问题讨论】:

  • ERROR_INVALID_PARAMETER 更快,因为您尝试读取的lenToBeRead 或文件偏移量无效。但是您没有显示此数据
  • 您确定您要读取的扇区确实存在吗?当您尝试从物理驱动器而不是逻辑卷读取同一扇区时会发生什么?
  • @RbMm 就是这样。我忘了剪掉lenToBeRead 以适应剩余空间。我已编辑我的问题以添加此数据。谢谢。

标签: winapi readfile


【解决方案1】:

我找到了解决方案并将其添加到问题正文中。 使用ReadFile 时必须记住的是控制参数(长度)不跨越文件的边界。 在做FSCTL_ALLOW_EXTENDED_DASD_IO 之前,我曾尝试将其作为修复,但没有帮助。但是FSCTL_ALLOW_EXTENDED_DASD_IO 和边界检查的结合给了我想要的结果——我可以读取最后一个字节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多