P/调用ReadFile不工作(错误87:无效参数)
本文关键字:无效 参数 错误 调用 ReadFile 工作 | 更新日期: 2023-09-27 18:08:37
我正在使用p/Invoke从c#访问原始驱动器。我遇到了一个问题,ReadFile失败,错误87,但我无法找出哪个参数是不正确的:我对我的缓冲区和我正在访问的驱动器都有很好的处理,并且整数参数的类型是正确的。
我把相关的代码放在这里
Also, Here:
从Drive.cs
public Boolean TryOpen(){
.
.
.
_hDrive = FileIO.Methods.CreateFile(
Info.PhysicalPath,
FileIO.FileAccess.GenericRead | FileIO.FileAccess.GenericWrite,
FileIO.FileShare.Read | FileIO.FileShare.Write,
IntPtr.Zero,
FileIO.CreationDisposition.OpenExisting,
FileIO.FileAttributes.NoBuffering | FileIO.FileAttributes.Write_Through | FileIO.FileAttributes.RandomAccess,
IntPtr.Zero);
.
.
.
}
private const Int32 DRIVE_PAGEBUFFER_SIZE = 0x0000FFFF;
private unsafe Boolean _bufferFrom(UInt32 pageIdx)
{
bool success = false;
long retPtr;
uint retBytes;
if (FileIO.Methods.SeekFile(_hDrive, pageIdx * DRIVE_PAGEBUFFER_SIZE, out retPtr, FileIO.FileSeekMethod.FileBegin))
{
_curPageIdx = pageIdx;
if (FileIO.Methods.ReadFile(_hDrive,_pageBuffer, 65535, out retBytes, null))
{
success = true;
}
else
{
Console.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());
//read failed.
}
}
else
{
//seek failed.
}
return success;
}
从FileIO.cs: public static class Methods
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern SafeFileHandle CreateFile(
string lpFileName,
[MarshalAs(UnmanagedType.U4)] FileAccess access,
[MarshalAs(UnmanagedType.U4)] FileShare share,
[Optional] IntPtr security,
[MarshalAs(UnmanagedType.U4)] CreationDisposition disposition,
[MarshalAs(UnmanagedType.U4)] FileAttributes attributes,
IntPtr template
);
[DllImport("kernel32.dll", SetLastError = true)]
public static unsafe extern Boolean WriteFile(
SafeFileHandle hFile,
SafeBuffer lpBuffer,
UInt32 nNumberOfBytesToWrite,
out UInt32 lpNumberOfBytesToWrite,
NativeOverlapped* lpOverlapped
);
[DllImport("kernel32.dll", SetLastError = true)]
public static unsafe extern Boolean ReadFile(
SafeFileHandle hFile,
SafeBuffer lpBuffer,
UInt32 nNumberOfBytesToRead,
out UInt32 lpNumberOfBytesRead,
NativeOverlapped* lpOverlapped
);
[DllImport("kernel32.dll", EntryPoint = "SetFilePointerEx", SetLastError = true)]
public static extern Boolean SeekFile(
[In] SafeFileHandle hFile,
[In] Int64 liDistanceToMove,
[Out] out Int64 lpNewFilePointer,
[In][MarshalAs(UnmanagedType.U4)] FileSeekMethod seekMethod
);
}
从MemBuffer.cs: class MemBuffer:SafeBuffer
{
public MemBuffer(Int32 size):base(true)
{
this.SetHandle(Marshal.AllocHGlobal(size));
this.Initialize((ulong)size);
}
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(this.handle);
return true;
}
}
我已经尝试重新定义ReadFile和WriteFile工作与标准IntPtrs(而不是SafeFileHandle和SafeBuffer),但它没有区别。
我做错了什么?
原始驱动器访问和访问用FILE_FLAG_NO_BUFFERING
(FileIO.FileAttributes.NoBuffering
)打开的文件需要查找到的偏移量是底层设备扇区大小的倍数(通常是512字节或4096字节),并且读写的数量是扇区大小的倍数。
你的代码正在试图寻找是0xFFFF的倍数的偏移量,并试图读取65535字节。它们不是512或4096的倍数,因此会出现"Invalid argument"错误。
改变你的代码使用对齐的大小(即0x10000/65536),它应该工作。在所有可能的情况下,您试图读取的结构实际上是65536字节,而不是65535。