2016-06-25 2 views
0

Когда я запускаю CreateVritualDisk, я получаю ошибку 87 (ERROR_INVALID_PARAMETER). Предположительно, отсутствует параметр или неверен. Проблема с версией CREATE_VIRTUAL_DISK_VERSION_2, CREATE_VIRTUAL_DISK_VERSION_1 выполняется успешно.Каковы правильные параметры для CREATE_VIRTUAL_DISK_VERSION_2?

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; 

Я уже пробовал несколько комбинаций, но не удался.

EDIT: Я использую 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; 
+0

Какой ОС вы используете? Версия 2 не поддерживается до Windows 8. –

+0

Просто вы знаете, что документация MSDN для API виртуальных дисков ужасна. Куча вещей отсутствует или неверна. – theB

+0

Какой тип устройства вы на самом деле создаете? Значения различаются в зависимости от того, является ли это VHD, VHDX или VHD Set – cogumel0

ответ

0

У меня есть. У меня есть эти параметры:

// 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; 
+1

Хотя это, возможно, устранило вашу проблему, я боюсь, что это не правильный ответ. 'CREATE_VIRTUAL_DISK_PARAMETERS.Version2' struct не содержит ни параметра' SourceLimitPath', ни '' BackingStorageType', 'CREATE_VIRTUAL_DISK_PARAMETERS.Version3' ... Так что может быть, что ваш' CREATE_VIRTUAL_DISK_VERSION_2' установлен на 3, а не на 2 на вашем внутреннем структура. Я могу предоставить вам копию всей структуры из заголовков Windows 10 SDK, если она вам нужна. Проблема заключается ни в вашей структуре, ни в каких значениях, которые вы указываете, поэтому укажите * все * необходимый код. – cogumel0

+0

Вот ошибка: params.Version1.SourcePath: = nil; -> params.Version2.SourcePath: = nil; @ cogumel0: Вы правы, я удалил эти два параметра, и он работает. – michl2007

+0

Итак, проблема всегда заключалась в том, что SourcePath был установлен на пустую строку, а не на «nil»? – cogumel0