【问题标题】:Cannot Get ReadFile to work with a Physical Drive无法让 ReadFile 与物理驱动器一起使用
【发布时间】:2015-03-08 01:23:15
【问题描述】:

我可以让 ReadFile 读取一个简单的文本文件,但无法让它在物理驱动器上正常工作。我从 GetLastError 收到错误“参数不正确”。我的代码如下并提供了更多信息:

using System;
using System.Runtime.InteropServices;

namespace ReadFileTest
{
class Program
{
    [DllImport("kernel32.dll")]
    static extern unsafe uint GetLastError();

    [DllImport("kernel32", SetLastError = true)]
    static extern unsafe System.IntPtr CreateFile
    (
        string FileName,          // file name
        uint DesiredAccess,       // access mode
        uint ShareMode,           // share mode
        uint SecurityAttributes,  // Security Attributes
        uint CreationDisposition, // how to create
        uint FlagsAndAttributes,  // file attributes
        int hTemplateFile         // handle to template file
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern unsafe bool ReadFile
    (
        IntPtr hFile, 
        [Out] byte[] lpBuffer,
        uint nNumberOfBytesToRead, 
        out uint lpNumberOfBytesRead, 
        IntPtr lpOverlapped
    );

    const uint GENERIC_READ = 0x80000000;
    const uint GENERIC_WRITE = 0x050000000;
    const uint GENERIC_ALL = 0x10000000;
    const uint FILE_SHARE_READ = 1;
    const uint FILE_SHARE_WRITE = 2;

    const uint OPEN_EXISTING = 3;
    const int INVALID_HANDLE_VALUE = -1;

    static void Main(string[] args)
    {
        unsafe 
        {
            // Reading a simple text file works perfectly:
            //IntPtr handle = CreateFile("D:\\Test.txt", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

            // CreateFile of a physical drive gives me a valid handle.
            // But when attempting to read the drive, (all of my drives give the same result), I get the error "The parameter is incorrect."
            IntPtr handle = CreateFile(@"\\.\PHYSICALDRIVE2", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

            // GetLastError returns this:
            // ERROR_INVALID_PARAMETER87 (0x57)
            // The parameter is incorrect.

            byte[] b = { 1, 2, 3, 4, 5 };
            uint n = 1;

            while (n != 0)
            {
                bool ret = ReadFile(handle, b, (uint)5, out n, (IntPtr)0);
                uint e = GetLastError();
            }

        }
    }
}
}

// I have unmounted the physical drive and run the test with the same results.
// I tried using pointers for the parameters, same result.
// I tried different variations of options for CreateFile.
// Don't know which parameter is giving the error.

【问题讨论】:

  • 你是在提升吗? (ISTR普通用户无法直接读取设备。)
  • 旁注:你知道你应该直接使用GetLastWin32Error而不是PInvoke GetLastError吗? (不知道为什么你显示 GetLastError 调用,因为它使样本更长)。
  • 另外,你没有检查ReadFile的结果:成功的API调用并不总是清除错误值。

标签: c# readfile hard-drive drive createfile


【解决方案1】:

我相信5 在从原始设备读取时读取的大小无效 - 应该与某个块大小对齐。像0x1000 这样的东西更有机会成功。

请务必仔细阅读ReadFile 文档。如果您真的要探索低级 API,请考虑阅读“Windows Internals”一书。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 2014-10-31
    相关资源
    最近更新 更多