HANDLE vhdHandle;
_VIRTUAL_STORAGE_TYPE storageType;
storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;
wchar_t path[] = L"C:\\Hyper-V\\Virtual Hard Disks\\L\\Windows2016.vhdx";
VIRTUAL_DISK_ACCESS_MASK mask = VIRTUAL_DISK_ACCESS_GET_INFO;
PGET_VIRTUAL_DISK_INFO diskInfo;
ULONG diskInfoSize = sizeof(GET_VIRTUAL_DISK_INFO) + sizeof(changeTrackingInfo);
std::wcout << "size of diskinfo structure " << diskInfoSize << std::endl;
diskInfo = (PGET_VIRTUAL_DISK_INFO)malloc(diskInfoSize);
...
OPEN_VIRTUAL_DISK_PARAMETERS *openParameters = NULL;
DWORD res = OpenVirtualDisk(&storageType, path,
VIRTUAL_DISK_ACCESS_GET_INFO | VIRTUAL_DISK_ACCESS_DETACH | VIRTUAL_DISK_ACCESS_ATTACH_RO,
OPEN_VIRTUAL_DISK_FLAG_NONE,
openParameters,
&vhdHandle);
diskInfo->Version = GET_VIRTUAL_DISK_INFO_SIZE;
res = GetVirtualDiskInformation(vhdHandle, &diskInfoSize, diskInfo, &szUsed);
ULONGLONG physicalSize = diskInfo->Size.PhysicalSize;
ULONGLONG virtualSize = diskInfo->Size.VirtualSize;
ULONG sectorSize = diskInfo->Size.SectorSize;
ULONG blockSize = diskInfo->Size.BlockSize;
diskInfo->Version = (GET_VIRTUAL_DISK_INFO_VERSION)GET_VIRTUAL_DISK_INFO_CHANGE_TRACKING_STATE;
szUsed = NULL;
res = GetVirtualDiskInformation(vhdHandle, &diskInfoSize, diskInfo, &szUsed);
if (res != ERROR_SUCCESS)
{
std::cout << "Failed to GET_VIRTUAL_DISK_INFO_CHANGE_TRACKING_STATE, ret=" << res << std::endl;
}
std::wcout << "\nrct id:" << diskInfo->ChangeTrackingState.MostRecentId << std::endl;
std::wcout << "\change tracking enabled: " << diskInfo->ChangeTrackingState.Enabled << std::endl;
WCHAR* rctId = diskInfo->ChangeTrackingState.MostRecentId;
//to get incr changes we used rct id like this L"rctX:c2eb01d9:ccb1:405d:acb6:f0e76d055906:00000001";
//to get allocated blocks for full backup we used rct is as "*", "0", etc.
std::wcout << "\nQuerying for changed disk areas..." << rctId << std::endl;
ULONG64 byteOffset = 0;
ULONG64 byteLength = 19327352832; //set disk max internal size.
QUERY_CHANGES_VIRTUAL_DISK_RANGE* changedAreas = NULL;
ULONG rangeCount = 0;
ULONG64 processedLength = 0;
res = QueryChangesVirtualDisk(vhdHandle, rctId, byteOffset, byteLength,
QUERY_CHANGES_VIRTUAL_DISK_FLAG_NONE,
changedAreas, &rangeCount, &processedLength);
if (res != ERROR_SUCCESS)
{
std::cout << "Failed to get changed areas, ret=" << res << std::endl;
;
}
....