private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
private const uint FILE_SHARE_READ = 0x00000001;
private const uint FILE_SHARE_WRITE = 0x00000002;
private const uint OPEN_EXISTING = 3;
public enum EMoveMethod : uint
{
Begin = 0,
Current = 1,
End = 2
}
导入需要用到的API函数:
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern uint SetFilePointer(
[In] SafeFileHandle hFile,
[In] int lDistanceToMove,
IntPtr lpDistanceToMoveHigh,
[In] EMoveMethod dwMoveMethod);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool ReadFile(
[In] SafeFileHandle hFile,
[Out] byte[] lpBuffer,
uint nNumberOfBytesToRead,
out uint lpNumberOfBytesRead,
IntPtr lpOverlapped);
[DllImport("kernel32.dll")]
static extern bool WriteFile(
[In] SafeFileHandle hFile,
byte[] lpBuffer,
uint nNumberOfBytesToWrite,
out uint lpNumberOfBytesWritten,
IntPtr lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern SafeFileHandle CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);
读写<逻辑>扇区:
public void ReadSector([Out] byte[] ReturnByte, int SectorIndex)
{
uint dwCB;
if (SectorIndex > _SectorLength) return;
SafeFileHandle DirverHandle = CreateFile("\\\\.\\" + DirverName.Trim(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
SetFilePointer(DirverHandle, SectorIndex * 512, IntPtr.Zero, EMoveMethod.Begin);
ReadFile(DirverHandle, ReturnByte, 512, out dwCB, IntPtr.Zero);
DirverHandle.Close();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
public void WritSector(byte[] SectorBytes, int SectorIndex)
{
uint dwCB;
if (SectorBytes.Length != 512) return;
if (SectorIndex > _SectorLength) return;
SafeFileHandle DirverHandle = CreateFile("\\\\.\\" + DirverName.Trim(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
SetFilePointer(DirverHandle, SectorIndex * 512, IntPtr.Zero, EMoveMethod.Begin);
WriteFile(DirverHandle, SectorBytes, 512, out dwCB, IntPtr.Zero);
DirverHandle.Close();
}
上面用到的 DirverName 就是盘符,例如"C:"或者"D:"之类。读写到的是逻辑扇区,假如你要读写MRB,那就要使用下面的方法读写磁盘的物理扇区。
读写物理扇区:
先看下面这幅图(硬盘管理器可以看到):
![](http://hiphotos.baidu.com/jamiedu/pic/item/813680ee17023d5ffcfa3c31.jpg)
红色框里的数字表示:磁盘序号(不是序列号);
天蓝色框表示:盘符;
黄色框表示:分区,分区的序号是从0开始,每个物理磁盘的分区序号都是从0开始计算。
在读写物理扇区时,需要用到磁盘序号,下一节记录怎样通过盘符获取磁盘序号的,因为一般网上找到的都是获取盘符的办法,之前这个问题差点搞疯了。
程序提到的PhysicalDrive2里的2就是磁盘序号。
创建句柄:
SafeFileHandle hdnl = CreateFile("\\\\.\\PhysicalDrive2", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
创建完句柄后读写就和操作逻辑扇区一样了,调用ReadFile/WriteFile,然后传入这个句柄就可以。