无法获取ReadFile以使用物理驱动器

时间:2015-01-09 16:53:03

标签: c# readfile hard-drive drive createfile

我可以让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.

1 个答案:

答案 0 :(得分:2)

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

请务必仔细阅读ReadFile文档。考虑阅读其中一个版本的" Windows Internals"预订,如果你真的想探索低级API。