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,然后传入这个句柄就可以。
  • 相关阅读:
    opencv出现问题:/usr/lib/x86_64-linux-gnu/libpng16.so.16: undefined reference to `inflateValidate@ZLIB_1.2.9'
    SCI-HUB 解锁论文的正确姿势——如何免费下载论文
    VS2019 实现与 Linux服务器同步
    VS Code 写代码实时同步服务器【Sftp插件】
    Docker实用技巧(二):容器与主机之间复制文件
    Docker实用技巧(一):镜像的备份/保存/加载/删除
    mycat注解及高可用(三)
    mycat分片及主从(二)
    SVN中trunk,branches,tags用法详解
    寄存器的英文全称
  • 原文地址:https://www.cnblogs.com/tinz/p/2078120.html
Copyright © 2011-2022 走看看