P / Invoke写入引导扇区

时间:2013-11-22 17:07:42

标签: c# .net io pinvoke

我在.NET(C#)中创建一个(非生产)实用程序,用于将原始数据预加载到SD卡上。我正在尝试避免使用文件系统,因为我正在使用的嵌入式处理器没有足够的资源来实现文件系统管理器。到目前为止,我已经阅读了一堆Stack Overflow帖子和其他资源(例如pinvoke.net),但未能成功地将数据写入SD卡的扇区0。我很肯定我错过了很明显的东西。无论如何这里是相关的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;

public class RawIO
{
    public const uint GENERIC_READ = 0x80000000;
    public const uint GENERIC_WRITE = 0x40000000;
    public const uint OPEN_EXISTING = 3;
    public const short INVALID_HANDLE_VALUE = -1;

    // P/Invoke functions
    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern IntPtr CreateFile(
        string fileName,
        uint fileAccess,
        uint fileShare,
        IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES structure can be passed
        uint creationDisposition,
        uint flagsAndAttributes,
        IntPtr template);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool CloseHandle(IntPtr hObject);

    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern int SetFilePointer(IntPtr handle, int lDistanceToMove, out int lpDistanceToMoveHigh, uint dwMoveMethod);

    [DllImport("kernel32.dll")]
    static extern bool WriteFile(IntPtr hFile, byte [] lpBuffer,
        uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
        IntPtr lpOverlapped);

    public static IntPtr RawOpenVolume(string path)
    {
        // Acquire the handle
        IntPtr handle = CreateFile(
            path,
            GENERIC_READ | GENERIC_WRITE,
            0,
            IntPtr.Zero,
            OPEN_EXISTING,
            0,
            IntPtr.Zero);

        if (handle.ToInt32() == INVALID_HANDLE_VALUE)
        {
            Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
        }

        return handle;
    }

    public static int RawWriteVolume(IntPtr handle, byte[] buffer, int count)
    {
        uint bytesWritten;
        bool result = WriteFile(handle, buffer, count, out bytesWritten, IntPtr.Zero);
        if (!result)
        {
            Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
        }
        return (int) bytesWritten;
    }
}

我在Main()

中调用代码
static void Main(string[] args)
{
    byte[] buffer = Encoding.ASCII.GetBytes("abcdefghijklmnop"); 
    IntPtr handle = RawIO.RawOpenVolume("\\\\.\\G:");
    int bytesWritten = RawIO.RawWriteVolume(handle, buffer, buffer.Length);
}

但是,当我查看卷的十六进制转储时,我看不到这样的字节序列。我没有得到任何错误。另外,当我使用完全相同的句柄进行阅读时,我能够从卷中读取(尽管从扇区8192开始,但这是一个不同的问题。)我对.NET和Windows API很新,所以我确定我错过了一些非常明显的东西。我很感激我能得到的任何建议。

0 个答案:

没有答案