VirtDisk.h QueryChangesVirtualDisk() 函数返回 RangeCount 为 0

VirtDisk.h QueryChangesVirtualDisk() function return RangeCount as 0

本文关键字:返回 RangeCount 函数 QueryChangesVirtualDisk VirtDisk      更新时间:2023-10-16

https://learn.microsoft.com/ko-kr/windows/win32/api/virtdisk/nf-virtdisk-querychangesvirtualdisk?redirectedfrom=MSDN

DWORD QueryChangesVirtualDisk(
HANDLE                            VirtualDiskHandle,
PCWSTR                            ChangeTrackingId,
ULONG64                           ByteOffset,
ULONG64                           ByteLength,
QUERY_CHANGES_VIRTUAL_DISK_FLAG   Flags,
PQUERY_CHANGES_VIRTUAL_DISK_RANGE Ranges,
PULONG                            RangeCount,
PULONG64                          ProcessedLength
);

我正在尝试获取两个虚拟磁盘或两个弹性更改跟踪 ID (RCT( 之间的区别

RangeCount总是返回为 0

我打开了带有两个枚举参数VIRTUAL_DISK_ACCESS_GET_INFO的虚拟磁盘文件 (vhdx(,OPEN_VIRTUAL_DISK_FLAG_NONE

opStatus = OpenVirtualDisk(
&storageType,
VirtualDiskPath,
VIRTUAL_DISK_ACCESS_GET_INFO,
OPEN_VIRTUAL_DISK_FLAG_NONE,
NULL,
&vhdHandle ); // output handle

然后使用QueryChangesVirtualDisk()

opStatus = QueryChangesVirtualDisk(
vhdHandle,
ChangeTrackingId,
0,
32212254720,
QUERY_CHANGES_VIRTUAL_DISK_FLAG_NONE,
pRctRanges,
&rctRangeCnt,
&processedLength
);

OpenVirtualDisk()QueryChangesVirtualDisk()

这两个函数都没有返回错误,但在每种情况下RangeCount值始终为 0

虚拟磁盘文件和 RCT ID 之间肯定有区别

请给我一些建议

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <initguid.h>
#include <strsafe.h>
#include <virtdisk.h>
#include "Storage.h"
DWORD QueryChangesVirtualDisk(_In_    LPCWSTR     VirtualDiskPath, _In_    LPCWSTR     ChangeTrackingId)
{
VIRTUAL_STORAGE_TYPE storageType;
PGET_VIRTUAL_DISK_INFO diskInfo;
ULONG diskInfoSize;
DWORD opStatus;
HANDLE vhdHandle;
QUERY_CHANGES_VIRTUAL_DISK_RANGE *pRctRanges;
ULONG                            rctRangeCnt;
ULONG64                          processedLength;
UINT                             i;
vhdHandle = INVALID_HANDLE_VALUE;
diskInfo = NULL;
diskInfoSize = sizeof(GET_VIRTUAL_DISK_INFO);
rctRangeCnt = 0L;
processedLength = 0L;
pRctRanges = NULL;
i = 0;
diskInfo = (PGET_VIRTUAL_DISK_INFO)malloc(diskInfoSize);
if (diskInfo == NULL)
{
opStatus = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;
//////////////////////////////////////////////////////////////////
opStatus = OpenVirtualDisk(
&storageType,
VirtualDiskPath,
VIRTUAL_DISK_ACCESS_GET_INFO,
OPEN_VIRTUAL_DISK_FLAG_NONE,
NULL,
&vhdHandle);
if (opStatus != ERROR_SUCCESS)
{
wprintf(L"OpenVirtualDisk failn");
goto Cleanup;
}
opStatus = QueryChangesVirtualDisk(
vhdHandle,
ChangeTrackingId,
0,
32212254720,
QUERY_CHANGES_VIRTUAL_DISK_FLAG_NONE,
pRctRanges,
&rctRangeCnt,
&processedLength
);
wprintf(L"rctRangeCnt : %lun", rctRangeCnt);
wprintf(L"processedLength : %llun", processedLength);
for (i = 0; i < rctRangeCnt; i++)
{
wprintf(L"ByteOffset : %lld   ByteLength : %lldn", pRctRanges[i].ByteOffset, pRctRanges[i].ByteLength);
}
if (opStatus != ERROR_SUCCESS)
{
wprintf(L"QueryChangesVirtualDisk failn");
goto Cleanup;
}
Cleanup:
if (opStatus == ERROR_SUCCESS)
{
wprintf(L"successn");
}
else
{
wprintf(L"error = %un", opStatus);
}
if (vhdHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(vhdHandle);
}
if (diskInfo != NULL)
{
free(diskInfo);
}
if (pRctRanges != NULL)
{
for (i = 0; i < rctRangeCnt; i++)
{
free(&pRctRanges[i]);
}
}
return opStatus;
}

问题是你为Ranges参数传递一个空指针,为RangeCount传递零。

对于Ranges,您应该传递指向第一个元素或QUERY_CHANGES_VIRTUAL_DISK_RANGE元素数组的指针,并且RangeCount应初始化为该数组中的元素数。

QueryChangesVirtualDisk函数返回时,它将修改RangeCountRanges数组中初始化元素的数量。

从您链接到的文档,关于RangeCount参数:

在输入时,该值指示Ranges参数指向的数组可以容纳的QUERY_CHANGES_VIRTUAL_DISK_RANGE结构数。在输出时,该值包含方法放置在数组中的QUERY_CHANGES_VIRTUAL_DISK_RANGE结构数。

简而言之:该函数不会为您创建此数组,您必须在调用该函数之前执行此操作。