【问题标题】:What are the correct parameters for CREATE_VIRTUAL_DISK_VERSION_2?CREATE_VIRTUAL_DISK_VERSION_2 的正确参数是什么?
【发布时间】:2016-06-25 22:54:57
【问题描述】:

当我运行 CreateVritualDisk 时,我收到错误 87 (ERROR_INVALID_PARAMETER)。大概是缺少参数或不正确。问题在于版本 CREATE_VIRTUAL_DISK_VERSION_2,CREATE_VIRTUAL_DISK_VERSION_1 运行成功。

function TForm3.CreateVHDX(const AFilePath: string; const ASize: ULONG; const AType: integer; out AReturn: DWORD): Boolean;
var
  params: TCreateVirtualDiskParameters;
  mask: TVIRTUAL_DISK_ACCESS_MASK;
  vst: TVirtualStorageType;
  hvhd: THandle;
  begin
  hVhd := INVALID_HANDLE_VALUE;

//  vst.DeviceId := VIRTUAL_STORAGE_TYPE_DEVICE_VHDX;
  vst.DeviceId := VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
//  vst.VendorId := VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT ;
  vst.VendorId := VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;

  params.Version:= CREATE_VIRTUAL_DISK_VERSION_2;
  params.Version2.UniqueId := TGUID.Empty;
  params.Version2.MaximumSize:= ASize * 1024 * 1024;
  params.Version2.BlockSizeInBytes := CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE; //0
  params.Version2.SectorSizeInBytes := $200;
  params.Version2.PhysicalSectorSize := $200;
  params.Version2.ParentPath := nil;
//  params.Version2.OpenFlags := OPEN_VIRTUAL_DISK_FLAG_NONE;
  params.Version2.ResiliencyGuid := TGUID.Empty;
//  params.Version2.ParentVirtualStorageType := ;

  mask := VIRTUAL_DISK_ACCESS_NONE;

  if AType = 0 then //dynamic
  begin
    AReturn := CreateVirtualDisk(
      @vst,
      PWideChar(AFilePath),
      mask,
      nil,
      CREATE_VIRTUAL_DISK_FLAG_NONE,
      0,
      @params,
      nil,
      hvhd);
      Result := AReturn = ERROR_SUCCESS;
  end;

  if AType = 1 then //fixed
  begin
    AReturn := CreateVirtualDisk(
    @vst,
    PWideChar(AFilePath),
    mask,
    nil,
    CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION,
    0,
    @params,
    nil,
    hvhd);
 Result := AReturn = ERROR_SUCCESS;
 end;

 if hvhd <> INVALID_HANDLE_VALUE then
   CloseHandle( hvhd )
 end;

我已经尝试了几种组合,但都没有成功。

编辑: 我使用 Windows 10。 将来,我想用一个方法调用创建 VHD 和 VHDX 文件(固定、动态和差分)。 此时,我想创建 VHDX(固定、动态和差分)。

TCreateVirtualDiskParametersVersion2 = record
  UniqueId: TGUID;
  MaximumSize: ULONGLONG;
  BlockSizeInBytes: ULONG;
  SectorSizeInBytes: ULONG;
  PhysicalSectorSize: ULONG;
  ParentPath: LPCWSTR;
  SourcePath: LPCWSTR;
  OpenFlags: TOPEN_VIRTUAL_DISK_FLAG;
  ParentVirtualStorageType: VIRTUAL_STORAGE_TYPE;
  SourceVirtualStorageType: VIRTUAL_STORAGE_TYPE;
  ResiliencyGuid: TGUID;
end;

【问题讨论】:

  • 您使用的是什么操作系统? Windows 8 之前不支持版本 2。
  • 您知道虚拟磁盘 API 的 MSDN 文档很糟糕。一堆东​​西丢失或不正确。
  • 您实际创建的是什么类型的设备?这些值取决于它是 VHD、VHDX 还是 VHD 集
  • 您的代码缺少一些东西,例如对实际 CreateVirtualDisk() 方法的调用。你也可以粘贴你的CREATE_VIRTUAL_DISK_PARAMETERS 结构吗?
  • 您是否尝试过将SourcePath 也设置为零?大概它当前的值为空字符串。

标签: winapi vhd


【解决方案1】:

我明白了。 我有这个参数:

//  vst.DeviceId := VIRTUAL_STORAGE_TYPE_DEVICE_VHDX;
  vst.DeviceId := VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
