FSCTL_ALLOW_EXTENDED_DASD_IO 后,卷上的 ReadFile 失败并显示 ERROR_INVALID_PARAMETER

ReadFile on volume fails with ERROR_INVALID_PARAMETER after FSCTL_ALLOW_EXTENDED_DASD_IO

我正在使用 ReadFile 读取卷(逻辑驱动器)。我将 DeviceIoControl 与 FSCTL_ALLOW_EXTENDED_DASD_IO 代码一起使用,因为我想访问所有(包括最后一个)字节并且在尝试读取最后 512 个字节时遇到问题(ReadFile 成功,但报告读取了 0 个字节)并看到了使用它的建议。不幸的是,ReadFile 在调用 DeviceIoControl 之后失败了。 在代码中它看起来像这样(为简洁起见省略了所有成功检查):

    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 以适应剩余的 space(所以,如果它是 0x1000,它会变成 0x200),因为我发现ReadFile 不能保证在 lenToBeRead 的情况下将所有字节读取到 EOF 大于当前句柄位置剩余的字节数。这没有帮助,ReadFile仍然成功返回并读取了 0 个字节。我删除了该修复程序,然后使用了 FSCTL_ALLOW_EXTENDED_DASD_IO,然后 ReadFilelenToBeRead = 0x1000 上出现 ERROR_INVALID_PARAMETER 失败。我完全忘记了第一个修复程序,现在想起来了。

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