BOOL OpenAndMergeVHD(PCWSTR pszVhdPath) { BOOL bRet = FALSE; DWORD ret; HANDLE hVhd; MERGE_VIRTUAL_DISK_PARAMETERS mparms; OPEN_VIRTUAL_DISK_PARAMETERS oparms; MERGE_VIRTUAL_DISK_FLAG flags = MERGE_VIRTUAL_DISK_FLAG_NONE; VIRTUAL_STORAGE_TYPE vst = { VIRTUAL_STORAGE_TYPE_DEVICE_VHD, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; wprintf(L"OpenAndMergeVHD %s\n", pszVhdPath); oparms.Version = OPEN_VIRTUAL_DISK_VERSION_1; oparms.Version1.RWDepth = 2; ret = OpenVirtualDisk(&vst, pszVhdPath, VIRTUAL_DISK_ACCESS_METAOPS | VIRTUAL_DISK_ACCESS_GET_INFO, OPEN_VIRTUAL_DISK_FLAG_NONE, &oparms, &hVhd); if (ERROR_SUCCESS == ret) { printf("success opening vdisk...\n"); mparms.Version = MERGE_VIRTUAL_DISK_VERSION_1; mparms.Version1.MergeDepth = oparms.Version1.RWDepth - 1; //MERGE_VIRTUAL_DISK_DEFAULT_MERGE_DEPTH; ret = MergeVirtualDisk(hVhd, flags, &mparms, NULL); if (ERROR_SUCCESS == ret) { printf("success merging vdisk...\n"); bRet = TRUE; } else { printf("failed to expand vdisk... %d\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } } else { printf("failed to open vdisk...err %d\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } if (INVALID_HANDLE_VALUE != hVhd) { CloseHandle(hVhd); } return bRet; }
BOOL OpenAndGetPhysVHD(PCWSTR pszVhdPath, PWSTR pszPhysicalDiskPath) { BOOL bRet = FALSE; HANDLE hVhd = INVALID_HANDLE_VALUE; DWORD ret; OPEN_VIRTUAL_DISK_PARAMETERS oparams; ATTACH_VIRTUAL_DISK_PARAMETERS iparams; VIRTUAL_STORAGE_TYPE vst = { VIRTUAL_STORAGE_TYPE_DEVICE_VHD, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; wprintf(L"OpenAndGetPhysVHD %s\n", pszVhdPath); oparams.Version = OPEN_VIRTUAL_DISK_VERSION_1; oparams.Version1.RWDepth = OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT; iparams.Version = ATTACH_VIRTUAL_DISK_VERSION_1; ret = OpenVirtualDisk(&vst, pszVhdPath, VIRTUAL_DISK_ACCESS_ATTACH_RW | VIRTUAL_DISK_ACCESS_GET_INFO | VIRTUAL_DISK_ACCESS_DETACH, OPEN_VIRTUAL_DISK_FLAG_NONE, &oparams, &hVhd); if (ERROR_SUCCESS == ret) { ULONG sizePhysicalDisk; printf("success opening vdisk...\n"); memset(pszPhysicalDiskPath, 0, sizeof (wchar_t) * PHYS_PATH_LEN); sizePhysicalDisk = (PHYS_PATH_LEN * sizeof(wchar_t)) * 256; ret = GetVirtualDiskPhysicalPath(hVhd, &sizePhysicalDisk, pszPhysicalDiskPath); if (ERROR_SUCCESS == ret) { wprintf(L"success getting physical path %s vhdname\n", pszPhysicalDiskPath); bRet = TRUE; } else { printf("failed to get vhd physical info %d\n", ret); PrintErrorMessage(GetLastError()); } } else { printf("failed to open vdisk...err 0x%x\n", ret); PrintErrorMessage(GetLastError()); } if (INVALID_HANDLE_VALUE != hVhd) { CloseHandle(hVhd); } return bRet; }
BOOL OpenAndAttachVHD(PCWSTR pszVhdPath) { BOOL bRet = FALSE; HANDLE hVhd = INVALID_HANDLE_VALUE; DWORD ret; OPEN_VIRTUAL_DISK_PARAMETERS oparams; ATTACH_VIRTUAL_DISK_PARAMETERS iparams; VIRTUAL_STORAGE_TYPE vst = { VIRTUAL_STORAGE_TYPE_DEVICE_VHD, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; wprintf(L"OpenAndAttachVHD %s\n", pszVhdPath); oparams.Version = OPEN_VIRTUAL_DISK_VERSION_1; oparams.Version1.RWDepth = OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT; iparams.Version = ATTACH_VIRTUAL_DISK_VERSION_1; ret = OpenVirtualDisk(&vst, pszVhdPath, VIRTUAL_DISK_ACCESS_ATTACH_RW | VIRTUAL_DISK_ACCESS_GET_INFO | VIRTUAL_DISK_ACCESS_DETACH, OPEN_VIRTUAL_DISK_FLAG_NONE, &oparams, &hVhd); if (ERROR_SUCCESS == ret) { printf("success opening vdisk...\n"); ret = AttachVirtualDisk(hVhd, NULL, ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME, 0, &iparams, NULL); if (ERROR_SUCCESS == ret) { printf("success attaching vdisk...\n"); } else { printf("failed to attach vdisk...err 0x%x\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } } else { printf("failed to open vdisk...err 0x%x\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } if (INVALID_HANDLE_VALUE != hVhd) { CloseHandle(hVhd); } return bRet; }
BOOL OpenAndDetachVHD(PCWSTR pszVhdPath) { BOOL bRet = FALSE; DWORD ret; DETACH_VIRTUAL_DISK_FLAG Flags; HANDLE hVhd = INVALID_HANDLE_VALUE; OPEN_VIRTUAL_DISK_PARAMETERS oparams; VIRTUAL_STORAGE_TYPE vst = { VIRTUAL_STORAGE_TYPE_DEVICE_VHD, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; wprintf(L"OpenAndDetachVHD %s\n", pszVhdPath); oparams.Version = OPEN_VIRTUAL_DISK_VERSION_1; oparams.Version1.RWDepth = OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT; ret = OpenVirtualDisk(&vst, pszVhdPath, VIRTUAL_DISK_ACCESS_DETACH, OPEN_VIRTUAL_DISK_FLAG_NONE, NULL /*&oparams*/, &hVhd); if (ERROR_SUCCESS == ret) { printf("success opening vdisk...\n"); Flags = DETACH_VIRTUAL_DISK_FLAG_NONE; ret = DetachVirtualDisk(hVhd, Flags, 0); if (ERROR_SUCCESS == ret) { printf("success detaching vdisk...\n"); } else { printf("failed to detach vdisk... %d\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } } else { printf("failed to open vdisk...err %d\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } if (INVALID_HANDLE_VALUE != hVhd) { CloseHandle(hVhd); } return bRet; }
int OpenAndSetVHDInfo(PCWSTR pszVhdPath, PCWSTR pszGuid, GUID *Guid) { BOOL bRet = FALSE; DWORD ret; HANDLE hVhd; ULONG InfoSize; SET_VIRTUAL_DISK_INFO SetInfo; VIRTUAL_STORAGE_TYPE vst = { VIRTUAL_STORAGE_TYPE_DEVICE_VHD, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; wprintf(L"OpenAndSetVHDInfo %s GUID %s\n", pszVhdPath, pszGuid); ret = OpenVirtualDisk(&vst, pszVhdPath, VIRTUAL_DISK_ACCESS_ALL, OPEN_VIRTUAL_DISK_FLAG_NONE, NULL, &hVhd); if (ERROR_SUCCESS == ret) { printf("success opening vdisk...\n"); SetInfo.Version = SET_VIRTUAL_DISK_INFO_IDENTIFIER; InfoSize = sizeof(SetInfo); SetInfo.UniqueIdentifier = zGuid; //*Guid; ret = SetVirtualDiskInformation(hVhd, &SetInfo); if (ret == ERROR_SUCCESS) { printf("success setting vhd info\n"); } else { printf("failed to set vhd info %d\n", ret); PrintErrorMessage(GetLastError()); } } else { printf("failed to open vdisk...err %d\n", ret); PrintErrorMessage(GetLastError()); } if (INVALID_HANDLE_VALUE != hVhd) { CloseHandle(hVhd); } return bRet; }
// Expanding a virtual disk requires that the virtual disk be detached during // the operation. BOOL OpenAndExpandVHD(PCWSTR pszVhdPath, ULONG newSizeMB) { BOOL bRet = FALSE; DWORD ret; HANDLE hVhd = INVALID_HANDLE_VALUE; EXPAND_VIRTUAL_DISK_PARAMETERS xparams; VIRTUAL_STORAGE_TYPE vst = { VIRTUAL_STORAGE_TYPE_DEVICE_VHD, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; wprintf(L"OpenAndExpandVHD %s, new size (MB) %d\n", pszVhdPath, newSizeMB); ret = OpenVirtualDisk(&vst, pszVhdPath, VIRTUAL_DISK_ACCESS_METAOPS, OPEN_VIRTUAL_DISK_FLAG_NONE, NULL, &hVhd); if (ERROR_SUCCESS == ret) { printf("success opening vdisk...\n"); xparams.Version = EXPAND_VIRTUAL_DISK_VERSION_1; xparams.Version1.NewSize = newSizeMB * 1024 * 1024; ret = ExpandVirtualDisk(hVhd, EXPAND_VIRTUAL_DISK_FLAG_NONE, &xparams, 0); if (ERROR_SUCCESS == ret) { printf("success expanding vdisk...\n"); } else { printf("failed to expand vdisk... %d\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } } else { printf("failed to open vdisk...err %d\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } if (INVALID_HANDLE_VALUE != hVhd) { CloseHandle(hVhd); } return bRet; }
DWORD SampleResizeVirtualDisk( _In_ LPCWSTR VirtualDiskPath, _In_ ULONGLONG FileSize) { OPEN_VIRTUAL_DISK_PARAMETERS openParameters; RESIZE_VIRTUAL_DISK_PARAMETERS resizeParameters; VIRTUAL_STORAGE_TYPE storageType; HANDLE vhdHandle; DWORD opStatus; vhdHandle = INVALID_HANDLE_VALUE; // // Specify UNKNOWN for both device and vendor so the system will use the // file extension to determine the correct VHD format. // storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN; storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN; // // Open the VHD/VHDX. // // Only V2 handles can be used to resize a VHD/VHDX. // // VIRTUAL_DISK_ACCESS_NONE is the only acceptable access mask for V2 handle opens. // OPEN_VIRTUAL_DISK_FLAG_NONE bypasses any special handling of the open. // memset(&openParameters, 0, sizeof(openParameters)); openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_2; opStatus = OpenVirtualDisk( &storageType, VirtualDiskPath, VIRTUAL_DISK_ACCESS_NONE, OPEN_VIRTUAL_DISK_FLAG_NONE, &openParameters, &vhdHandle); if (opStatus != ERROR_SUCCESS) { goto Cleanup; } // // Perform the resize (shrink or expand). // // RESIZE_VIRTUAL_DISK_VERSION_1 is the only version of the parameters currently supported. // RESIZE_VIRTUAL_DISK_FLAG_NONE prevents unsafe shrink where the new virtual disk size cannot // be less than the "SmallestSafeVirtualSize" reported through the GetVirtualDiskInformation API // with a "VirtualDiskInfo" of GET_VIRTUAL_DISK_INFO_SMALLEST_SAFE_VIRTUAL_SIZE. // memset(&resizeParameters, 0, sizeof(resizeParameters)); resizeParameters.Version = RESIZE_VIRTUAL_DISK_VERSION_1; resizeParameters.Version1.NewSize = FileSize; opStatus = ResizeVirtualDisk( vhdHandle, RESIZE_VIRTUAL_DISK_FLAG_NONE, &resizeParameters, NULL); if (opStatus != ERROR_SUCCESS) { goto Cleanup; } Cleanup: if (opStatus == ERROR_SUCCESS) { wprintf(L"success\n"); } else { wprintf(L"error = %u\n", opStatus); } if (vhdHandle != INVALID_HANDLE_VALUE) { CloseHandle(vhdHandle); } return opStatus; }
int OpenAndGetVHDInfo(PCWSTR pszVhdPath, PCWSTR pszGuid) { BOOL bRet = FALSE; DWORD ret; HANDLE hVhd; GET_VIRTUAL_DISK_INFO Info; ULONG InfoSize; ULONG SizeUsed; VIRTUAL_STORAGE_TYPE vst = { VIRTUAL_STORAGE_TYPE_DEVICE_VHD, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; wprintf(L"OpenAndGetVHDInfo %s\n", pszVhdPath); ret = OpenVirtualDisk(&vst, pszVhdPath, VIRTUAL_DISK_ACCESS_ALL, OPEN_VIRTUAL_DISK_FLAG_NONE, NULL, &hVhd); if (ERROR_SUCCESS == ret) { printf("success opening vdisk...\n"); InfoSize = (ULONG)sizeof(GET_VIRTUAL_DISK_INFO); Info.Version = GET_VIRTUAL_DISK_INFO_SIZE; ret = GetVirtualDiskInformation(hVhd, &InfoSize, &Info, &SizeUsed); if (ret == ERROR_SUCCESS) { printf("success getting virtual disk size info\n"); printf("Info.Size.VirtualSize (bytes) = %I64d (dec)\n", Info.Size.VirtualSize); printf("Info.Size.PhysicalSize (bytes) = %I64d (dec)\n", Info.Size.PhysicalSize); printf("Info.Size.BlockSize (bytes) = %d (dec)\n", Info.Size.BlockSize); printf("Info.Size.SectorSize (bytes) = %d (dec)\n", Info.Size.SectorSize); bRet = TRUE; } else { printf("failed to get virtual disk size info %d\n", ret); PrintErrorMessage(GetLastError()); } InfoSize = (ULONG)sizeof(GET_VIRTUAL_DISK_INFO); Info.Version = GET_VIRTUAL_DISK_INFO_IDENTIFIER; ret = GetVirtualDiskInformation(hVhd, &InfoSize, &Info, &SizeUsed); if (ret == ERROR_SUCCESS) { StringFromCLSID(Info.Identifier, (LPOLESTR *) &pszGuid); printf("success getting virtual disk ID info\n"); wprintf(L"Info.Identifier (GUID) = %s\n", pszGuid); bRet = TRUE; } else { printf("failed to get virtual disk ID info %d\n", ret); PrintErrorMessage(GetLastError()); } } else { printf("failed to open vdisk...err %d\n", ret); PrintErrorMessage(GetLastError()); } if (INVALID_HANDLE_VALUE != hVhd) { CloseHandle(hVhd); } return bRet; }
BOOL OpenAndCompactVHD(PCWSTR pszVhdPath) { BOOL bRet = FALSE; DWORD ret; HANDLE hVhd = INVALID_HANDLE_VALUE; OPEN_VIRTUAL_DISK_PARAMETERS oparams; COMPACT_VIRTUAL_DISK_PARAMETERS parameters; COMPACT_VIRTUAL_DISK_FLAG flags = COMPACT_VIRTUAL_DISK_FLAG_NONE; VIRTUAL_STORAGE_TYPE vst = { VIRTUAL_STORAGE_TYPE_DEVICE_VHD, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; wprintf(L"OpenAndCompactVHD %s\n", pszVhdPath); oparams.Version = OPEN_VIRTUAL_DISK_VERSION_1; oparams.Version1.RWDepth = OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT; ret = OpenVirtualDisk(&vst, pszVhdPath, VIRTUAL_DISK_ACCESS_METAOPS, OPEN_VIRTUAL_DISK_FLAG_NONE, &oparams, &hVhd); if (ERROR_SUCCESS == ret) { printf("success opening vdisk...\n"); parameters.Version = COMPACT_VIRTUAL_DISK_VERSION_1; parameters.Version1.Reserved = 0; ret = CompactVirtualDisk(hVhd, COMPACT_VIRTUAL_DISK_FLAG_NONE, ¶meters, 0); if (ERROR_SUCCESS == ret) { printf("success expanding vdisk...\n"); } else { printf("failed to expand vdisk... %d\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } } else { printf("failed to open vdisk...err %d\n", ret); PrintErrorMessage(GetLastError()); bRet = FALSE; } if (INVALID_HANDLE_VALUE != hVhd) { CloseHandle(hVhd); } return bRet; }
DWORD SampleDeleteUserMetaData( _In_ LPCWSTR VHDPath) { OPEN_VIRTUAL_DISK_PARAMETERS openParameters; VIRTUAL_STORAGE_TYPE storageType; HANDLE vhdHandle; GUID uniqueId; DWORD status; vhdHandle = NULL; status = ERROR_SUCCESS; if (VHDPath == NULL) { status = ERROR_INVALID_PARAMETER; goto Cleanup; } // // Specify UNKNOWN for both device and vendor so the system will use the // file extension to determine the correct VHD format. // storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN; storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN; // // Only V2 handles can be used to query/set/delete user metadata. // memset(&openParameters, 0, sizeof(openParameters)); openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_2; // // Open the VHD/VHDX // // VIRTUAL_DISK_ACCESS_NONE is the only acceptable access mask for V2 handle opens. // OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS indicates the parent chain should not be opened. // status = OpenVirtualDisk( &storageType, VHDPath, VIRTUAL_DISK_ACCESS_NONE, OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS, &openParameters, &vhdHandle); if (status != ERROR_SUCCESS) { goto Cleanup; } // // Use the same GUID specified in SampleSetUserMetaData. This GUID is arbitray and any // GUID can be utilized. // uniqueId.Data1 = 0x34a631f3; uniqueId.Data2 = 0xa39d; uniqueId.Data3 = 0x4e45; uniqueId.Data4[0] = 0xbb; uniqueId.Data4[1] = 0x2e; uniqueId.Data4[2] = 0x98; uniqueId.Data4[3] = 0xcf; uniqueId.Data4[4] = 0x2d; uniqueId.Data4[5] = 0xfe; uniqueId.Data4[6] = 0x4f; uniqueId.Data4[7] = 0x3d; status = DeleteVirtualDiskMetadata(vhdHandle, &uniqueId); Cleanup: if (status == ERROR_SUCCESS) { wprintf(L"success\n"); } else { wprintf(L"error = %u\n", status); } if (vhdHandle != INVALID_HANDLE_VALUE) { CloseHandle(vhdHandle); } return status; }