zoukankan      html  css  js  c++  java
  • 用C#访问硬盘物理扇区和逻辑扇区的方法

    因为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,然后传入这个句柄就可以。
  • 相关阅读:
    ES6/5比较
    Javascript中的var和let
    git中remotes/origin/HEAD指向的分支丢失
    js实用篇之数组、字符串常用方法
    JS设计模式一:单例模式
    Linux C 面试题总结 .
    深入理解javascript原型和闭包(15)——闭包
    一些有意思的面试题(持续更新) .C语言编程技巧札记
    一个三流大学生的北京三年 .
    C 字节对齐.我的算法学习之路
  • 原文地址:https://www.cnblogs.com/tinz/p/2078120.html
Copyright © 2011-2022 走看看