我正在编写一个将FreeDOS安装到虚拟硬盘上的程序。它生成并执行DiskPart脚本来创建VHD,对其进行分区,格式化,然后为其分配驱动器号。
这很好。我的安装程序将所有内容复制到VHD,但是现在我需要写一个引导扇区,这需要直接访问卷。在开始这个过程之前,我尝试使用FSCTL_LOCK_VOLUME来锁定卷。
问题是:DeviceIoControl
返回ERROR_ACCESS_DENIED
,这(根据MSDN)意味着卷上有打开的文件。但是我的安装程序一旦完成复制就会关闭每个文件,所以我不确定还有什么原因会导致这种情况。这是否与DiskPart挂载VHD的方式有关?
DiskPart脚本示例
create vdisk file=E:Devfreedos.vhd maximum=128 type=fixed
select vdisk file=E:Devfreedos.vhd
attach vdisk
create partition primary
select partition 1
format quick fs=FAT
assign letter=A
注意:文件路径,磁盘大小,文件系统和驱动器号值取决于提供给程序的选项。
C代码
HANDLE volume;
char volName[MAX_PATH];
DWORD bytesReturned;
if (!GetVolumeNameForVolumeMountPoint(config.volRoot, volName, sizeof(volName)))
ThrowError(1, "Failed to get volume name (error %d)!", GetLastError());
/*
* CreateFile will fail if the volume name has a trailing backslash
*/
PathRemoveBackslash(volName);
volume = CreateFile(volName, (GENERIC_READ | GENERIC_WRITE),
(FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (volume == INVALID_HANDLE_VALUE)
ThrowError(1, "Failed to open installation volume (error %d)!", GetLastError());
if (!DeviceIoControl(volume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &bytesReturned, NULL))
ThrowError(1, "Failed to lock installation volume (error %d)!", GetLastError());
CloseHandle(volume);
这并不能真正回答您的问题,但实际上最好先直接创建VHD ,然后挂载它。VHD是一种非常简单的格式,你可以写一个程序直接创建一个VHD与一个已经预先编写的引导加载程序(即只使用CreateFile/WriteFile),然后挂载它并创建一个文件系统。