【发布时间】: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