Error: Access denied when using the function 'CreateVirtualDisk' in WIN7
-
Tuesday, July 06, 2010 8:35 PMHello 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


