調(diào)用API函數(shù)即可完成對扇區(qū)的讀寫操作
[DllImport("Kernel32.dll")]
extern static IntPtr CreateFile(string fileName, uint accessFlag, uint shareMode, IntPtr security, uint createFlag, uint attributeFlag, IntPtr tempfile);
首先要創(chuàng)建文件
[DllImport("Kernel32.dll", SetLastError = true)]
extern static uint SetFilePointer(IntPtr handle, uint offset, [In, Out] ref uint lpDistanceToMoveHigh, uint flag);
設(shè)置文件指針
如果不設(shè)置第三個參數(shù)(null),系統(tǒng)會把第二個參數(shù)offset當(dāng)作一個有符號整數(shù)(32位)劫瞳,最多偏移2GB倘潜。
設(shè)置后會把第三個參數(shù)當(dāng)作64有符號數(shù)的高32位,第二個參數(shù)當(dāng)作低32位志于。
(要注意的是第三個參數(shù)是引用類型)
[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中返回值為為零寫入成功,不為零錯誤伺绽。對應(yīng)到這里就是返回false和true
第三個參數(shù)保存的是寫入了多少字節(jié)养泡。
[DllImport("Kernel32.dll")]
extern static bool CloseHandle(IntPtr handle);
最后要記得關(guān)閉句柄
參數(shù)設(shè)置,具體含義見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>
/// 寫入內(nèi)容 需為扇區(qū)整數(shù)倍奈应,不然寫不進(jìn)去
/// </summary>
/// <param name="drivename">驅(qū)動器名</param>
/// <param name="sector">扇區(qū)</param>
/// <param name="buffer">寫入內(nèi)容</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;
}