Каковы правильные параметры для CREATE_VIRTUAL_DISK_VERSION_2?

когда я запускаю 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;

person michl2007    schedule 25.06.2016    source источник
comment
Какую ОС вы используете? Версия 2 не поддерживается до Windows 8.   -  person Jonathan Potter    schedule 26.06.2016
comment
Просто чтобы вы знали, что документация MSDN для API виртуального диска ужасна. Куча вещей отсутствует или неверна.   -  person theB    schedule 26.06.2016
comment
Какой тип устройства вы на самом деле создаете? Значения различаются в зависимости от того, является ли это VHD, VHDX или VHD Set.   -  person cogumel0    schedule 26.06.2016
comment
В вашем коде не хватает нескольких вещей, таких как вызов фактического метода CreateVirtualDisk(). Можете ли вы также вставить свою структуру CREATE_VIRTUAL_DISK_PARAMETERS?   -  person cogumel0    schedule 26.06.2016
comment
Вы также пытались установить SourcePath на ноль? Предположительно, в настоящее время он имеет значение пустой строки.   -  person cogumel0    schedule 26.06.2016
comment
Я отредактировал свой вопрос. Я попытался установить SourcePath на ноль, но безуспешно.   -  person michl2007    schedule 26.06.2016
comment
В будущем я хочу создавать файлы VHD и VHDX (фиксированные, динамические и разностные) одним вызовом метода. Тип виртуального диска, который вы хотите создать (VHD, VHDX, набор VHD), не имеет ничего общего с используемой версией структуры. Вы можете создать VHDX, используя структуру V1, точно так же, как вы можете создать VHD, используя структуру V2. Все новые структуры дают новые функции. Например, используя V1, вы не можете указать PhysicalSectorSizeInBytes при создании виртуального диска, а также не можете вызывать определенные методы, такие как метод ResizeVirtualDisk().   -  person cogumel0    schedule 26.06.2016


Ответы (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; BackingStorageType: 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;
person michl2007    schedule 26.06.2016
comment
Хотя это могло решить вашу проблему, я боюсь, что это не правильный ответ. Структура CREATE_VIRTUAL_DISK_PARAMETERS.Version2 не содержит ни члена SourceLimitPath, ни члена BackingStorageType, а CREATE_VIRTUAL_DISK_PARAMETERS.Version3 содержит... Таким образом, возможно, для вашей внутренней структуры CREATE_VIRTUAL_DISK_VERSION_2 установлено значение 3, а не 2. Я могу предоставить вам копию всей структуры из заголовков Windows 10 SDK, если вам это нужно. Проблема не в вашей структуре и не в том, какие значения вы указываете, поэтому предоставьте весь необходимый код. - person cogumel0; 26.06.2016
comment
Вот ошибка: params.Version1.SourcePath := nil; -> params.Version2.SourcePath := nil; @cogumel0: Вы правы, я удалил эти два параметра, и они работают. - person michl2007; 26.06.2016
comment
Итак, проблема всегда заключалась в том, что SourcePath всегда был установлен в пустую строку, а не nil тогда? - person cogumel0; 26.06.2016
comment
ваш код выше все еще содержит params.Version1.SourcePath := nil;. - person cogumel0; 26.06.2016
comment
Если сравнить код до и после, вот в чем разница. Однако его следует называть версией 2, а не версией 1. - person michl2007; 27.06.2016
comment
Я до сих пор не понимаю, почему вы используете V1 для VHD и V2 для VHDX. Просто используйте один из двух для всего. - person cogumel0; 27.06.2016
comment
V2 не для win7/2008R2. В более новых системах я использую V2 - person michl2007; 28.06.2016
comment
Я хочу сказать, что более новые системы также поддерживают структуру V1. Если вам действительно не нужны дополнительные возможности, которые предлагает структура V2, чего, скажем честно, почти никто не делает, то вам следует просто использовать одну структуру для всего... Что дает вам структура V2 что вам нужно иметь, чего нет в структуре V1? - person cogumel0; 01.07.2016
comment
У нас есть клиенты, и они используют Server 2008R2, и они не будут обновляться до более новой версии. Так что мне нужна структура v1 - person michl2007; 10.07.2016
comment
Вы до сих пор не понимаете, что я пытаюсь сказать. Структура V1 позволяет создавать файлы VHD и VHDX. Так почему бы просто не использовать структуру V1 для создания VHD, VHDX, VHD Set в Windows 2008, Windows 2008 R2, Windows 2012, Windows 2012 R2 и Windows 2016? Структура V1 будет работать на всех ОС, начиная с Windows 2008, и работать на всех типах VHD. Период. Вы теряете некоторые функции, но вопрос именно в том, что вам нужно. Если вы просто хотите создать диск, проще всего использовать V1 для всего. Будь проще. - person cogumel0; 13.07.2016
comment
Хорошо, теперь я тебя понимаю. Моя проблема: когда я создаю VHDX с V1, мне не удается открыть диск с помощью проводника Windows 10 (диск поврежден). Если я использую функцию присоединения из V1, диск смонтирован и готов. - person michl2007; 19.07.2016
comment
Это звучит как ошибка для меня. - person cogumel0; 19.07.2016
comment
INVALID_HANDLE_VALUE неверно. Документ CreateVirtualDisk указывает, что возвращаемое значение дескриптора диска не определено, если вызов API возвращает значение, отличное от ERROR_SUCCESS. Вызывающий должен установить значение hvhd в INVALID_HANDLE_VALUE, если вызов не удался. - person Cristian Amarie; 17.01.2019