您的位置:首页 > 编程语言 > C#

用C#访问硬盘物理扇区和逻辑扇区的方法

2010-10-28 21:25 597 查看
因为API要用到一些宏定义和枚举变量,所以这里先定义一下:

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,那就要使用下面的方法读写磁盘的物理扇区。

读写物理扇区:

先看下面这幅图(硬盘管理器可以看到):



红色框里的数字表示:磁盘序号(不是序列号);

天蓝色框表示:盘符;

黄色框表示:分区,分区的序号是从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,然后传入这个句柄就可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: