【问题标题】:VirtDisk.h QueryChangesVirtualDisk() function return RangeCount as 0VirtDisk.h QueryChangesVirtualDisk() 函数将 RangeCount 返回为 0
【发布时间】:2020-05-28 20:42:40
【问题描述】:

https://docs.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
);

我正在尝试获取两个虚拟磁盘或两个 Resillent Change Tracking ID (RCT) 之间的差异

RangeCount 总是返回为 0

我用两个枚举参数VIRTUAL_DISK_ACCESS_GET_INFOOPEN_VIRTUAL_DISK_FLAG_NONE打开了虚拟磁盘文件(vhdx)

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 fail\n");
        goto Cleanup;
    }

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

    wprintf(L"rctRangeCnt : %lu\n", rctRangeCnt);
    wprintf(L"processedLength : %llu\n", processedLength);

    for (i = 0; i < rctRangeCnt; i++)
    {
        wprintf(L"ByteOffset : %lld   ByteLength : %lld\n", pRctRanges[i].ByteOffset, pRctRanges[i].ByteLength);
    }

    if (opStatus != ERROR_SUCCESS)
    {
        wprintf(L"QueryChangesVirtualDisk fail\n");
        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);
    }

    if (diskInfo != NULL)
    {
        free(diskInfo);
    }

    if (pRctRanges != NULL)
    {
        for (i = 0; i < rctRangeCnt; i++)
        {
            free(&pRctRanges[i]);
        }
    }

    return opStatus;
}

【问题讨论】:

    标签: c++ hyper-v windows-server-2016 change-tracking virtual-disk


    【解决方案1】:

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

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

    QueryChangesVirtualDisk 函数返回时,它会将RangeCount 修改为Ranges 数组中已初始化元素的数量。

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

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

    简而言之:函数不会为你创建这个数组,你必须在调用函数之前创建。

    【讨论】:

    • 下次我应该更仔细地阅读文档...谢谢您的帮助
    • @TK_WooDong 是否在快照和运行虚拟机的基础磁盘上工作,或者您是否在离线虚拟机上查询更改的块?使用正在运行的虚拟机,我被拒绝访问..任何指针?
    猜你喜欢
    • 1970-01-01
    • 2023-02-11
    • 2020-12-01
    • 2018-04-28
    • 2015-12-03
    • 2012-03-09
    • 1970-01-01
    • 2018-04-17
    • 2016-06-05
    相关资源
    最近更新 更多