Error: Access denied when using the function 'CreateVirtualDisk' in WIN7

Unanswered Error: Access denied when using the function 'CreateVirtualDisk' in WIN7

  • Tuesday, July 06, 2010 8:35 PM
     
     
    Hello everyone,

    Right now I am experimenting with the CreateVirtualDisk function to create a VHD from both physical disk and virtual disk. I had no problem with creating a new VHD from a virtual disk, but from a physical disk, I got the error: Access is denied. I always ran the program with the administrator rights so in theory it should work out but it didn’t. I really don’t know what went wrong here.

    I used the PInvoke to call this method from C#, this is how I defined the function and the relevant structure:

    Definition of the function:

    [DllImport ("virtdisk.dll" , CharSet = CharSet .Unicode)]

          public static extern Int32 CreateVirtualDisk(

             ref VIRTUAL_STORAGE_TYPE VirtualStorageType,

             String Path,

             _VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask,

             IntPtr SecurityDescriptor,

             _CREATE_VIRTUAL_DISK_FLAG Flags,

             Int32 ProviderSpecificFlags,

             ref CREATE_VIRTUAL_DISK_PARAMETERS Parameters,

             IntPtr Overlapped,

             ref VirtualDiskSafeHandle Handle);

    Definition of CREATE_VIRTUAL_DISK_PARAMETER:

          public struct CREATE_VIRTUAL_DISK_PARAMETERS

          {

             /// <summary>

             /// An enum specifies the version of the CREATE_VIRTUAL_DISK_PARAMETERS structure being passed to or from the VHD functions.

             /// </summary>

             public _CREATE_VIRTUAL_DISK_VERSION Version;

     

             /// <summary>

             /// Version1

             /// </summary>

             public CREATE_VIRTUAL_DISK_PARAMETERS_VERSION1 Version1;

          }

    Definition of CREATE_VIRTUAL_DISK_PARAMETER_VERSION1:

    public struct CREATE_VIRTUAL_DISK_PARAMETERS_VERSION1

          {

             /// <summary>

             /// Unique identifier to assign to the virtual disk object. If this member is set to zero, a unique identifier is created by the system.

             /// </summary>

             public Guid UniqueId;

     

             /// <summary>

             /// The maximum virtual size of the virtual disk object. Must be a multiple of 512.

             /// </summary>

             public Int64 MaximumSize;

     

             /// <summary>

             /// Internal size of the virtual disk object blocks.

             /// </summary>

             public Int32 BlockSizeInBytes;

     

             /// <summary>

             /// Internal size of the virtual disk object sectors. Must be set to 512.

             /// </summary>

             public Int32 SectorSizeInBytes;

     

             /// <summary>

             /// Optional fully qualified path to a parent virtual disk object. Associates the new virtual disk with an existing virtual disk

             /// </summary>

             public IntPtr ParentPath;

     

             /// <summary>

             /// Optional fully qualified path to pre-populate the new virtual disk object with block data from an existing disk. This path may refer to a virtual disk or a physical disk.

             /// </summary>

             public IntPtr SourcePath;

          }

     

    And this is how I received the error:

    I set all the parameters like this:

    ·         VIRTUAL_STORAGE_TYPE:

    o    virtualStorageType.DeviceID = VIRTUAL_STORAGE_TYPE_DEVICE_VHD;

    o   virtualStorageType.VendorID = VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT;

    ·         PATH:

    o   m_path = “D:\VirtualDisk\test.vhd”;

    ·         VIRTUAL_DISK_ACCESS_MASK:

    o   virtualDiskAccessMask = VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_CREATE;

    ·         SECURITY_DESCRIPTOR:

    o   securityDescriptor = IntPtr .Zero;

    ·         CREATE_VIRTUAL_DISK_FLAG:

    o   createVirtualDiskFlag = CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION

    ·         ProviderSpecificFlag:

    o   providerSpecificFlag = 0;

    ·         CREATE_VIRTUAL_DISK_PARAMETER:

    o    m_createVirtualDiskParameters.Version = _CREATE_VIRTUAL_DISK_VERSION .CREATE_VIRTUAL_DISK_VERSION_1;

    o    m_createVirtualDiskParameters.Version1.UniqueId = Guid .Empty;

    o    m_createVirtualDiskParameters.Version1.MaximumSize = 0;

    o    m_createVirtualDiskParameters.Version1.BlockSizeInBytes = 0;

    o    m_createVirtualDiskParameters.Version1.SectorSizeInByte = VirtualDisk .CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_SECTOR_SIZE;

    o    m_createVirtualDiskParameters.Version1.ParentPath = IntPtr .Zero;

    o   m_createVirtualDiskParameters.Version1.SourcePath = Marshal .StringToHGlobalAuto(sourcepath );

    ·         OVERLAPPED:

    o   Overlapped  = IntPtr .Zero ;

    ·         HANDLE:

    o   handle

    I have tried with many values of the string variable ‘sourcepath and here are the results:

    1.  With the absolute path of an existing virtual disk:

    sourcepath = @"D:\VirtualDisk\KarhuBearOS.vhd";

    Success!

    2.  With the absolute path of a physical disk:

    sourcepath = @"C:\";

    Failed! à Access is denied.

    3.  With a volume ID created by VSS Service:

    sourcepath = @"\\?\Volume{a3c3c244-8b7a-11de-a777-806e6f6e6963}\ "

    Failed! à Access is denied.

    4.  With the absolute path of a volume ID created by VSS Service

    sourcepath = @"\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy30\ "

    Failed! à Access is denied.

     

    I will greatly appreciate your help if you can show me the way to correct this problem.

    My very best,

    Hoang Anh Nguyen