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. Mybatis多表关联查询字段值覆盖问题

    一.错误展示 1.首先向大家展示多表关联查询的返回结果集 <resultMap id="specialdayAndWorktimeMap type="com.hierway. ...

  2. CentOS 编译安装 Emacs 并配置

    Linux 中 CentOS 系列一向以稳定为目标,然而也会存在版本太旧的问题,Emacs 就是其中的一个,目前 Emacs 都发行到 25.2 了,而 CentOS 上的 Emacs 版本却还是 2 ...

  3. Pytest系列(9) - 参数化@pytest.mark.parametrize

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 pytest允许在多个级别启 ...

  4. C++编译/编辑器对OIer的必要功能

    (没有引战的意思,如果有不同意见可以评论区发言,只是写出我目前的情况) 作为一个C++ OIer肯定是用过Dev的,因为学校推荐啊我也没有办法.都知道Dev又丑又没有代码补全,但是却是最最最适合OIe ...

  5. mpvue怎么使用iconfont

    原文链接:https://blog.csdn.net/weixin_39818813/article/details/80695750 1.首先去阿里巴巴矢量图标库区把你要图标加到购物车 阿里巴巴矢量 ...

  6. 大O表示法是什么?

    1.什么是大O表示法: 1.在算法描述中,我们用这种方式来描述计算机算法的效率. 2.在计算机中,这种粗略的量度叫做 "大O" 表示法. 3.在具体的情境中,利用大O表示法来描述具 ...

  7. String 对象-->charAt() 方法

    1.定义和用法 charAt() 方法获取指定下标的字符,下标从0开始 语法: string.charAt(index) 参数: index:指定的下标 举例:获取下标为2的字符 var str = ...

  8. 合理使用CSS框架,加速UI设计进程

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://dzone.com/articles/how-to-speed-up-your-d ...

  9. 【转】解决存储过程执行快,但C#程序调用执行慢的问题

    这两天遇到一个问题令人比较郁闷,一个大概120行左右的存储过程在SQL Server2012的查询分析器里面执行,速度非常理想,1秒不到,即可筛选抓取到大概500条数据记录.但在C#程序代码里调用,就 ...

  10. copy模块中的copy与deepcopy的区别

    前言 每空闲下来,就觉得以前写的博客很low........也许现在也很low~~~~好吧就当升级版的low吧~~~~ 如果要了解copy与deepcopy的区别,就需要了解Python的存储机制:P ...