views:

31

answers:

0

Hello everyone,

Right now I am experimenting with the CreateVirtualDisk function to create a VHD from both physical disk and virtual disk. I have got stuck here for one week because of the error: Access is denied when I tried to create a VHD from a physical disk. 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.

You can find VHD API document here: VHD

I used the PInvoke to call this method from the library 'virtdisk.dll', this is how I defined 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);

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: // name of the new VHD file
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