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

This is an old question but it still has no answer so I'll provide one in case someone stumble upon it like I did.

Attaching the VHD

For the complete Reference on MSDN [VHD Reference]: http://msdn.microsoft.com/en-us/library/windows/desktop/dd323700(v=vs.85).aspx

OPEN_VIRTUAL_DISK_PARAMETERS openParameters;
openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
openParameters.Version1.RWDepth = OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT; VIRTUAL_STORAGE_TYPE storageType;
storageType.DeviceID = VIRTUAL_STORAGE_TYPE_DEVICE_VHD;
storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT; ATTACH_VIRTUAL_DISK_PARAMETERS attachParameters;
attachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1; HANDLE vhdHandle; if (OpenVirtualDisk(&openStorageType, "{VHD PATH GOES HERE}",
VIRTUAL_DISK_ACCESS_ALL, OPEN_VIRTUAL_DISK_FLAG_NONE,
&openParameters, &vhdHandle) != ERROR_SUCCESS) {
// If return value of OpenVirtualDisk isn't ERROR_SUCCESS, there was a problem opening the VHD
} // Warning: AttachVirtualDisk requires elevation
if (AttachVirtualDisk(vhdHandle, , ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME,
, &attachParameters, ) != ERROR_SUCCESS) {
// If return value of AttachVirtualDisk isn't ERROR_SUCCESS, there was a problem attach the disk
}

VHD successfully attached, now it'll show up like any other physical disks and a drive letter will automatically be assigned to the volume(s) contained in the VHD. If you'd like to choose what drive letter is used to mount it, keep reading.

Assigning a drive letter

First, add the ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER flag to your AttachVirtualDisk call so it won't do this automatic letter assigning. Next, you'll have to find the volume path of the VHD volumes [it has this format: \\?\Volume{GUID}]:

wchar_t physicalDrive[MAX_PATH];
ULONG bufferSize = sizeof(physicalDrive);
GetVirtualDiskPhysicalPath(vhdHandle, &bufferSize, physicalDrive);

Now you'll have the physical path of your attached VHD in physical drive in the following format: \\.\PhysicalDrive# where # is the drive number you'll need to find your VHD volumes with FindFirstVolume/FindNextVolume. Extract the number and convert it to an integer and you'll be ready for the next piece of code:

char volumeName[MAX_PATH];
DWORD bytesReturned;
VOLUME_DISK_EXTENTS diskExtents;
HANDLE hFVol = FindFirstVolume(volumeName, sizeof(volumeName));
bool hadTrailingBackslash = false; do {
// I had a problem where CreateFile complained about the trailing \ and
// SetVolumeMountPoint desperately wanted the backslash there. I ended up
// doing this to get it working but I'm not a fan and I'd greatly
// appreciate it if someone has any further info on this matter
int backslashPos = strlen(volumeName) - ;
if (hadTrailingBackslash = volumeName[backslashPos] == '\\') {
volumeName[backslashPos] = ;
} HANDLE hVol = CreateFile(volumeName, , FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, , NULL);
if (hVol == INVALID_HANDLE_VALUE) {
return;
} DeviceIoControl(hVol, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL,
, &diskExtents, sizeof(diskExtents), &bytesReturned, NULL); // If the volume were to span across multiple physical disks, you'd find
// more than one Extents here but we don't have to worry about that with VHD
// Note that 'driveNumber' would be the integer you extracted out of
// 'physicalDrive' in the previous snippet
if (diskExtents.Extents[].DiskNumber == driveNumber) {
if (hadTrailingBackslash) {
volumeName[backslashPos] = '\\';
} // Found volume that's on the VHD, let's mount it with a letter of our choosing.
// Warning: SetVolumeMountPoint requires elevation
SetVolumeMountPoint("H:\\", volumeName);
}
} while (FindNextVolume(hFVol, volumeName, sizeof(volumeName)));
FindVolumeClose(hFVol);

Don't forget these includes and link to this library:

#define WINVER _WIN32_WINNT_WIN7
#include <windows.h>
#include <winioctl.h>
#include <virtdisk.h> #pragma comment(lib, "virtdisk.lib")

Disclaimer: This is something I was doing in a C# codebase, I translated the code to C/C++ because of the question but haven't tried to actually compile it. If you find errors in the code, please edit it or let me know so I can do it.

Edits: Typos, includes and lib, forgot FindVolumeClose, elevation warnings

