我正在尝试使用Windows 7 API函数挂载虚拟硬盘(.VHD),但是我找不到相关的函数,是否存在?
我正在使用Visual Studio 2010以C++进行编程,以获取信息。
提前致谢 ;)
最佳答案
这是一个古老的问题,但是仍然没有答案,因此我会提供一个答案,以防有人像我一样偶然发现它。
附加VHD
有关MSDN的完整引用[VHD引用]: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, 0, ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME,
0, &attachParameters, 0) != ERROR_SUCCESS) {
// If return value of AttachVirtualDisk isn't ERROR_SUCCESS, there was a problem attach the disk
}
VHD已成功连接,现在它将像其他任何物理磁盘一样显示,并且驱动器号将自动分配给VHD中包含的卷。如果您想选择用于挂载的驱动器号,请继续阅读。
分配驱动器号
首先,将
ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER
标志添加到您的AttachVirtualDisk调用中,这样它就不会执行此自动字母分配。接下来,您必须找到VHD卷的卷路径[其格式为:\\?\Volume {GUID}]:wchar_t physicalDrive[MAX_PATH];
ULONG bufferSize = sizeof(physicalDrive);
GetVirtualDiskPhysicalPath(vhdHandle, &bufferSize, physicalDrive);
现在,您将具有以下格式的物理驱动器中已连接的VHD的物理路径:\\。\PhysicalDrive#其中#是使用FindFirstVolume/FindNextVolume查找VHD卷所需的驱动器号。提取数字并将其转换为整数,您就可以准备下一段代码:
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) - 1;
if (hadTrailingBackslash = volumeName[backslashPos] == '\\') {
volumeName[backslashPos] = 0;
}
HANDLE hVol = CreateFile(volumeName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hVol == INVALID_HANDLE_VALUE) {
return;
}
DeviceIoControl(hVol, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL,
0, &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[0].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);
不要忘记这些包含并链接到该库:
#define WINVER _WIN32_WINNT_WIN7
#include <windows.h>
#include <winioctl.h>
#include <virtdisk.h>
#pragma comment(lib, "virtdisk.lib")
免责声明:这是我在C#代码库中所做的事情,由于这个问题,我将代码翻译为C/C++,但并未尝试对其进行实际编译。如果您在代码中发现错误,请对其进行编辑或让我知道,以便我可以解决。
编辑:错别字,包含和库,忘记了FindVolumeClose,海拔警告
关于c++ - 以编程方式安装Microsoft虚拟硬盘驱动器(VHD),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24396644/