虽然 @MSalters 的答案是有道理的,但这不是我的代码的工作原理。事实上,它是如此违反直觉,我花了几天时间来确保代码确实有效。
这些代码片段位于经过验证的大众消费市场软件产品中。当需要修改磁盘结构时,它会卸载 win32 卷,以便可以修改 NTFS 或 FAT 文件系统结构。有趣的是,卷访问句柄是只读的:
char fn [30];
snprintf (fn, sizeof fn, "\\\\.\\%s:", vol -> GetVolName ());
vol_handle = CreateFile (fn, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS,
NULL);
if (vol_handle == INVALID_HANDLE_VALUE)
{
// show error message and exit
}
如果无法获得对卷或分区的写访问权限,并且用户在严重警告后授权执行此操作,则此代码将强制卸载:
if (!DeviceIoControl (vol_handle, FSCTL_DISMOUNT_VOLUME,
NULL, 0, NULL, 0, &status, NULL))
{
DWORD err = GetLastError ();
errormsg ("Error %d attempting to dismount volume: %s",
err, w32errtxt (err));
}
// lock volume
if (!DeviceIoControl (vol_handle, FSCTL_LOCK_VOLUME,
NULL, 0, NULL, 0, &status, NULL))
{
// error handling; not sure if retrying is useful
}
除了按 512 字节扇区定位文件指针外,写入相当简单:
long hipart = sect >> (32-9);
long lopart = sect << 9;
long err;
SetLastError (0); // needed before SetFilePointer post err detection
lopart = SetFilePointer (vol_handle, lopart, &hipart, FILE_BEGIN);
if (lopart == -1 && NO_ERROR != (err = GetLastError ()))
{
errormsg ("HWWrite: error %d seeking drive %x sector %ld: %s",
err, drive, sect, w32errtxt (err));
return false;
}
DWORD n;
if (!WriteFile (vol_handle, buf, num_sects*512, &n, NULL))
{
err = GetLastError ();
errormsg ("WriteFile: error %d writing drive %x sectors %lu..%lu: %s",
err, drv, sect, sect + num_sects - 1,
w32errtxt (err));
return false;
}