Programmatically mount a Microsoft Virtual Hard Drive (VHD)的更多相关文章

  1. Microsoft Virtual Academy 介绍

    Microsoft Virtual Academy 是微软的虚拟学院,会推出微软各个方面的一些教程 介绍一点有用的链接 http://www.microsoftvirtualacademy.com/e ...

  2. (转)vmware下给linux虚拟机扩容

    “Well, here’s another fine mess you’ve gotten me into” Let us pretend that you have an Ubuntu Server ...

  3. How to Convert and Import VHD to VMDK (VMWare)

    VHD or Virtual Hard Disk is the disk image format used by Microsoft virtualization software such as ...

  4. VMWare File Format Learning && Use VHD File To Boot VMWare && CoreOS Docker Configuration And Running

    目录 . Virtual Machine Introduce . Vmware Image File Format . VHD File Format . Convert VHD File Into ...

  5. windows平台vhd磁盘文件挂载

    在windows平台下挂载vhd磁盘文件类似于挂载iso等文件; 使用VHDMount工具挂载VHD文件 启动Hyper-V里的外部VHD文件有点困难.如果在备份驱动上有个VHD文件,并需要从其虚拟机 ...

  6. DiskPart.exe and managing Virtual Hard Disks (VHDs) in Windows 7

    coreygoOctober 7, 2009 In Windows 7, new commands have been added in DiskPart to allow for the creat ...

  7. VHD轻松实现双系统

    VHD 是微软虚拟磁盘文件.   VHD(Microsoft Virtual Hard Disk format). 目前可以使用Microsoft Virtual PC 2007 and Micros ...

  8. VHD VHDX 区别

    A Virtual hard disk is saved either with VHD or VHDX file extension. VHD is the older while VHDX is ...

  9. MOUNT MACBOOK DISK (OSX / HFS+) ON UBUNTU 12.04 LTS WITH READ/WRITE

    MOUNT MACBOOK DISK (OSX / HFS+) ON UBUNTU 12.04 LTS WITH READ/WRITE So you want to mount your HFS+ ( ...

随机推荐

  1. 性能测试环境搭建:XAMPP1.8+PHPwind9.0安装教程

    1.安装准备 1.1软件版本 XAMPP的版本:XAMPP 1.8.2 phpwind的版本:PHPWind 9.0   1.2.安装环境 我的环境:win10 其实安装环境影响不大,win7,win ...

  2. Q - 迷宫问题 POJ - 3984(BFS / DFS + 记录路径)

    Q - 迷宫问题 POJ - 3984 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, ...

  3. mysql 中UNIQUE KEY 到底是约束还是索引?

    答案来自:https://zhidao.baidu.com/question/1863373387452612907.html 两者关系 unique索引包含了unique约束,因为unique约束是 ...

  4. 10年阿里自动化测试架构师帮您收集的:git常用命令大全以及git原理图【泣血推荐,建议收藏】

    一.Git分布式版本控制简介 ​ Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势.本来想着只把最有用.最常用的 Git 命令记下来, ...

  5. STM32F103ZET6的基本定时器

    1.定时器的分类 STM32F103ZET6总共有8个定时器,它们是:TIM1~TIM8.STM32的定时器分为基本定时器.通用定时器和高等定时器. TIM6.TIM7是基本定时器.基本定时器是只能向 ...

  6. java中OOM错误解析(面试可以聊的东西)

    嗯,生活加油鸭.... 实习中遇到OOM错误 GC overhead limit exceeded 问题,所以整理一下OOM异常问题: 先看一下“阿里的开发手册”对OOM的描述: OOM,全称“Out ...

  7. Alibaba Cloud Linux 2 LTS 正式发布,提供更高性能和更多保障!

    在Alibaba Cloud Linux 2(原Aliyun Linux 2)上线一年之际阿里云对外正式发布Alibaba Cloud Linux 2 LTS版本.LTS版本的发布对于Alibaba ...

  8. spark foreachPartition foreach

    1.foreach val list = new ArrayBuffer() myRdd.foreach(record => { list += record }) 2.foreachParti ...

  9. centos7 NAT链接配置(静态ip/修改网卡名为eth0)|1

    NAT的静态ip设置并且修改网卡名为eth0 1 cd /etc/sysconfig/network-scripts/ mv eno16777736  ifcfg-eth0 #修改名称 vi eth0 ...

  10. lr组织架构模式

    基本模式:默认目录由三部分组成 Vuser_int Action,…… Vuser_end 执行时会按照这三个顺序执行(Action部分是可以循环的,也可多个action) 1.lr12录制前可以设置 ...