J Evans
J Evans

Reputation: 1122

Creating VHD files with the VirtualDisk API

I'm trying to use a VSS snapshot as the source for CreateVirtualDisk(). Environment/tools are C++ VS2008SP1 and 7.1 SDK on W7x64Ultimate

[Edited]

This works on Windows 7 x64

BOOL CreateVHD_Fixed(PCWSTR pszVhdPath, ULONG sizeInMB)
{
    BOOL bRet = FALSE;
    HANDLE hvhd;
    CREATE_VIRTUAL_DISK_PARAMETERS  params;
    VIRTUAL_DISK_ACCESS_MASK        mask;
    VIRTUAL_STORAGE_TYPE            vst =
    {
        VIRTUAL_STORAGE_TYPE_DEVICE_VHD,
        VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT
    };

    wprintf(L"CreateVHD_Fixed %s, size (MB) %d\n", pszVhdPath, sizeInMB);

    params.Version1.UniqueId            = GUID_NULL;
    params.Version1.BlockSizeInBytes    = 0;
    params.Version1.MaximumSize         = sizeInMB * 1024 * 1024;
    params.Version1.ParentPath          = NULL;
    params.Version1.SourcePath          = NULL;
    params.Version1.SectorSizeInBytes   = 512;
    params.Version          = CREATE_VIRTUAL_DISK_VERSION_1;
    mask                                = VIRTUAL_DISK_ACCESS_CREATE;

    DWORD ret = CreateVirtualDisk(&vst, 
        pszVhdPath, 
        mask, 
        NULL, 
        // To create a dynamic disk, use CREATE_VIRTUAL_DISK_FLAG_NONE instead.
        CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION, 
        0, 
        &params, 
        NULL, 
        &hvhd);

    if (ret == ERROR_SUCCESS)
    {
        bRet = TRUE;
    }
    else
    {
        bRet = FALSE;
        printf("failed to create vdisk...err 0x%x\n", ret);
        PrintErrorMessage(GetLastError());
    }

    if (INVALID_HANDLE_VALUE != hvhd)
    {
        CloseHandle(hvhd);
    }

    return bRet;
}

[Edited] - now failing in a different way with ERROR_INVALID_PARAMETER. Parameters are below with a root path of "\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy64"

    VIRTUAL_STORAGE_TYPE storageType =
    {
        VIRTUAL_STORAGE_TYPE_DEVICE_VHD,
        // do not use any other GUID else you get an unknown provider error
        VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT // **critical!**
    };

    VIRTUAL_DISK_ACCESS_MASK vdam = (VIRTUAL_DISK_ACCESS_MASK)(VIRTUAL_DISK_ACCESS_CREATE); // |VIRTUAL_DISK_ACCESS_WRITABLE|VIRTUAL_DISK_ACCESS_READ|VIRTUAL_DISK_ACCESS_GET_INFO);
    CREATE_VIRTUAL_DISK_FLAG flags = CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION; // CREATE_VIRTUAL_DISK_FLAG_NONE;
    CREATE_VIRTUAL_DISK_PARAMETERS parameters;
    //
    parameters.Version = CREATE_VIRTUAL_DISK_VERSION_1;
    parameters.Version1.UniqueId = GUID_NULL;
    parameters.Version1.MaximumSize = 0;
    parameters.Version1.BlockSizeInBytes = CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE;
    parameters.Version1.ParentPath = 0;
    parameters.Version1.SourcePath = root.c_str();
    parameters.Version1.SectorSizeInBytes = CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_SECTOR_SIZE;
    ULONG ProviderSpecificFlags = 0;

HANDLE handle = 0;
dwRet = CreateVirtualDisk(&storageType,
_T("t:\\test.vhd"),
vdam,
NULL,
flags,
ProviderSpecificFlags,
&parameters,0,&handle);

Any ideas? The virtual disk API does not seem to have much example code.

Thx++

Jerry.

Upvotes: 2

Views: 5261

Answers (1)

Bharath Ravindra
Bharath Ravindra

Reputation: 81

Jerry,

Use CreateVirtualDisk API to create a VHD or a differential VHD, make sure u send the right parameters. You have to specify the parent hard disk but not the source hard disk. Care must also be taken while using the flags.

Refer the links below: "http://code.msdn.microsoft.com/windowshardware/CppVhdAPI-4412d182"

and

"http://code.msdn.microsoft.com/windowsdesktop/Virtual-hard-disk-03108ed3"

Upvotes: 0

Related Questions