调用API函数即可完成对扇区的读写操作
[DllImport("Kernel32.dll")]
extern static IntPtr CreateFile(string fileName, uint accessFlag, uint shareMode, IntPtr security, uint createFlag, uint attributeFlag, IntPtr tempfile);
首先要创建文件
[DllImport("Kernel32.dll", SetLastError = true)]
extern static uint SetFilePointer(IntPtr handle, uint offset, [In, Out] ref uint lpDistanceToMoveHigh, uint flag);
设置文件指针
如果不设置第三个参数(null),系统会把第二个参数offset当作一个有符号整数(32位),最多偏移2GB。
设置后会把第三个参数当作64有符号数的高32位,第二个参数当作低32位。
(要注意的是第三个参数是引用类型)
[DllImport("Kernel32.dll")]
extern static bool WriteFile(IntPtr handle, [In] byte[] buffer, uint bufferLength, ref uint length, IntPtr overLapped);
[DllImport("Kernel32.dll")]
extern static bool ReadFile(IntPtr handle, [Out] byte[] buffer, uint bufferLength, ref uint length, IntPtr overLapped);
然后开始你的操作。
Win32 api中返回值为为零写入成功,不为零错误。对应到这里就是返回false和true
第三个参数保存的是写入了多少字节。
[DllImport("Kernel32.dll")]
extern static bool CloseHandle(IntPtr handle);
最后要记得关闭句柄
参数设置,具体含义见MSDN: CreateFile
public const uint FILE_ATTRIBUTE_NORMAL = 0x80;
public const short INVALID_HANDLE_VALUE = -1;
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint CREATE_NEW = 1;
public const uint CREATE_ALWAYS = 2;
public const uint OPEN_EXISTING = 3;
public const uint FILE_BEGIN = 0;
public const uint FILE_CURRENT = 1;
public const uint FILE_END = 2;
例子:
/// <summary>
/// 写入内容 需为扇区整数倍,不然写不进去
/// </summary>
/// <param name="drivename">驱动器名</param>
/// <param name="sector">扇区</param>
/// <param name="buffer">写入内容</param>
/// <returns></returns>
static public bool write(string drivename, UInt32 sector, byte[] buffer)
{
IntPtr DiskHandle = CreateFile(drivename, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
uint length = 0;
UInt64 distance = sector ;//偏移量
distance = distance << 9;
UInt32 distancehigh = (UInt32)(distancehigh>> 32);
var i=SetFilePointer(DiskHandle, (uint)distance, ref distancehigh, FILE_BEGIN);
if (i == 0xffffffff)//返回值是低32位地址,返回-1时getlastwin32error查看错误
{
var errCode=Marshal.GetLastWin32Error();
IntPtr tempptr = IntPtr.Zero;
string msg = null;
FormatMessage(0x1300, ref tempptr, errCode, 0, ref msg, 255, ref tempptr);
}
var res=WriteFile(DiskHandle, buffer, (uint)buffer.Length, ref length, IntPtr.Zero);
CloseHandle(DiskHandle);
return res;
}
网友评论