//  vst.VendorId := VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT ;
  vst.VendorId := VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;

  params.Version:= CREATE_VIRTUAL_DISK_VERSION_2;
  params.Version2.UniqueId := TGUID.Empty;
  params.Version2.MaximumSize:= ASize * 1024 * 1024;
  params.Version2.BlockSizeInBytes := CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE; //0
  params.Version2.SectorSizeInBytes := 0;
  params.Version2.PhysicalSectorSize := 0;
  params.Version2.ParentPath := nil;
  params.Version2.SourcePath := nil;
  params.Version2.OpenFlags := OPEN_VIRTUAL_DISK_FLAG_NONE;
  params.Version2.ResiliencyGuid := TGUID.Empty;
//  params.Version2.ParentVirtualStorageType := ;

  mask := VIRTUAL_DISK_ACCESS_NONE;

TCreateVirtualDiskParametersVersion2 记录中缺少两个参数。 我添加了:SourceLimitPath:LPCWSTR;支持存储类型:VIRTUAL_STORAGE_TYPE;

新记录:

TCreateVirtualDiskParametersVersion2 = record
  UniqueId: TGUID;
  MaximumSize: ULONGLONG;
  BlockSizeInBytes: UINT;
  SectorSizeInBytes: UINT;
  PhysicalSectorSize: UINT;
  ParentPath: LPCWSTR;
  SourcePath: LPCWSTR;
  OpenFlags: TOPEN_VIRTUAL_DISK_FLAG;
  ParentVirtualStorageType: VIRTUAL_STORAGE_TYPE;
  SourceVirtualStorageType: VIRTUAL_STORAGE_TYPE;
  ResiliencyGuid: TGUID;
  SourceLimitPath: LPCWSTR;
  BackingStorageType: VIRTUAL_STORAGE_TYPE;
end;

我的临时工作职能:

function TForm3.CreateVHDX(const AFilePath: string; const ASize: ULONG; const AType: integer; out AReturn: DWORD): Boolean;
var
  params: TCreateVirtualDiskParameters;
  mask: TVIRTUAL_DISK_ACCESS_MASK;
  vst: TVirtualStorageType;
  hvhd: THandle;
begin
  hVhd := INVALID_HANDLE_VALUE;

//  vst.DeviceId := VIRTUAL_STORAGE_TYPE_DEVICE_VHDX;
  vst.DeviceId := VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
//  vst.VendorId := VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT ;
  vst.VendorId := VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;

  params.Version:= CREATE_VIRTUAL_DISK_VERSION_2;
  params.Version2.UniqueId := TGUID.Empty;
  params.Version2.MaximumSize:= ASize * 1024 * 1024;
  params.Version2.BlockSizeInBytes := CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE; //0
  params.Version2.SectorSizeInBytes := 0;
  params.Version2.PhysicalSectorSize := 0;
  params.Version2.ParentPath := nil;
  params.Version1.SourcePath := nil;
  params.Version2.OpenFlags := OPEN_VIRTUAL_DISK_FLAG_NONE;
  params.Version2.ResiliencyGuid := TGUID.Empty;
//  params.Version2.ParentVirtualStorageType := ;

  mask := VIRTUAL_DISK_ACCESS_NONE;

  if AType = 0 then //dynamic
  begin
    AReturn := CreateVirtualDisk(
      @vst,
      PWideChar(AFilePath),
      mask,
      nil,
      CREATE_VIRTUAL_DISK_FLAG_NONE,
      0,
      @params,
      nil,
      hvhd);
    Result := AReturn = ERROR_SUCCESS;
  end;

  if AType = 1 then //fixed
  begin
    AReturn := CreateVirtualDisk(
      @vst,
      PWideChar(AFilePath),
      mask,
      nil,
      CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION,
      0,
      @params,
      nil,
      hvhd);
    Result := AReturn = ERROR_SUCCESS;
  end;

  if hvhd <> INVALID_HANDLE_VALUE then
    CloseHandle( hvhd );
end;

【讨论】:

  • 虽然这可能解决了您的问题,但恐怕它不是正确答案。 CREATE_VIRTUAL_DISK_PARAMETERS.Version2 结构不包含 SourceLimitPathBackingStorageType 成员,CREATE_VIRTUAL_DISK_PARAMETERS.Version3 确实...因此,您的内部结构上的 CREATE_VIRTUAL_DISK_VERSION_2 可能设置为 3 而不是 2。如果您需要,我可以从 Windows 10 SDK 的标头中为您提供整个结构的副本。问题既不在您的结构中,也不在您指定的值中,因此请提供 all 所需的代码。
  • 这是一个错误:params.Version1.SourcePath := nil; -> params.Version2.SourcePath := nil; @cogumel0:你说得对,我已经删除了这两个参数并且它可以工作。
  • 那么,问题始终是 SourcePath 设置为空字符串而不是 nil 那么?
  • 您上面的代码仍然包含params.Version1.SourcePath := nil;
  • 如果比较之前和之后的代码,这就是区别。但是,它应该被称为版本 2 而不是版本 1。
猜你喜欢
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 2021-01-05
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多