美文网首页
利用Win32 api 读写硬盘扇区

利用Win32 api 读写硬盘扇区

作者: Misaka14375 | 来源:发表于2017-07-16 00:17 被阅读0次

    调用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;
            }
    

    相关文章

      网友评论

          本文标题:利用Win32 api 读写硬盘扇区

          本文链接:https://www.haomeiwen.com/subject/bahzcxtx.html