编程实现挂载ISO镜像文件
2024-03-17 17:33:41

Win8平台自带API

挂载虚拟磁盘文件VHD或ISO镜像文件可以用 OpenVirtualDisk 相关API。其中ISO文件要求Win8及以上的系统,Win7不支持ISO文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <initguid.h>
#include <virtdisk.h>

#pragma comment(lib, "VirtDisk")

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hVirtualDisk = nullptr;
VIRTUAL_STORAGE_TYPE vst;
vst.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_ISO; // Win7不支持ISO
vst.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT;

OPEN_VIRTUAL_DISK_PARAMETERS openParams;
openParams.Version = OPEN_VIRTUAL_DISK_VERSION_1;

DWORD dwError = OpenVirtualDisk(&vst, L"E:\\vs2013.4_ult_chs.iso", VIRTUAL_DISK_ACCESS_ATTACH_RO, OPEN_VIRTUAL_DISK_FLAG_NONE, &openParams, &hVirtualDisk);
if (dwError == ERROR_SUCCESS) {
ATTACH_VIRTUAL_DISK_PARAMETERS attachParameters;
attachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
dwError = AttachVirtualDisk(hVirtualDisk, nullptr, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME, 0, &attachParameters, nullptr);
if (dwError == ERROR_SUCCESS) {
} else {
std::cout << "AttachVirtualDisk error: " << dwError << std::endl;
}
} else {
std::cout << "OpenVirtualDisk error: " << dwError << std::endl;
}

system("pause");
return 0;
}

上面的方法虽然可以挂载了,但是分配的挂载点是随机的,如果要手动指定挂载点则需要额外处理。

1、在 OpenVirtualDisk 的第3个参数带上 VIRTUAL_DISK_ACCESS_GET_INFO,否则后面的 GetVirtualDiskPhysicalPath 函数会失败。
2、在 AttachVirtualDisk 的第3个参数带上 ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER,表示不自动分配分区。
3、使用 GetVirtualDiskPhysicalPath 得到设备名称。
4、用 FindFirstVolumeFindNextVolume来枚举所有卷,并用 QueryDosDevice 查询每个卷的设备名,和上一步得到的设备名做比对,从而确认卷名称。
5、用 SetVolumeMountPoint 挂载到指定分区上。

其中第四步枚举的方法有点愚蠢,更简单的方式是用 GetVolumeNameForVolumeMountPointW 函数代替,它可以直接获取卷名称,参数是设备路径(注意末尾必须是反斜杠)

1
\\.\GLOBALROOT\Device\CDROM0\

卸载虚拟磁盘用 DetachVirtualDisk 函数

兼容Win7平台方案

如果要兼容Win7可以考虑使用第三方工具,比如这个 https://www.osforensics.com/tools/mount-disk-images.html
提取 OSFMount.com 文件和 OSFMount.sys 文件即可,驱动程序会自动注册进系统
只读挂载命令

1
OSFMount.com -a -t file -m Z: -o ro -f "D:\vs2013.4_ce_enu.iso"

卸载命令

1
OSFMount.com -D -m Z:

V2.0.1001版本的驱动在Win7 x64下无法使用,提示无法验证驱动签名。V1.5.1015版本可用。

参考

https://stackoverflow.com/questions/24396644/programmatically-mount-a-microsoft-virtual-hard-drive-vhd