mirror of https://github.com/dahall/Vanara.git
FIxes and improvements to PInvoke.VirtDisk (some breaking changes) and Vanara.VirtualDisk (chaged Enabled to ResilientChangeTrackingEnabled to avoid confusion).
parent
221385fd00
commit
ecdd314dff
|
@ -11,7 +11,10 @@ namespace Vanara.PInvoke
|
|||
public static partial class VirtDisk
|
||||
{
|
||||
/// <summary>The virtual storage type vendor Microsoft</summary>
|
||||
public static readonly Guid VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT = new Guid("EC984AEC-A0F9-47e9-901F-71415A66345B");
|
||||
public static readonly Guid VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT = new(0xec984aec, 0xa0f9, 0x47e9, 0x90, 0x1f, 0x71, 0x41, 0x5a, 0x66, 0x34, 0x5b);
|
||||
|
||||
/// <summary>The virtual storage type vendor unknown.</summary>
|
||||
public static readonly Guid VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN = new(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
/// <summary>Contains flags affecting the behavior of the ApplySnapshotVhdSet function.</summary>
|
||||
[PInvokeData("VirtDisk.h", MSDNShortId = "mt638035")]
|
||||
|
@ -827,7 +830,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
public static extern Win32Error AddVirtualDiskParent(VIRTUAL_DISK_HANDLE VirtualDiskHandle, [MarshalAs(UnmanagedType.LPWStr)] string ParentPath);
|
||||
public static extern Win32Error AddVirtualDiskParent([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, [MarshalAs(UnmanagedType.LPWStr)] string ParentPath);
|
||||
|
||||
/// <summary>Applies a snapshot of the current virtual disk for VHD Set files.</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -842,7 +845,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
public static extern Win32Error ApplySnapshotVhdSet(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in APPLY_SNAPSHOT_VHDSET_PARAMETERS Parameters, APPLY_SNAPSHOT_VHDSET_FLAG Flags);
|
||||
public static extern Win32Error ApplySnapshotVhdSet([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in APPLY_SNAPSHOT_VHDSET_PARAMETERS Parameters, APPLY_SNAPSHOT_VHDSET_FLAG Flags);
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a virtual hard disk (VHD) or CD or DVD image file (ISO) by locating an appropriate VHD provider to accomplish the attachment.
|
||||
|
@ -872,8 +875,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
public static extern Win32Error AttachVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, [Optional] PSECURITY_DESCRIPTOR SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags,
|
||||
uint ProviderSpecificFlags, in ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, [In] IntPtr Overlapped);
|
||||
public static extern Win32Error AttachVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, [In, Optional] PSECURITY_DESCRIPTOR SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags,
|
||||
uint ProviderSpecificFlags, in ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, [In, Optional] IntPtr Overlapped);
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a virtual hard disk (VHD) or CD or DVD image file (ISO) by locating an appropriate VHD provider to accomplish the attachment.
|
||||
|
@ -903,8 +906,39 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
public static extern Win32Error AttachVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, [Optional] PSECURITY_DESCRIPTOR SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags,
|
||||
uint ProviderSpecificFlags, in ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped);
|
||||
public static extern Win32Error AttachVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, [In, Optional] PSECURITY_DESCRIPTOR SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags,
|
||||
uint ProviderSpecificFlags, [In, Optional] IntPtr Parameters, [In, Optional] IntPtr Overlapped);
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a virtual hard disk (VHD) or CD or DVD image file (ISO) by locating an appropriate VHD provider to accomplish the attachment.
|
||||
/// </summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
/// A handle to an open virtual disk. For information on how to open a virtual disk, see the OpenVirtualDisk function.
|
||||
/// </param>
|
||||
/// <param name="SecurityDescriptor">
|
||||
/// An optional pointer to a SECURITY_DESCRIPTOR to apply to the attached virtual disk. If this parameter is NULL, the security
|
||||
/// descriptor of the virtual disk image file is used.
|
||||
/// <para>
|
||||
/// Ensure that the security descriptor that AttachVirtualDisk applies to the attached virtual disk grants the write attributes
|
||||
/// permission for the user, or that the security descriptor of the virtual disk image file grants the write attributes permission
|
||||
/// for the user if you specify NULL for this parameter. If the security descriptor does not grant write attributes permission for a
|
||||
/// user, Shell displays the following error when the user accesses the attached virtual disk: The Recycle Bin is corrupted. Do you
|
||||
/// want to empty the Recycle Bin for this drive?
|
||||
/// </para>
|
||||
/// </param>
|
||||
/// <param name="Flags">A valid combination of values of the ATTACH_VIRTUAL_DISK_FLAG enumeration.</param>
|
||||
/// <param name="ProviderSpecificFlags">Flags specific to the type of virtual disk being attached. May be zero if none are required.</param>
|
||||
/// <param name="Parameters">A pointer to a valid ATTACH_VIRTUAL_DISK_PARAMETERS structure that contains attachment parameter data.</param>
|
||||
/// <param name="Overlapped">An optional pointer to a valid OVERLAPPED structure if asynchronous operation is desired.</param>
|
||||
/// <returns>
|
||||
/// Status of the request.
|
||||
/// <para>If the function succeeds, the return value is ERROR_SUCCESS.</para>
|
||||
/// <para>If the function fails, the return value is an error code. For more information, see System Error Codes.</para>
|
||||
/// </returns>
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
public static extern Win32Error AttachVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, [In, Optional] PSECURITY_DESCRIPTOR SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags,
|
||||
uint ProviderSpecificFlags, in ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, in NativeOverlapped Overlapped);
|
||||
|
||||
/// <summary>Breaks a previously initiated mirror operation and sets the mirror to be the active virtual disk.</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -918,7 +952,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h", MSDNShortId = "hh448676")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error BreakMirrorVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle);
|
||||
public static extern Win32Error BreakMirrorVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle);
|
||||
|
||||
/// <summary>Reduces the size of a virtual hard disk (VHD) backing store file.</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -970,7 +1004,7 @@ namespace Vanara.PInvoke
|
|||
/// </remarks>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error CompactVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, COMPACT_VIRTUAL_DISK_FLAG Flags, in COMPACT_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped);
|
||||
public static extern Win32Error CompactVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, COMPACT_VIRTUAL_DISK_FLAG Flags, in COMPACT_VIRTUAL_DISK_PARAMETERS Parameters, in NativeOverlapped Overlapped);
|
||||
|
||||
/// <summary>Reduces the size of a virtual hard disk (VHD) backing store file.</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1022,7 +1056,59 @@ namespace Vanara.PInvoke
|
|||
/// </remarks>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error CompactVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, COMPACT_VIRTUAL_DISK_FLAG Flags, in COMPACT_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped);
|
||||
public static extern Win32Error CompactVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, COMPACT_VIRTUAL_DISK_FLAG Flags, in COMPACT_VIRTUAL_DISK_PARAMETERS Parameters, [In, Optional] IntPtr Overlapped);
|
||||
|
||||
/// <summary>Reduces the size of a virtual hard disk (VHD) backing store file.</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
/// A handle to the open virtual disk, which must have been opened using the VIRTUAL_DISK_ACCESS_METAOPS flag in the
|
||||
/// VirtualDiskAccessMask parameter passed to OpenVirtualDisk. For information on how to open a virtual disk, see the OpenVirtualDisk function.
|
||||
/// </param>
|
||||
/// <param name="Flags">Must be the COMPACT_VIRTUAL_DISK_FLAG_NONE value (0) of the COMPACT_VIRTUAL_DISK_FLAG enumeration.</param>
|
||||
/// <param name="Parameters">
|
||||
/// A optional pointer to a valid COMPACT_VIRTUAL_DISK_PARAMETERS structure that contains compaction parameter data.
|
||||
/// </param>
|
||||
/// <param name="Overlapped">An optional pointer to a valid OVERLAPPED structure if asynchronous operation is desired.</param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is ERROR_SUCCESS. If the function fails, the return value is an error code. For more
|
||||
/// information, see System Error Codes.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Compaction can be run only on a virtual disk that is dynamically expandable or differencing.
|
||||
/// <para>There are two different types of compaction.</para>
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description>
|
||||
/// The first type, file-system-aware compaction, uses the NTFS file system to determine free space. This is done by attaching the
|
||||
/// VHD as a read-only device by including the VIRTUAL_DISK_ACCESS_METAOPS and VIRTUAL_DISK_ACCESS_ATTACH_RO flags in the
|
||||
/// VirtualDiskAccessMask parameter passed to OpenVirtualDisk, attaching the VHD by calling AttachVirtualDisk, and while the VHD is
|
||||
/// attached calling CompactVirtualDisk. Detaching the VHD before compaction is done can cause compaction to return failure before it
|
||||
/// is done (similar to cancellation of compaction).
|
||||
/// </description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>
|
||||
/// The second type, file-system-agnostic compaction, does not involve the file system but only looks for VHD blocks filled entirely
|
||||
/// with zeros (0). This is done by including the VIRTUAL_DISK_ACCESS_METAOPS flag in the VirtualDiskAccessMask parameter passed to
|
||||
/// OpenVirtualDisk, and calling CompactVirtualDisk.
|
||||
/// </description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// <para>
|
||||
/// File-system-aware compaction is the most efficient compaction type but using first the file-system-aware compaction followed by
|
||||
/// the file-system-agnostic compaction will produce the smallest VHD.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// A compaction operation on a virtual disk can be safely interrupted and re-run later. Re-opening a virtual disk file that has been
|
||||
/// interrupted may result in the reduction of a virtual disk file's size at the time of opening.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Compaction can be CPU-intensive and/or I/O-intensive, depending on how large the virtual disk is and how many blocks require movement.
|
||||
/// </para>
|
||||
/// <para>The CompactVirtualDisk function runs on the virtual disk in the same security context as the caller.</para>
|
||||
/// </remarks>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error CompactVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, COMPACT_VIRTUAL_DISK_FLAG Flags, [In, Optional] IntPtr Parameters, [In, Optional] IntPtr Overlapped);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a virtual hard disk (VHD) image file, either using default parameters or using an existing VHD or physical disk.
|
||||
|
@ -1047,8 +1133,9 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern Win32Error CreateVirtualDisk(in VIRTUAL_STORAGE_TYPE VirtualStorageType, string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask, PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags, in CREATE_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped, out SafeVIRTUAL_DISK_HANDLE Handle);
|
||||
public static extern Win32Error CreateVirtualDisk(in VIRTUAL_STORAGE_TYPE VirtualStorageType, string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask,
|
||||
[In, Optional] PSECURITY_DESCRIPTOR SecurityDescriptor, CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags,
|
||||
in CREATE_VIRTUAL_DISK_PARAMETERS Parameters, [In, Optional] IntPtr Overlapped, out SafeVIRTUAL_DISK_HANDLE Handle);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a virtual hard disk (VHD) image file, either using default parameters or using an existing VHD or physical disk.
|
||||
|
@ -1073,8 +1160,9 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern Win32Error CreateVirtualDisk(in VIRTUAL_STORAGE_TYPE VirtualStorageType, string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask, PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags, in CREATE_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped, out SafeVIRTUAL_DISK_HANDLE Handle);
|
||||
public static extern Win32Error CreateVirtualDisk(in VIRTUAL_STORAGE_TYPE VirtualStorageType, string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask,
|
||||
[In, Optional] PSECURITY_DESCRIPTOR SecurityDescriptor, CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags,
|
||||
in CREATE_VIRTUAL_DISK_PARAMETERS Parameters, in NativeOverlapped Overlapped, out SafeVIRTUAL_DISK_HANDLE Handle);
|
||||
|
||||
/// <summary>Deletes a snapshot from a VHD Set file.</summary>
|
||||
/// <param name="VirtualDiskHandle">A handle to the open virtual disk.</param>
|
||||
|
@ -1086,7 +1174,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error DeleteSnapshotVhdSet(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in DELETE_SNAPSHOT_VHDSET_PARAMETERS Parameters, DELETE_SNAPSHOT_VHDSET_FLAG Flags);
|
||||
public static extern Win32Error DeleteSnapshotVhdSet([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in DELETE_SNAPSHOT_VHDSET_PARAMETERS Parameters, DELETE_SNAPSHOT_VHDSET_FLAG Flags);
|
||||
|
||||
/// <summary>Deletes metadata from a virtual disk.</summary>
|
||||
/// <param name="VirtualDiskHandle">A handle to the open virtual disk.</param>
|
||||
|
@ -1097,7 +1185,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error DeleteVirtualDiskMetadata(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in Guid Item);
|
||||
public static extern Win32Error DeleteVirtualDiskMetadata([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in Guid Item);
|
||||
|
||||
/// <summary>
|
||||
/// Detaches a virtual hard disk (VHD) or CD or DVD image file (ISO) by locating an appropriate virtual disk provider to accomplish
|
||||
|
@ -1116,7 +1204,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error DetachVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, DETACH_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags);
|
||||
public static extern Win32Error DetachVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, DETACH_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags);
|
||||
|
||||
/// <summary>Enumerates the metadata associated with a virtual disk.</summary>
|
||||
/// <param name="VirtualDiskHandle">Handle to an open virtual disk.</param>
|
||||
|
@ -1135,7 +1223,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error EnumerateVirtualDiskMetadata(VIRTUAL_DISK_HANDLE VirtualDiskHandle, ref uint NumberOfItems, IntPtr Items);
|
||||
public static extern Win32Error EnumerateVirtualDiskMetadata([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, ref uint NumberOfItems,
|
||||
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Guid[] Items);
|
||||
|
||||
/// <summary>Increases the size of a fixed or dynamic virtual hard disk (VHD).</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1150,7 +1239,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error ExpandVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, EXPAND_VIRTUAL_DISK_FLAG Flags, in EXPAND_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped);
|
||||
public static extern Win32Error ExpandVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, EXPAND_VIRTUAL_DISK_FLAG Flags,
|
||||
in EXPAND_VIRTUAL_DISK_PARAMETERS Parameters, [In, Optional] IntPtr Overlapped);
|
||||
|
||||
/// <summary>Increases the size of a fixed or dynamic virtual hard disk (VHD).</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1165,7 +1255,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error ExpandVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, EXPAND_VIRTUAL_DISK_FLAG Flags, in EXPAND_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped);
|
||||
public static extern Win32Error ExpandVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, EXPAND_VIRTUAL_DISK_FLAG Flags,
|
||||
in EXPAND_VIRTUAL_DISK_PARAMETERS Parameters, in NativeOverlapped Overlapped);
|
||||
|
||||
/// <summary>Get the paths of all attached virtual disks.</summary>
|
||||
/// <param name="PathsBufferSizeInBytes">Size of the buffer supplied in <paramref name="PathsBuffer"/>.</param>
|
||||
|
@ -1176,7 +1267,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error GetAllAttachedVirtualDiskPhysicalPaths(ref uint PathsBufferSizeInBytes, IntPtr PathsBuffer);
|
||||
public static extern Win32Error GetAllAttachedVirtualDiskPhysicalPaths(ref uint PathsBufferSizeInBytes, [Out] IntPtr PathsBuffer);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the relationships between virtual hard disks (VHDs) or the volumes contained within those disks and their parent disk or volume.
|
||||
|
@ -1194,7 +1285,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error GetStorageDependencyInformation(VIRTUAL_DISK_HANDLE ObjectHandle, GET_STORAGE_DEPENDENCY_FLAG Flags, int StorageDependencyInfoSize, IntPtr StorageDependencyInfo, ref int SizeUsed);
|
||||
public static extern Win32Error GetStorageDependencyInformation([In] VIRTUAL_DISK_HANDLE ObjectHandle, GET_STORAGE_DEPENDENCY_FLAG Flags,
|
||||
int StorageDependencyInfoSize, [In, Out] IntPtr StorageDependencyInfo, ref int SizeUsed);
|
||||
|
||||
/// <summary>Retrieves information about a virtual hard disk (VHD).</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1212,7 +1304,27 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error GetVirtualDiskInformation(VIRTUAL_DISK_HANDLE VirtualDiskHandle, ref uint VirtualDiskInfoSize, IntPtr VirtualDiskInfo, out uint SizeUsed);
|
||||
public static extern Win32Error GetVirtualDiskInformation([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, ref uint VirtualDiskInfoSize,
|
||||
ref GET_VIRTUAL_DISK_INFO VirtualDiskInfo, out uint SizeUsed);
|
||||
|
||||
/// <summary>Retrieves information about a virtual hard disk (VHD).</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
/// A handle to the open VHD, which must have been opened using the VIRTUAL_DISK_ACCESS_GET_INFO flag.
|
||||
/// </param>
|
||||
/// <param name="VirtualDiskInfoSize">A pointer to a ULONG that contains the size of the VirtualDiskInfo parameter.</param>
|
||||
/// <param name="VirtualDiskInfo">
|
||||
/// A pointer to a valid <see cref="GET_VIRTUAL_DISK_INFO"/> structure. The format of the data returned is dependent on the value
|
||||
/// passed in the Version member by the caller.
|
||||
/// </param>
|
||||
/// <param name="SizeUsed">A pointer to a ULONG that contains the size used.</param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is ERROR_SUCCESS and the Handle parameter contains a valid pointer to the new virtual
|
||||
/// disk object. If the function fails, the return value is an error code and the value of the Handle parameter is undefined.
|
||||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error GetVirtualDiskInformation([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, ref uint VirtualDiskInfoSize,
|
||||
[In, Out] IntPtr VirtualDiskInfo, out uint SizeUsed);
|
||||
|
||||
/// <summary>Retrieves the specified metadata from the virtual disk.</summary>
|
||||
/// <param name="VirtualDiskHandle">Handle to an open virtual disk.</param>
|
||||
|
@ -1230,7 +1342,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error GetVirtualDiskMetadata(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in Guid Item, ref uint MetaDataSize, IntPtr MetaData);
|
||||
public static extern Win32Error GetVirtualDiskMetadata([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in Guid Item, ref uint MetaDataSize, [Out] IntPtr MetaData);
|
||||
|
||||
/// <summary>Checks the progress of an asynchronous virtual hard disk (VHD) operation.</summary>
|
||||
/// <param name="VirtualDiskHandle">A valid handle to a virtual disk with a pending asynchronous operation.</param>
|
||||
|
@ -1246,7 +1358,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error GetVirtualDiskOperationProgress(VIRTUAL_DISK_HANDLE VirtualDiskHandle, ref NativeOverlapped Overlapped, out VIRTUAL_DISK_PROGRESS Progress);
|
||||
public static extern Win32Error GetVirtualDiskOperationProgress([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in NativeOverlapped Overlapped, out VIRTUAL_DISK_PROGRESS Progress);
|
||||
|
||||
/// <summary>Retrieves the path to the physical device object that contains a virtual hard disk (VHD).</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1260,7 +1372,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
public static extern Win32Error GetVirtualDiskPhysicalPath(VIRTUAL_DISK_HANDLE VirtualDiskHandle, ref int DiskPathSizeInBytes, StringBuilder DiskPath);
|
||||
public static extern Win32Error GetVirtualDiskPhysicalPath([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, ref int DiskPathSizeInBytes, [Out] StringBuilder DiskPath);
|
||||
|
||||
/// <summary>Merges a child virtual hard disk (VHD) in a differencing chain with parent disks in the chain.</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1275,7 +1387,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error MergeVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, MERGE_VIRTUAL_DISK_FLAG Flags, in MERGE_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped);
|
||||
public static extern Win32Error MergeVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, MERGE_VIRTUAL_DISK_FLAG Flags,
|
||||
in MERGE_VIRTUAL_DISK_PARAMETERS Parameters, [In, Optional] IntPtr Overlapped);
|
||||
|
||||
/// <summary>Merges a child virtual hard disk (VHD) in a differencing chain with parent disks in the chain.</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1290,7 +1403,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error MergeVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, MERGE_VIRTUAL_DISK_FLAG Flags, in MERGE_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped);
|
||||
public static extern Win32Error MergeVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, MERGE_VIRTUAL_DISK_FLAG Flags,
|
||||
in MERGE_VIRTUAL_DISK_PARAMETERS Parameters, in NativeOverlapped Overlapped);
|
||||
|
||||
/// <summary>
|
||||
/// Initiates a mirror operation for a virtual disk. Once the mirroring operation is initiated it will not complete until either
|
||||
|
@ -1310,7 +1424,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error MirrorVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, MIRROR_VIRTUAL_DISK_FLAG Flags, in MIRROR_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped);
|
||||
public static extern Win32Error MirrorVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, MIRROR_VIRTUAL_DISK_FLAG Flags,
|
||||
in MIRROR_VIRTUAL_DISK_PARAMETERS Parameters, in NativeOverlapped Overlapped);
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the internal contents of a virtual disk file. Can be used to set the active leaf, or to fix up snapshot entries.
|
||||
|
@ -1324,7 +1439,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error ModifyVhdSet(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in MODIFY_VHDSET_PARAMETERS Parameters, MODIFY_VHDSET_FLAG Flags);
|
||||
public static extern Win32Error ModifyVhdSet([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in MODIFY_VHDSET_PARAMETERS Parameters, MODIFY_VHDSET_FLAG Flags);
|
||||
|
||||
/// <summary>Opens a virtual hard disk (VHD) or CD or DVD image file (ISO) for use.</summary>
|
||||
/// <param name="VirtualStorageType">A pointer to a valid VIRTUAL_STORAGE_TYPE structure.</param>
|
||||
|
@ -1343,8 +1458,9 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true, ThrowOnUnmappableChar = true)]
|
||||
public static extern Win32Error OpenVirtualDisk(in VIRTUAL_STORAGE_TYPE VirtualStorageType, [MarshalAs(UnmanagedType.LPWStr)] string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask,
|
||||
OPEN_VIRTUAL_DISK_FLAG Flags, [In] OPEN_VIRTUAL_DISK_PARAMETERS Parameters, out SafeVIRTUAL_DISK_HANDLE Handle);
|
||||
public static extern Win32Error OpenVirtualDisk(in VIRTUAL_STORAGE_TYPE VirtualStorageType, [MarshalAs(UnmanagedType.LPWStr)] string Path,
|
||||
VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask, OPEN_VIRTUAL_DISK_FLAG Flags,
|
||||
[In, Optional] OPEN_VIRTUAL_DISK_PARAMETERS Parameters, out SafeVIRTUAL_DISK_HANDLE Handle);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves information about changes to the specified areas of a virtual hard disk (VHD) that are tracked by resilient change
|
||||
|
@ -1387,8 +1503,10 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error QueryChangesVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, [MarshalAs(UnmanagedType.LPWStr)] string ChangeTrackingId, ulong ByteOffset, ulong ByteLength,
|
||||
QUERY_CHANGES_VIRTUAL_DISK_FLAG Flags, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 6)] QUERY_CHANGES_VIRTUAL_DISK_RANGE[] Ranges, ref uint RangeCount, out ulong ProcessedLength);
|
||||
public static extern Win32Error QueryChangesVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, [MarshalAs(UnmanagedType.LPWStr)] string ChangeTrackingId,
|
||||
ulong ByteOffset, ulong ByteLength, QUERY_CHANGES_VIRTUAL_DISK_FLAG Flags,
|
||||
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 6)] QUERY_CHANGES_VIRTUAL_DISK_RANGE[] Ranges, ref uint RangeCount,
|
||||
out ulong ProcessedLength);
|
||||
|
||||
/// <summary>Issues an embedded SCSI request directly to a virtual hard disk.</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1408,7 +1526,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error RawSCSIVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in RAW_SCSI_VIRTUAL_DISK_PARAMETERS Parameters, RAW_SCSI_VIRTUAL_DISK_FLAG Flags, out RAW_SCSI_VIRTUAL_DISK_RESPONSE Response);
|
||||
public static extern Win32Error RawSCSIVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in RAW_SCSI_VIRTUAL_DISK_PARAMETERS Parameters,
|
||||
RAW_SCSI_VIRTUAL_DISK_FLAG Flags, out RAW_SCSI_VIRTUAL_DISK_RESPONSE Response);
|
||||
|
||||
/// <summary>Resizes a virtual disk.</summary>
|
||||
/// <param name="VirtualDiskHandle">Handle to an open virtual disk.</param>
|
||||
|
@ -1425,7 +1544,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error ResizeVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, RESIZE_VIRTUAL_DISK_FLAG Flags, in RESIZE_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped);
|
||||
public static extern Win32Error ResizeVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, RESIZE_VIRTUAL_DISK_FLAG Flags,
|
||||
in RESIZE_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped);
|
||||
|
||||
/// <summary>Resizes a virtual disk.</summary>
|
||||
/// <param name="VirtualDiskHandle">Handle to an open virtual disk.</param>
|
||||
|
@ -1442,7 +1562,8 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error ResizeVirtualDisk(VIRTUAL_DISK_HANDLE VirtualDiskHandle, RESIZE_VIRTUAL_DISK_FLAG Flags, in RESIZE_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped);
|
||||
public static extern Win32Error ResizeVirtualDisk([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, RESIZE_VIRTUAL_DISK_FLAG Flags,
|
||||
in RESIZE_VIRTUAL_DISK_PARAMETERS Parameters, in NativeOverlapped Overlapped);
|
||||
|
||||
/// <summary>Sets information about a virtual hard disk (VHD).</summary>
|
||||
/// <param name="VirtualDiskHandle">
|
||||
|
@ -1455,7 +1576,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h")]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error SetVirtualDiskInformation(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in SET_VIRTUAL_DISK_INFO VirtualDiskInfo);
|
||||
public static extern Win32Error SetVirtualDiskInformation([In, Out] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in SET_VIRTUAL_DISK_INFO VirtualDiskInfo);
|
||||
|
||||
/// <summary>Sets a metadata item for a virtual disk.</summary>
|
||||
/// <param name="VirtualDiskHandle">Handle to an open virtual disk.</param>
|
||||
|
@ -1468,7 +1589,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows8)]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error SetVirtualDiskMetadata(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in Guid Item, uint MetaDataSize, IntPtr MetaData);
|
||||
public static extern Win32Error SetVirtualDiskMetadata([In, Out] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in Guid Item, uint MetaDataSize, IntPtr MetaData);
|
||||
|
||||
/// <summary>Creates a snapshot of the current virtual disk for VHD Set files.</summary>
|
||||
/// <param name="VirtualDiskHandle">A handle to the open virtual disk. This must be a VHD Set file.</param>
|
||||
|
@ -1480,7 +1601,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows10)]
|
||||
[DllImport(Lib.VirtDisk, ExactSpelling = true)]
|
||||
public static extern Win32Error TakeSnapshotVhdSet(VIRTUAL_DISK_HANDLE VirtualDiskHandle, in TAKE_SNAPSHOT_VHDSET_PARAMETERS Parameters, TAKE_SNAPSHOT_VHDSET_FLAG Flags);
|
||||
public static extern Win32Error TakeSnapshotVhdSet([In] VIRTUAL_DISK_HANDLE VirtualDiskHandle, in TAKE_SNAPSHOT_VHDSET_PARAMETERS Parameters, TAKE_SNAPSHOT_VHDSET_FLAG Flags);
|
||||
|
||||
/// <summary>Contains snapshot parameters, indicating information about the new snapshot to be applied.</summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows10)]
|
||||
|
@ -1528,7 +1649,7 @@ namespace Vanara.PInvoke
|
|||
public ATTACH_VIRTUAL_DISK_PARAMETERS_Version1 Version1;
|
||||
|
||||
/// <summary>Gets the default value for this structure. This is currently the only valid value for <see cref="ATTACH_VIRTUAL_DISK_PARAMETERS"/>.</summary>
|
||||
public static ATTACH_VIRTUAL_DISK_PARAMETERS Default => new ATTACH_VIRTUAL_DISK_PARAMETERS { Version = ATTACH_VIRTUAL_DISK_VERSION.ATTACH_VIRTUAL_DISK_VERSION_1 };
|
||||
public static ATTACH_VIRTUAL_DISK_PARAMETERS Default => new() { Version = ATTACH_VIRTUAL_DISK_VERSION.ATTACH_VIRTUAL_DISK_VERSION_1 };
|
||||
|
||||
/// <summary>A structure with the following member.</summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows7)]
|
||||
|
@ -1555,7 +1676,7 @@ namespace Vanara.PInvoke
|
|||
public COMPACT_VIRTUAL_DISK_PARAMETERS_Version1 Version1;
|
||||
|
||||
/// <summary>Gets the default value for this structure. This is currently the only valid value for <see cref="COMPACT_VIRTUAL_DISK_PARAMETERS"/>.</summary>
|
||||
public static COMPACT_VIRTUAL_DISK_PARAMETERS Default => new COMPACT_VIRTUAL_DISK_PARAMETERS { Version = COMPACT_VIRTUAL_DISK_VERSION.COMPACT_VIRTUAL_DISK_VERSION_1 };
|
||||
public static COMPACT_VIRTUAL_DISK_PARAMETERS Default => new() { Version = COMPACT_VIRTUAL_DISK_VERSION.COMPACT_VIRTUAL_DISK_VERSION_1 };
|
||||
|
||||
/// <summary>A structure with the following member.</summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows7)]
|
||||
|
@ -2244,48 +2365,74 @@ namespace Vanara.PInvoke
|
|||
|
||||
/// <summary>Contains virtual hard disk (VHD) information for set request.</summary>
|
||||
[PInvokeData("VirtDisk.h", MSDNShortId = "dd323686", MinClient = PInvokeClient.Windows7)]
|
||||
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode,
|
||||
#if X64
|
||||
Pack = 8
|
||||
#else
|
||||
Pack = 4
|
||||
#endif
|
||||
)]
|
||||
public struct SET_VIRTUAL_DISK_INFO
|
||||
{
|
||||
/// <summary>
|
||||
/// A SET_VIRTUAL_DISK_INFO_VERSION enumeration that specifies the version of the SET_VIRTUAL_DISK_INFO structure being passed to
|
||||
/// or from the VHD functions. This determines the type of information set.
|
||||
/// </summary>
|
||||
[FieldOffset(0)] public SET_VIRTUAL_DISK_INFO_VERSION Version;
|
||||
public SET_VIRTUAL_DISK_INFO_VERSION Version;
|
||||
|
||||
private UNION union;
|
||||
|
||||
/// <summary>Path to the parent backing store.</summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows7)]
|
||||
[FieldOffset(8)] public StrPtrUni ParentFilePath;
|
||||
public StrPtrUni ParentFilePath { get => union.ParentFilePath; set => union.ParentFilePath = value; }
|
||||
|
||||
/// <summary>Unique identifier of the VHD.</summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows7)]
|
||||
[FieldOffset(8)] public Guid UniqueIdentifier;
|
||||
public Guid UniqueIdentifier { get => union.UniqueIdentifier; set => union.UniqueIdentifier = value; }
|
||||
|
||||
/// <summary>Sets the parent file path and the child depth.</summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows8)]
|
||||
[FieldOffset(8)] public SET_VIRTUAL_DISK_INFO_ParentPathWithDepthInfo ParentPathWithDepthInfo;
|
||||
public SET_VIRTUAL_DISK_INFO_ParentPathWithDepthInfo ParentPathWithDepthInfo { get => union.ParentPathWithDepthInfo; set => union.ParentPathWithDepthInfo = value; }
|
||||
|
||||
/// <summary>Sets the physical sector size reported by the VHD.</summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows8)]
|
||||
[FieldOffset(8)] public uint VhdPhysicalSectorSize;
|
||||
public uint VhdPhysicalSectorSize { get => union.VhdPhysicalSectorSize; set => union.VhdPhysicalSectorSize = value; }
|
||||
|
||||
/// <summary>
|
||||
/// The identifier that is uniquely created when a user first creates the virtual disk to attempt to uniquely identify that
|
||||
/// virtual disk.
|
||||
/// </summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows81)]
|
||||
[FieldOffset(8)] public Guid VirtualDiskId;
|
||||
public Guid VirtualDiskId { get => union.VirtualDiskId; set => union.VirtualDiskId = value; }
|
||||
|
||||
/// <summary>Turns resilient change tracking (RCT) on or off for the VHD. TRUE turns RCT on. FALSE turns RCT off.</summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows10)]
|
||||
[FieldOffset(8), MarshalAs(UnmanagedType.Bool)] public bool ChangeTrackingEnabled;
|
||||
public bool ChangeTrackingEnabled { get => union.ChangeTrackingEnabled; set => union.ChangeTrackingEnabled = value; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the parent linkage information that differencing VHDs store. Parent linkage information is metadata used to locate and
|
||||
/// correctly identify the next parent in the virtual disk chain.
|
||||
/// </summary>
|
||||
[PInvokeData("VirtDisk.h", MinClient = PInvokeClient.Windows10)]
|
||||
[FieldOffset(8)] public SET_VIRTUAL_DISK_INFO_ParentLocator ParentLocator;
|
||||
public SET_VIRTUAL_DISK_INFO_ParentLocator ParentLocator { get => union.ParentLocator; set => union.ParentLocator = value; }
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
|
||||
private struct UNION
|
||||
{
|
||||
[FieldOffset(0)] public StrPtrUni ParentFilePath;
|
||||
|
||||
[FieldOffset(0)] public Guid UniqueIdentifier;
|
||||
|
||||
[FieldOffset(0)] public SET_VIRTUAL_DISK_INFO_ParentPathWithDepthInfo ParentPathWithDepthInfo;
|
||||
|
||||
[FieldOffset(0)] public uint VhdPhysicalSectorSize;
|
||||
|
||||
[FieldOffset(0)] public Guid VirtualDiskId;
|
||||
|
||||
[FieldOffset(0), MarshalAs(UnmanagedType.Bool)] public bool ChangeTrackingEnabled;
|
||||
|
||||
[FieldOffset(0)] public SET_VIRTUAL_DISK_INFO_ParentLocator ParentLocator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the parent linkage information that differencing VHDs store. Parent linkage information is metadata used to locate and
|
||||
|
@ -2299,7 +2446,7 @@ namespace Vanara.PInvoke
|
|||
public Guid LinkageId;
|
||||
|
||||
/// <summary>The path of the file for the parent VHD.</summary>
|
||||
public IntPtr ParentFilePath;
|
||||
public StrPtrUni ParentFilePath;
|
||||
}
|
||||
|
||||
/// <summary>Sets the parent file path and the child depth.</summary>
|
||||
|
@ -2311,7 +2458,7 @@ namespace Vanara.PInvoke
|
|||
public uint ChildDepth;
|
||||
|
||||
/// <summary>Specifies the depth to the parent from the leaf. The leaf itself is at depth 1.</summary>
|
||||
public IntPtr ParentFilePath;
|
||||
public StrPtrUni ParentFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2403,14 +2550,14 @@ namespace Vanara.PInvoke
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct VIRTUAL_DISK_HANDLE : IHandle
|
||||
{
|
||||
private IntPtr handle;
|
||||
private readonly IntPtr handle;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="VIRTUAL_DISK_HANDLE"/> struct.</summary>
|
||||
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
|
||||
public VIRTUAL_DISK_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
|
||||
|
||||
/// <summary>Returns an invalid handle by instantiating a <see cref="VIRTUAL_DISK_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
|
||||
public static VIRTUAL_DISK_HANDLE NULL => new VIRTUAL_DISK_HANDLE(IntPtr.Zero);
|
||||
public static VIRTUAL_DISK_HANDLE NULL => new(IntPtr.Zero);
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
|
||||
public bool IsNull => handle == IntPtr.Zero;
|
||||
|
@ -2423,7 +2570,7 @@ namespace Vanara.PInvoke
|
|||
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="VIRTUAL_DISK_HANDLE"/>.</summary>
|
||||
/// <param name="h">The pointer to a handle.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator VIRTUAL_DISK_HANDLE(IntPtr h) => new VIRTUAL_DISK_HANDLE(h);
|
||||
public static implicit operator VIRTUAL_DISK_HANDLE(IntPtr h) => new(h);
|
||||
|
||||
/// <summary>Implements the operator !=.</summary>
|
||||
/// <param name="h1">The first handle.</param>
|
||||
|
@ -2438,7 +2585,7 @@ namespace Vanara.PInvoke
|
|||
public static bool operator ==(VIRTUAL_DISK_HANDLE h1, VIRTUAL_DISK_HANDLE h2) => h1.Equals(h2);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj) => obj is VIRTUAL_DISK_HANDLE h ? handle == h.handle : false;
|
||||
public override bool Equals(object obj) => obj is VIRTUAL_DISK_HANDLE h && handle == h.handle;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode() => handle.GetHashCode();
|
||||
|
@ -2496,7 +2643,7 @@ namespace Vanara.PInvoke
|
|||
/// <summary>
|
||||
/// Gets an instance of <see cref="VIRTUAL_STORAGE_TYPE"/> that represents a Microsoft Virtual Hard Drive or .vhd file.
|
||||
/// </summary>
|
||||
public static VIRTUAL_STORAGE_TYPE VHD => new VIRTUAL_STORAGE_TYPE(VIRTUAL_STORAGE_TYPE_DEVICE_TYPE.VIRTUAL_STORAGE_TYPE_DEVICE_VHD);
|
||||
public static VIRTUAL_STORAGE_TYPE VHD => new(VIRTUAL_STORAGE_TYPE_DEVICE_TYPE.VIRTUAL_STORAGE_TYPE_DEVICE_VHD);
|
||||
}
|
||||
|
||||
/// <summary>Contains virtual disk open request parameters.</summary>
|
||||
|
@ -2574,7 +2721,7 @@ namespace Vanara.PInvoke
|
|||
}
|
||||
|
||||
/// <summary>Gets the default value for this structure. This is currently the only valid value for <see cref="ATTACH_VIRTUAL_DISK_PARAMETERS"/>.</summary>
|
||||
public static OPEN_VIRTUAL_DISK_PARAMETERS DefaultV2 => new OPEN_VIRTUAL_DISK_PARAMETERS(false);
|
||||
public static OPEN_VIRTUAL_DISK_PARAMETERS DefaultV2 => new(false);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -12,9 +13,73 @@ namespace Vanara.IO.Tests
|
|||
[TestFixture()]
|
||||
public class VirtualDiskTests
|
||||
{
|
||||
static readonly string tmpfn = Vanara.PInvoke.Tests.TestCaseSources.TempDirWhack + "TestVHD.vhd";
|
||||
static readonly string tmpcfn = Vanara.PInvoke.Tests.TestCaseSources.TempDirWhack + "TestVHD - Diff.vhd";
|
||||
static readonly string fn = Vanara.PInvoke.Tests.TestCaseSources.VirtualDisk;
|
||||
private static readonly string fn = Vanara.PInvoke.Tests.TestCaseSources.VirtualDisk;
|
||||
private static readonly string tmpcfn = Vanara.PInvoke.Tests.TestCaseSources.TempDirWhack + "TestVHD - Diff.vhd";
|
||||
private static readonly string tmpfn = Vanara.PInvoke.Tests.TestCaseSources.TempDirWhack + "TestVHD.vhd";
|
||||
|
||||
[Test()]
|
||||
public void CompactTest()
|
||||
{
|
||||
using var vhd = VirtualDisk.Open(fn, false);
|
||||
Assert.That(() => vhd.Compact(), Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public async Task CompactTest1()
|
||||
{
|
||||
using var vhd = VirtualDisk.Open(fn, false);
|
||||
var cts = new CancellationTokenSource();
|
||||
var rpt = new Reporter();
|
||||
var lastVal = 0;
|
||||
rpt.NewVal += (o, e) => TestContext.WriteLine($"{DateTime.Now:o} NewVal={lastVal = e}");
|
||||
await vhd.Compact(cts.Token, rpt);
|
||||
Assert.That(lastVal, Is.EqualTo(100));
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void CreateDiffTest()
|
||||
{
|
||||
const int sz = 0x03010400;
|
||||
try
|
||||
{
|
||||
using var vhdp = VirtualDisk.Create(tmpfn, sz);
|
||||
using var vhd = VirtualDisk.CreateDifferencing(tmpcfn, tmpfn);
|
||||
Assert.That(System.IO.File.Exists(tmpcfn));
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
Assert.That(vhd.BlockSize, Is.EqualTo(0x200000));
|
||||
Assert.That(vhd.DiskType, Is.EqualTo(VirtualDisk.DeviceType.Vhd));
|
||||
Assert.That(vhd.ResilientChangeTrackingEnabled, Is.False);
|
||||
//Assert.That(vhd.FragmentationPercentage, Is.Zero); // must be non-differencing
|
||||
Assert.That(vhd.Identifier, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.Is4kAligned);
|
||||
Assert.That(vhd.IsLoaded, Is.False);
|
||||
Assert.That(vhd.IsRemote, Is.False);
|
||||
Assert.That(vhd.LogicalSectorSize, Is.EqualTo(0x200));
|
||||
//Assert.That(vhd.MostRecentId, Is.Null.Or.Empty);
|
||||
Assert.That(vhd.NewerChanges, Is.False);
|
||||
Assert.That(vhd.ParentBackingStore, Is.EqualTo(tmpfn)); // must be differencing
|
||||
Assert.That(vhd.ParentIdentifier, Is.Not.EqualTo(Guid.Empty)); // must be differencing
|
||||
Assert.That(vhd.ParentPaths, Is.Null); // must be differencing
|
||||
Assert.That(vhd.ParentTimeStamp, Is.Zero); // must be differencing
|
||||
//TestContext.WriteLine(vhd.PhysicalPath); // must be attached
|
||||
Assert.That(vhd.PhysicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.PhysicalSize, Is.LessThan(sz));
|
||||
Assert.That(vhd.ProviderSubtype, Is.EqualTo(VirtualDisk.Subtype.Differencing));
|
||||
Assert.That(vhd.SectorSize, Is.EqualTo(0x200));
|
||||
//Debug.WriteLine(vhd.SmallestSafeVirtualSize); // must have file system
|
||||
Assert.That(vhd.VendorId, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.VhdPhysicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.VirtualDiskId, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(tmpcfn);
|
||||
System.IO.File.Delete(tmpfn);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void CreateDynPropTest()
|
||||
|
@ -22,38 +87,53 @@ namespace Vanara.IO.Tests
|
|||
const int sz = 0x03010200;
|
||||
try
|
||||
{
|
||||
using (var vhd = VirtualDisk.Create(tmpfn, sz))
|
||||
//using (var pv = new PrivilegedCodeBlock(SystemPrivilege.ManageVolume))
|
||||
{
|
||||
//vhd.Attach(true);
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
Assert.That(vhd.BlockSize, Is.EqualTo(0x200000));
|
||||
Assert.That(vhd.DiskType, Is.EqualTo(VirtualDisk.DeviceType.Vhd));
|
||||
Assert.That(vhd.Enabled, Is.False);
|
||||
Assert.That(vhd.FragmentationPercentage, Is.Zero);
|
||||
Assert.That(vhd.Identifier, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.Is4kAligned);
|
||||
Assert.That(vhd.IsLoaded, Is.False);
|
||||
Assert.That(vhd.IsRemote, Is.False);
|
||||
Assert.That(vhd.LogicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.MostRecentId, Is.Null.Or.Empty);
|
||||
Assert.That(vhd.NewerChanges, Is.False);
|
||||
//Debug.WriteLine(vhd.ParentBackingStore); // must be differencing
|
||||
//Debug.WriteLine(vhd.ParentIdentifier); // must be differencing
|
||||
//Debug.WriteLine(vhd.ParentPaths); // must be differencing
|
||||
//Debug.WriteLine(vhd.ParentTimeStamp); // must be differencing
|
||||
//Debug.WriteLine(vhd.PhysicalPath); // must be attached
|
||||
Assert.That(vhd.PhysicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.PhysicalSize, Is.LessThan(sz));
|
||||
Assert.That(vhd.ProviderSubtype, Is.EqualTo(VirtualDisk.Subtype.Dynamic));
|
||||
Assert.That(vhd.SectorSize, Is.EqualTo(0x200));
|
||||
//Debug.WriteLine(vhd.SmallestSafeVirtualSize); // must have file system
|
||||
Assert.That(vhd.VendorId, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.VhdPhysicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.VirtualDiskId, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
}
|
||||
using var vhd = VirtualDisk.Create(tmpfn, sz);
|
||||
//vhd.Attach(true);
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
Assert.That(vhd.BlockSize, Is.EqualTo(0x200000));
|
||||
Assert.That(vhd.DiskType, Is.EqualTo(VirtualDisk.DeviceType.Vhd));
|
||||
Assert.That(vhd.ResilientChangeTrackingEnabled, Is.False);
|
||||
Assert.That(vhd.FragmentationPercentage, Is.Zero);
|
||||
Assert.That(vhd.Identifier, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.Is4kAligned);
|
||||
Assert.That(vhd.IsLoaded, Is.False);
|
||||
Assert.That(vhd.IsRemote, Is.False);
|
||||
Assert.That(vhd.LogicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.MostRecentId, Is.Null.Or.Empty);
|
||||
Assert.That(vhd.NewerChanges, Is.False);
|
||||
//Debug.WriteLine(vhd.ParentBackingStore); // must be differencing
|
||||
//Debug.WriteLine(vhd.ParentIdentifier); // must be differencing
|
||||
//Debug.WriteLine(vhd.ParentPaths); // must be differencing
|
||||
//Debug.WriteLine(vhd.ParentTimeStamp); // must be differencing
|
||||
//Debug.WriteLine(vhd.PhysicalPath); // must be attached
|
||||
Assert.That(vhd.PhysicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.PhysicalSize, Is.LessThan(sz));
|
||||
Assert.That(vhd.ProviderSubtype, Is.EqualTo(VirtualDisk.Subtype.Dynamic));
|
||||
Assert.That(vhd.SectorSize, Is.EqualTo(0x200));
|
||||
//Debug.WriteLine(vhd.SmallestSafeVirtualSize); // must have file system
|
||||
Assert.That(vhd.VendorId, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.VhdPhysicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.VirtualDiskId, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(tmpfn);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void CreateFixedPropTest()
|
||||
{
|
||||
const int sz = 0x03010400;
|
||||
try
|
||||
{
|
||||
using var vhd = VirtualDisk.Create(tmpfn, sz, false, null);
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.PhysicalSize, Is.EqualTo(sz + 512));
|
||||
Assert.That(vhd.ProviderSubtype, Is.EqualTo(VirtualDisk.Subtype.Fixed));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -66,11 +146,9 @@ namespace Vanara.IO.Tests
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var vhd = VirtualDisk.CreateFromSource(tmpfn, fn))
|
||||
{
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
vhd.Close();
|
||||
}
|
||||
using var vhd = VirtualDisk.CreateFromSource(tmpfn, fn);
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
vhd.Close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -78,192 +156,6 @@ namespace Vanara.IO.Tests
|
|||
}
|
||||
}
|
||||
|
||||
//[Test()]
|
||||
//public async Task CreateFromSourceTest1()
|
||||
//{
|
||||
// VirtualDisk vd = null;
|
||||
// try
|
||||
// {
|
||||
// var cts = new CancellationTokenSource();
|
||||
// var rpt = new Reporter();
|
||||
// var lastVal = 0;
|
||||
// rpt.NewVal += (o, e) => TestContext.WriteLine($"{DateTime.Now:o} NewVal={lastVal = e}");
|
||||
// vd = await VirtualDisk.CreateFromSource(tmpfn, fn, cts.Token, rpt);
|
||||
// Assert.That(lastVal, Is.EqualTo(100));
|
||||
// Assert.That(System.IO.File.Exists(tmpfn));
|
||||
// TestContext.WriteLine($"New file sz: {new System.IO.FileInfo(tmpfn).Length}");
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// vd?.Close();
|
||||
// try { System.IO.File.Delete(tmpfn); } catch { }
|
||||
// }
|
||||
//}
|
||||
|
||||
[Test()]
|
||||
public void CreateFixedPropTest()
|
||||
{
|
||||
const int sz = 0x03010400;
|
||||
try
|
||||
{
|
||||
using (var vhd = VirtualDisk.Create(tmpfn, sz, false, null))
|
||||
{
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.PhysicalSize, Is.EqualTo(sz + 512));
|
||||
Assert.That(vhd.ProviderSubtype, Is.EqualTo(VirtualDisk.Subtype.Fixed));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(tmpfn);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void CreateDiffTest()
|
||||
{
|
||||
const int sz = 0x03010400;
|
||||
try
|
||||
{
|
||||
using (var vhdp = VirtualDisk.Create(tmpfn, sz))
|
||||
using (var vhd = VirtualDisk.CreateDifferencing(tmpcfn, tmpfn))
|
||||
{
|
||||
Assert.That(System.IO.File.Exists(tmpcfn));
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
Assert.That(vhd.BlockSize, Is.EqualTo(0x200000));
|
||||
Assert.That(vhd.DiskType, Is.EqualTo(VirtualDisk.DeviceType.Vhd));
|
||||
Assert.That(vhd.Enabled, Is.False);
|
||||
//Assert.That(vhd.FragmentationPercentage, Is.Zero); // must be non-differencing
|
||||
Assert.That(vhd.Identifier, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.Is4kAligned);
|
||||
Assert.That(vhd.IsLoaded, Is.False);
|
||||
Assert.That(vhd.IsRemote, Is.False);
|
||||
Assert.That(vhd.LogicalSectorSize, Is.EqualTo(0x200));
|
||||
//Assert.That(vhd.MostRecentId, Is.Null.Or.Empty);
|
||||
Assert.That(vhd.NewerChanges, Is.False);
|
||||
Assert.That(vhd.ParentBackingStore, Is.EqualTo(tmpfn)); // must be differencing
|
||||
Assert.That(vhd.ParentIdentifier, Is.Not.EqualTo(Guid.Empty)); // must be differencing
|
||||
Assert.That(vhd.ParentPaths, Is.Null); // must be differencing
|
||||
Assert.That(vhd.ParentTimeStamp, Is.Zero); // must be differencing
|
||||
//TestContext.WriteLine(vhd.PhysicalPath); // must be attached
|
||||
Assert.That(vhd.PhysicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.PhysicalSize, Is.LessThan(sz));
|
||||
Assert.That(vhd.ProviderSubtype, Is.EqualTo(VirtualDisk.Subtype.Differencing));
|
||||
Assert.That(vhd.SectorSize, Is.EqualTo(0x200));
|
||||
//Debug.WriteLine(vhd.SmallestSafeVirtualSize); // must have file system
|
||||
Assert.That(vhd.VendorId, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.VhdPhysicalSectorSize, Is.EqualTo(0x200));
|
||||
Assert.That(vhd.VirtualDiskId, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(tmpcfn);
|
||||
System.IO.File.Delete(tmpfn);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void OpenAttachRawTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
var param = new OPEN_VIRTUAL_DISK_PARAMETERS(false);
|
||||
using (var vhd = VirtualDisk.Open(fn, OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NONE, param, VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE))
|
||||
{
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
var flags = ATTACH_VIRTUAL_DISK_FLAG.ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY;
|
||||
var aparam = ATTACH_VIRTUAL_DISK_PARAMETERS.Default;
|
||||
var sd = ConvertStringSecurityDescriptorToSecurityDescriptor("O:BAG:BAD:(A;;GA;;;WD)");
|
||||
vhd.Attach(flags, ref aparam, sd);
|
||||
Assert.That(vhd.Attached, Is.True);
|
||||
vhd.Detach();
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static FileSecurity GetFileSecurity(string sddl)
|
||||
{
|
||||
var sd = new FileSecurity();
|
||||
sd.SetSecurityDescriptorSddlForm(sddl);
|
||||
return sd;
|
||||
}
|
||||
|
||||
private static FileSecurity GetWorldFullFileSecurity() => GetFileSecurity("O:BAG:BAD:(A;;GA;;;WD)");
|
||||
|
||||
[Test()]
|
||||
public void OpenAttachTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var vhd = VirtualDisk.Open(fn, true))
|
||||
{
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
vhd.Attach(true, true, false, GetWorldFullFileSecurity());
|
||||
Assert.That(vhd.Attached, Is.True);
|
||||
TestContext.WriteLine(vhd.PhysicalPath);
|
||||
Assert.That(vhd.PhysicalPath, Is.Not.Null); // must be attached
|
||||
vhd.Detach();
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
vhd.Attach();
|
||||
Assert.That(vhd.Attached, Is.True);
|
||||
vhd.Close();
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSetMetadataTest()
|
||||
{
|
||||
const int sz = 0x03010200;
|
||||
var lfn = tmpfn + "x";
|
||||
try
|
||||
{
|
||||
using (var vhd = VirtualDisk.Create(lfn, sz))
|
||||
{
|
||||
var count = 0;
|
||||
Assert.That(() => count = vhd.Metadata.Count, Throws.Nothing);
|
||||
|
||||
// Try get and set
|
||||
var guid = Guid.NewGuid();
|
||||
Assert.That(() => vhd.Metadata.Add(guid, new SafeCoTaskMemHandle("Testing")), Throws.Nothing);
|
||||
Assert.That(vhd.Metadata.Count, Is.EqualTo(count + 1));
|
||||
Assert.That(vhd.Metadata.ContainsKey(Guid.NewGuid()), Is.False);
|
||||
Assert.That(vhd.Metadata.TryGetValue(guid, out var mem), Is.True);
|
||||
Assert.That(mem.ToString(-1), Is.EqualTo("Testing"));
|
||||
|
||||
// Try enumerate and get
|
||||
foreach (var mkv in vhd.Metadata)
|
||||
{
|
||||
Assert.That(mkv.Key, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(mkv.Value.Size, Is.Not.Zero);
|
||||
TestContext.WriteLine($"{mkv.Key}={mkv.Value.Size}b:{mkv.Value.ToString(-1)}");
|
||||
}
|
||||
|
||||
// Try remove
|
||||
Assert.That(vhd.Metadata.Remove(guid), Is.True);
|
||||
Assert.That(vhd.Metadata.TryGetValue(guid, out mem), Is.False);
|
||||
Assert.That(vhd.Metadata.Count, Is.EqualTo(count));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(lfn);
|
||||
}
|
||||
}
|
||||
|
||||
//[Test()]
|
||||
public void DetachTest()
|
||||
{
|
||||
|
@ -286,6 +178,24 @@ namespace Vanara.IO.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void ExpandTest()
|
||||
{
|
||||
const int sz = 0x810400;
|
||||
try
|
||||
{
|
||||
using var vhd = VirtualDisk.Create(tmpfn, sz, true, null);
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
vhd.Expand(sz * 2);
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz * 2));
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(tmpfn);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void GetAllAttachedVirtualDiskPathsTest()
|
||||
{
|
||||
|
@ -298,31 +208,77 @@ namespace Vanara.IO.Tests
|
|||
Assert.That(VirtualDisk.GetAllAttachedVirtualDiskPaths(), Is.Empty);
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void CompactTest()
|
||||
[Test]
|
||||
public void GetSetMetadataTest()
|
||||
{
|
||||
using (var vhd = VirtualDisk.Open(fn, false))
|
||||
const int sz = 0x03010200;
|
||||
var lfn = tmpfn + "x";
|
||||
try
|
||||
{
|
||||
Assert.That(() => vhd.Compact(), Throws.Nothing);
|
||||
using var vhd = VirtualDisk.Create(lfn, sz);
|
||||
var count = 0;
|
||||
Assert.That(() => count = vhd.Metadata.Count, Throws.Nothing);
|
||||
|
||||
// Try get and set
|
||||
var guid = Guid.NewGuid();
|
||||
Assert.That(() => vhd.Metadata.Add(guid, new SafeCoTaskMemHandle("Testing")), Throws.Nothing);
|
||||
Assert.That(vhd.Metadata.Count, Is.EqualTo(count + 1));
|
||||
Assert.That(vhd.Metadata.ContainsKey(Guid.NewGuid()), Is.False);
|
||||
Assert.That(vhd.Metadata.TryGetValue(guid, out SafeCoTaskMemHandle mem), Is.True);
|
||||
Assert.That(mem.ToString(-1), Is.EqualTo("Testing"));
|
||||
|
||||
// Try enumerate and get
|
||||
foreach (System.Collections.Generic.KeyValuePair<Guid, SafeCoTaskMemHandle> mkv in vhd.Metadata)
|
||||
{
|
||||
Assert.That(mkv.Key, Is.Not.EqualTo(Guid.Empty));
|
||||
Assert.That(mkv.Value.Size, Is.Not.Zero);
|
||||
TestContext.WriteLine($"{mkv.Key}={mkv.Value.Size}b:{mkv.Value.ToString(-1)}");
|
||||
}
|
||||
|
||||
// Try remove
|
||||
Assert.That(vhd.Metadata.Remove(guid), Is.True);
|
||||
Assert.That(vhd.Metadata.TryGetValue(guid, out mem), Is.False);
|
||||
Assert.That(vhd.Metadata.Count, Is.EqualTo(count));
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(lfn);
|
||||
}
|
||||
}
|
||||
|
||||
//[Test]
|
||||
public void GetSetPropTest()
|
||||
{
|
||||
const int sz = 0x03010200;
|
||||
var lfn = tmpfn + "x";
|
||||
try
|
||||
{
|
||||
using var vhd = VirtualDisk.Create(lfn, sz);
|
||||
var b = vhd.ResilientChangeTrackingEnabled;
|
||||
Assert.That(() => vhd.ResilientChangeTrackingEnabled = !b, Throws.Nothing);
|
||||
Assert.AreEqual(!b, vhd.ResilientChangeTrackingEnabled);
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(lfn);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void ExpandTest()
|
||||
public void MergeTest()
|
||||
{
|
||||
const int sz = 0x810400;
|
||||
const int sz = 0x03010400;
|
||||
try
|
||||
{
|
||||
using (var vhd = VirtualDisk.Create(tmpfn, sz, true, null))
|
||||
{
|
||||
using (var vhdp = VirtualDisk.Create(tmpfn, sz))
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
vhd.Expand(sz * 2);
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz * 2));
|
||||
}
|
||||
using var vhd = VirtualDisk.CreateDifferencing(tmpcfn, tmpfn);
|
||||
Assert.That(System.IO.File.Exists(tmpcfn));
|
||||
vhd.Merge(1, 2);
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(tmpcfn);
|
||||
System.IO.File.Delete(tmpfn);
|
||||
}
|
||||
}
|
||||
|
@ -335,11 +291,9 @@ namespace Vanara.IO.Tests
|
|||
{
|
||||
using (var vhdp = VirtualDisk.Create(tmpfn, sz))
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
using (var vhd = VirtualDisk.CreateDifferencing(tmpcfn, tmpfn))
|
||||
{
|
||||
Assert.That(System.IO.File.Exists(tmpcfn));
|
||||
vhd.MergeWithParent();
|
||||
}
|
||||
using var vhd = VirtualDisk.CreateDifferencing(tmpcfn, tmpfn);
|
||||
Assert.That(System.IO.File.Exists(tmpcfn));
|
||||
vhd.MergeWithParent();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -348,24 +302,68 @@ namespace Vanara.IO.Tests
|
|||
}
|
||||
}
|
||||
|
||||
//[Test()]
|
||||
//public async Task CreateFromSourceTest1()
|
||||
//{
|
||||
// VirtualDisk vd = null;
|
||||
// try
|
||||
// {
|
||||
// var cts = new CancellationTokenSource();
|
||||
// var rpt = new Reporter();
|
||||
// var lastVal = 0;
|
||||
// rpt.NewVal += (o, e) => TestContext.WriteLine($"{DateTime.Now:o} NewVal={lastVal = e}");
|
||||
// vd = await VirtualDisk.CreateFromSource(tmpfn, fn, cts.Token, rpt);
|
||||
// Assert.That(lastVal, Is.EqualTo(100));
|
||||
// Assert.That(System.IO.File.Exists(tmpfn));
|
||||
// TestContext.WriteLine($"New file sz: {new System.IO.FileInfo(tmpfn).Length}");
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// vd?.Close();
|
||||
// try { System.IO.File.Delete(tmpfn); } catch { }
|
||||
// }
|
||||
//}
|
||||
[Test()]
|
||||
public void MergeTest()
|
||||
public void OpenAttachRawTest()
|
||||
{
|
||||
const int sz = 0x03010400;
|
||||
try
|
||||
{
|
||||
using (var vhdp = VirtualDisk.Create(tmpfn, sz))
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
using (var vhd = VirtualDisk.CreateDifferencing(tmpcfn, tmpfn))
|
||||
{
|
||||
Assert.That(System.IO.File.Exists(tmpcfn));
|
||||
vhd.Merge(1, 2);
|
||||
}
|
||||
var param = new OPEN_VIRTUAL_DISK_PARAMETERS(false);
|
||||
using var vhd = VirtualDisk.Open(fn, OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NONE, param, VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE);
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
ATTACH_VIRTUAL_DISK_FLAG flags = ATTACH_VIRTUAL_DISK_FLAG.ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY;
|
||||
ATTACH_VIRTUAL_DISK_PARAMETERS aparam = ATTACH_VIRTUAL_DISK_PARAMETERS.Default;
|
||||
SafePSECURITY_DESCRIPTOR sd = ConvertStringSecurityDescriptorToSecurityDescriptor("O:BAG:BAD:(A;;GA;;;WD)");
|
||||
vhd.Attach(flags, ref aparam, sd);
|
||||
Assert.That(vhd.Attached, Is.True);
|
||||
vhd.Detach();
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void OpenAttachTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var vhd = VirtualDisk.Open(fn, true);
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
vhd.Attach(true, true, false, GetWorldFullFileSecurity());
|
||||
Assert.That(vhd.Attached, Is.True);
|
||||
TestContext.WriteLine(vhd.PhysicalPath);
|
||||
Assert.That(vhd.PhysicalPath, Is.Not.Null); // must be attached
|
||||
vhd.Detach();
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
vhd.Attach();
|
||||
Assert.That(vhd.Attached, Is.True);
|
||||
vhd.Close();
|
||||
Assert.That(vhd.Attached, Is.False);
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(tmpcfn);
|
||||
System.IO.File.Delete(tmpfn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,13 +373,11 @@ namespace Vanara.IO.Tests
|
|||
const int sz = 0x810400;
|
||||
try
|
||||
{
|
||||
using (var vhd = VirtualDisk.Create(tmpfn, sz, true, null))
|
||||
{
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
vhd.Resize(sz * 2);
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz * 2));
|
||||
}
|
||||
using var vhd = VirtualDisk.Create(tmpfn, sz, true, null);
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz));
|
||||
vhd.Resize(sz * 2);
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz * 2));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -395,12 +391,10 @@ namespace Vanara.IO.Tests
|
|||
const int sz = 0x810400;
|
||||
try
|
||||
{
|
||||
using (var vhd = VirtualDisk.Create(tmpfn, sz * 2, true, null))
|
||||
{
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz * 2));
|
||||
Assert.That(() => vhd.UnsafeResize(sz), Throws.Exception);
|
||||
}
|
||||
using var vhd = VirtualDisk.Create(tmpfn, sz * 2, true, null);
|
||||
Assert.That(System.IO.File.Exists(tmpfn));
|
||||
Assert.That(vhd.VirtualSize, Is.EqualTo(sz * 2));
|
||||
Assert.That(() => vhd.UnsafeResize(sz), Throws.Exception);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -408,28 +402,164 @@ namespace Vanara.IO.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public async Task CompactTest1()
|
||||
[Test]
|
||||
public void ParentChildTest()
|
||||
{
|
||||
using (var vhd = VirtualDisk.Open(fn, false))
|
||||
const uint PhysicalSectorSize = 4096;
|
||||
const int sz = 0x03010400;
|
||||
|
||||
var tmpfn = VirtualDiskTests.tmpfn + "x";
|
||||
var tmpcfn = VirtualDiskTests.tmpcfn + "x";
|
||||
|
||||
try
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
var rpt = new Reporter();
|
||||
var lastVal = 0;
|
||||
rpt.NewVal += (o, e) => TestContext.WriteLine($"{DateTime.Now:o} NewVal={lastVal = e}");
|
||||
await vhd.Compact(cts.Token, rpt);
|
||||
Assert.That(lastVal, Is.EqualTo(100));
|
||||
VirtualDisk.Create(tmpfn, sz).Dispose();
|
||||
VirtualDisk.CreateDifferencing(tmpcfn, tmpfn).Dispose();
|
||||
|
||||
//
|
||||
// Specify UNKNOWN for both device and vendor so the system will use the
|
||||
// file extension to determine the correct VHD format.
|
||||
//
|
||||
|
||||
VIRTUAL_STORAGE_TYPE storageType = new();
|
||||
storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_TYPE.VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
|
||||
storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;
|
||||
|
||||
//
|
||||
// Open the parent so it's properties can be queried.
|
||||
//
|
||||
// A "GetInfoOnly" handle is a handle that can only be used to query properties or
|
||||
// metadata.
|
||||
//
|
||||
|
||||
OPEN_VIRTUAL_DISK_PARAMETERS openParameters = new(false, true);
|
||||
|
||||
//
|
||||
// Open the VHD/VHDX.
|
||||
//
|
||||
// VIRTUAL_DISK_ACCESS_NONE is the only acceptable access mask for V2 handle opens.
|
||||
// OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS indicates the parent chain should not be opened.
|
||||
//
|
||||
|
||||
OpenVirtualDisk(storageType, tmpfn,
|
||||
VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE,
|
||||
OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS,
|
||||
openParameters, out var parentVhdHandle).ThrowIfFailed();
|
||||
|
||||
using (parentVhdHandle)
|
||||
{
|
||||
//
|
||||
// Get the disk ID of the parent.
|
||||
//
|
||||
|
||||
GET_VIRTUAL_DISK_INFO parentDiskInfo = new();
|
||||
var diskInfoSize = (uint)Marshal.SizeOf(typeof(GET_VIRTUAL_DISK_INFO));
|
||||
parentDiskInfo.Version = GET_VIRTUAL_DISK_INFO_VERSION.GET_VIRTUAL_DISK_INFO_IDENTIFIER;
|
||||
|
||||
GetVirtualDiskInformation(parentVhdHandle, ref diskInfoSize, ref parentDiskInfo, out _).ThrowIfFailed();
|
||||
|
||||
//
|
||||
// Open the VHD/VHDX so it's properties can be queried.
|
||||
//
|
||||
// VIRTUAL_DISK_ACCESS_NONE is the only acceptable access mask for V2 handle opens.
|
||||
// OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS indicates the parent chain should not be opened.
|
||||
//
|
||||
|
||||
OpenVirtualDisk(storageType, tmpcfn,
|
||||
VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE,
|
||||
OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS,
|
||||
openParameters, out var childVhdHandle).ThrowIfFailed();
|
||||
|
||||
using (childVhdHandle)
|
||||
{
|
||||
//
|
||||
// Get the disk ID expected for the parent.
|
||||
//
|
||||
|
||||
GET_VIRTUAL_DISK_INFO childDiskInfo = new();
|
||||
childDiskInfo.Version = GET_VIRTUAL_DISK_INFO_VERSION.GET_VIRTUAL_DISK_INFO_PARENT_IDENTIFIER;
|
||||
diskInfoSize = (uint)Marshal.SizeOf(childDiskInfo);
|
||||
|
||||
GetVirtualDiskInformation(childVhdHandle, ref diskInfoSize, ref childDiskInfo, out _).ThrowIfFailed();
|
||||
|
||||
//
|
||||
// Verify the disk IDs match.
|
||||
//
|
||||
|
||||
if (parentDiskInfo.Identifier != childDiskInfo.ParentIdentifier)
|
||||
Assert.Fail("Disk ID mismatch");
|
||||
|
||||
//
|
||||
// Reset the parent locators in the child.
|
||||
//
|
||||
}
|
||||
|
||||
//
|
||||
// This cannot be a "GetInfoOnly" handle because the intent is to alter the properties of the
|
||||
// VHD/VHDX.
|
||||
//
|
||||
// VIRTUAL_DISK_ACCESS_NONE is the only acceptable access mask for V2 handle opens.
|
||||
// OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS indicates the parent chain should not be opened.
|
||||
//
|
||||
|
||||
openParameters.Version2.GetInfoOnly = false;
|
||||
|
||||
OpenVirtualDisk(storageType, tmpcfn,
|
||||
VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE,
|
||||
OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS,
|
||||
openParameters, out childVhdHandle).ThrowIfFailed();
|
||||
|
||||
using (childVhdHandle)
|
||||
{
|
||||
//
|
||||
// Update the path to the parent.
|
||||
//
|
||||
|
||||
using var pParentPath = new SafeCoTaskMemString(tmpfn);
|
||||
SET_VIRTUAL_DISK_INFO setInfo = new();
|
||||
setInfo.Version = SET_VIRTUAL_DISK_INFO_VERSION.SET_VIRTUAL_DISK_INFO_PARENT_PATH_WITH_DEPTH;
|
||||
setInfo.ParentPathWithDepthInfo = new SET_VIRTUAL_DISK_INFO.SET_VIRTUAL_DISK_INFO_ParentPathWithDepthInfo
|
||||
{
|
||||
ChildDepth = 1,
|
||||
ParentFilePath = (IntPtr)pParentPath
|
||||
};
|
||||
|
||||
SetVirtualDiskInformation(childVhdHandle, setInfo).ThrowIfFailed();
|
||||
|
||||
//
|
||||
// Set the physical sector size.
|
||||
//
|
||||
// This operation will only succeed on VHDX.
|
||||
//
|
||||
|
||||
setInfo.Version = SET_VIRTUAL_DISK_INFO_VERSION.SET_VIRTUAL_DISK_INFO_PHYSICAL_SECTOR_SIZE;
|
||||
setInfo.VhdPhysicalSectorSize = PhysicalSectorSize;
|
||||
|
||||
SetVirtualDiskInformation(childVhdHandle, setInfo).ThrowIfFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.IO.File.Delete(tmpcfn);
|
||||
System.IO.File.Delete(tmpfn);
|
||||
}
|
||||
}
|
||||
|
||||
private static FileSecurity GetFileSecurity(string sddl)
|
||||
{
|
||||
var sd = new FileSecurity();
|
||||
sd.SetSecurityDescriptorSddlForm(sddl);
|
||||
return sd;
|
||||
}
|
||||
|
||||
private static FileSecurity GetWorldFullFileSecurity() => GetFileSecurity("O:BAG:BAD:(A;;GA;;;WD)");
|
||||
|
||||
private class Reporter : IProgress<int>
|
||||
{
|
||||
public event EventHandler<int> NewVal;
|
||||
|
||||
public void Report(int value)
|
||||
{
|
||||
NewVal?.Invoke(this, value);
|
||||
}
|
||||
public void Report(int value) => NewVal?.Invoke(this, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ namespace Vanara.IO
|
|||
ver = version;
|
||||
}
|
||||
|
||||
private delegate Win32Error RunAsyncMethod(ref NativeOverlapped overlap);
|
||||
private delegate Win32Error RunAsyncMethod(in NativeOverlapped overlap);
|
||||
|
||||
/// <summary>Represents the format of the virtual disk.</summary>
|
||||
public enum DeviceType : uint
|
||||
|
@ -83,9 +83,6 @@ namespace Vanara.IO
|
|||
/// <summary>The device identifier.</summary>
|
||||
public DeviceType DiskType => (DeviceType)GetInformation<uint>(GET_VIRTUAL_DISK_INFO_VERSION.GET_VIRTUAL_DISK_INFO_VIRTUAL_STORAGE_TYPE);
|
||||
|
||||
/// <summary>Whether RCT is turned on. TRUE if RCT is turned on; otherwise FALSE.</summary>
|
||||
public bool Enabled => GetInformation<bool>(GET_VIRTUAL_DISK_INFO_VERSION.GET_VIRTUAL_DISK_INFO_CHANGE_TRACKING_STATE);
|
||||
|
||||
/// <summary>The fragmentation level of the virtual disk.</summary>
|
||||
public uint FragmentationPercentage => GetInformation<uint>(GET_VIRTUAL_DISK_INFO_VERSION.GET_VIRTUAL_DISK_INFO_FRAGMENTATION);
|
||||
|
||||
|
@ -117,7 +114,7 @@ namespace Vanara.IO
|
|||
|
||||
/// <summary>Gets the metadata associated with this virtual disk. Currently on VHDX files support metadata.</summary>
|
||||
/// <value>The metadata.</value>
|
||||
public VirtualDiskMetadata Metadata => metadata ?? (metadata = new VirtualDiskMetadata(this));
|
||||
public VirtualDiskMetadata Metadata => metadata ??= new VirtualDiskMetadata(this);
|
||||
|
||||
/// <summary>
|
||||
/// The change tracking identifier for the change that identifies the state of the virtual disk that you want to use as the basis of
|
||||
|
@ -196,6 +193,17 @@ namespace Vanara.IO
|
|||
/// <summary>Provider-specific subtype.</summary>
|
||||
public Subtype ProviderSubtype => (Subtype)GetInformation<uint>(GET_VIRTUAL_DISK_INFO_VERSION.GET_VIRTUAL_DISK_INFO_PROVIDER_SUBTYPE);
|
||||
|
||||
/// <summary>Whether RCT is turned on. TRUE if RCT is turned on; otherwise FALSE.</summary>
|
||||
public bool ResilientChangeTrackingEnabled
|
||||
{
|
||||
get => GetInformation<bool>(GET_VIRTUAL_DISK_INFO_VERSION.GET_VIRTUAL_DISK_INFO_CHANGE_TRACKING_STATE);
|
||||
set
|
||||
{
|
||||
var si = new SET_VIRTUAL_DISK_INFO { Version = SET_VIRTUAL_DISK_INFO_VERSION.SET_VIRTUAL_DISK_INFO_CHANGE_TRACKING_STATE, ChangeTrackingEnabled = value };
|
||||
SetVirtualDiskInformation(Handle, si).ThrowIfFailed();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sector size of the VHD, in bytes.</summary>
|
||||
public uint SectorSize => GetInformation<uint>(GET_VIRTUAL_DISK_INFO_VERSION.GET_VIRTUAL_DISK_INFO_SIZE, 20);
|
||||
|
||||
|
@ -275,8 +283,8 @@ namespace Vanara.IO
|
|||
/// size of the virtual disk.
|
||||
/// </param>
|
||||
/// <param name="blockSize">
|
||||
/// Internal size of the virtual disk object blocks, in bytes. For VHDX this must be a multiple of 1 MB between 1 and 256 MB. For VHD
|
||||
/// 1 this must be set to one of the following values: 0 (default), 0x80000 (512K), or 0x200000 (2MB)
|
||||
/// Internal size of the virtual disk object blocks, in bytes. For VHDX this must be a multiple of 1 MB between 1 and 256 MB. For
|
||||
/// VHD 1 this must be set to one of the following values: 0 (default), 0x80000 (512K), or 0x200000 (2MB)
|
||||
/// </param>
|
||||
/// <param name="logicalSectorSize">
|
||||
/// Internal size of the virtual disk object sectors. For VHDX must be set to 512 (0x200) or 4096 (0x1000). For VHD 1 must be set to 512.
|
||||
|
@ -358,8 +366,8 @@ namespace Vanara.IO
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detach a virtual disk that was previously attached with the ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME flag or calling
|
||||
/// <see cref="Attach(bool, bool, bool, FileSecurity)"/> and setting autoDetach to <c>false</c>.
|
||||
/// Detach a virtual disk that was previously attached with the ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME flag or calling <see
|
||||
/// cref="Attach(bool, bool, bool, FileSecurity)"/> and setting autoDetach to <c>false</c>.
|
||||
/// </summary>
|
||||
/// <param name="path">A valid path to the virtual disk image to detach.</param>
|
||||
public static void Detach(string path)
|
||||
|
@ -498,8 +506,8 @@ namespace Vanara.IO
|
|||
/// </param>
|
||||
/// <returns><c>true</c> if operation completed without error or cancellation; <c>false</c> otherwise.</returns>
|
||||
public async Task<bool> Compact(CancellationToken cancellationToken, IProgress<int> progress) =>
|
||||
await RunAsync(cancellationToken, progress, Handle, (ref NativeOverlapped vhdOverlap) =>
|
||||
CompactVirtualDisk(Handle, COMPACT_VIRTUAL_DISK_FLAG.COMPACT_VIRTUAL_DISK_FLAG_NONE, COMPACT_VIRTUAL_DISK_PARAMETERS.Default, ref vhdOverlap));
|
||||
await RunAsync(cancellationToken, progress, Handle, (in NativeOverlapped vhdOverlap) =>
|
||||
CompactVirtualDisk(Handle, COMPACT_VIRTUAL_DISK_FLAG.COMPACT_VIRTUAL_DISK_FLAG_NONE, COMPACT_VIRTUAL_DISK_PARAMETERS.Default, vhdOverlap));
|
||||
|
||||
/// <summary>
|
||||
/// Detaches a virtual hard disk (VHD) or CD or DVD image file (ISO) by locating an appropriate virtual disk provider to accomplish
|
||||
|
@ -523,7 +531,7 @@ namespace Vanara.IO
|
|||
/// <param name="newSize">New size, in bytes, for the expansion request.</param>
|
||||
public void Expand(ulong newSize)
|
||||
{
|
||||
if (ver < OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_2)
|
||||
if (ver < OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_2)
|
||||
throw new NotSupportedException(@"Expansion is only available to virtual disks opened under version 2 or higher.");
|
||||
ExpandVirtualDisk(Handle, EXPAND_VIRTUAL_DISK_FLAG.EXPAND_VIRTUAL_DISK_FLAG_NONE, new EXPAND_VIRTUAL_DISK_PARAMETERS(newSize), IntPtr.Zero).ThrowIfFailed();
|
||||
}
|
||||
|
@ -538,12 +546,12 @@ namespace Vanara.IO
|
|||
/// disable progress reporting.
|
||||
/// </param>
|
||||
/// <returns><c>true</c> if operation completed without error or cancellation; <c>false</c> otherwise.</returns>
|
||||
public async Task<bool> Expand(ulong newSize, CancellationToken cancellationToken, IProgress<int> progress) =>
|
||||
await RunAsync(cancellationToken, progress, Handle, (ref NativeOverlapped vhdOverlap) =>
|
||||
public async Task<bool> Expand(ulong newSize, CancellationToken cancellationToken, IProgress<int> progress) =>
|
||||
await RunAsync(cancellationToken, progress, Handle, (in NativeOverlapped vhdOverlap) =>
|
||||
{
|
||||
if (ver < OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_2) throw new NotSupportedException(@"Expansion is only available to virtual disks opened under version 2 or higher.");
|
||||
var param = new EXPAND_VIRTUAL_DISK_PARAMETERS(newSize);
|
||||
return ExpandVirtualDisk(Handle, EXPAND_VIRTUAL_DISK_FLAG.EXPAND_VIRTUAL_DISK_FLAG_NONE, param, ref vhdOverlap);
|
||||
return ExpandVirtualDisk(Handle, EXPAND_VIRTUAL_DISK_FLAG.EXPAND_VIRTUAL_DISK_FLAG_NONE, param, vhdOverlap);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -570,7 +578,7 @@ namespace Vanara.IO
|
|||
/// </param>
|
||||
public void Resize(ulong newSize)
|
||||
{
|
||||
if (ver < OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_2)
|
||||
if (ver < OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_2)
|
||||
throw new NotSupportedException(@"Expansion is only available to virtual disks opened under version 2 or higher.");
|
||||
var flags = newSize == 0 ? RESIZE_VIRTUAL_DISK_FLAG.RESIZE_VIRTUAL_DISK_FLAG_RESIZE_TO_SMALLEST_SAFE_VIRTUAL_SIZE : RESIZE_VIRTUAL_DISK_FLAG.RESIZE_VIRTUAL_DISK_FLAG_NONE;
|
||||
var param = new RESIZE_VIRTUAL_DISK_PARAMETERS(newSize);
|
||||
|
@ -588,18 +596,18 @@ namespace Vanara.IO
|
|||
/// </param>
|
||||
/// <returns><c>true</c> if operation completed without error or cancellation; <c>false</c> otherwise.</returns>
|
||||
public async Task<bool> Resize(ulong newSize, CancellationToken cancellationToken, IProgress<int> progress) =>
|
||||
await RunAsync(cancellationToken, progress, Handle, (ref NativeOverlapped vhdOverlap) =>
|
||||
await RunAsync(cancellationToken, progress, Handle, (in NativeOverlapped vhdOverlap) =>
|
||||
{
|
||||
if (ver < OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_2)
|
||||
throw new NotSupportedException(@"Expansion is only available to virtual disks opened under version 2 or higher.");
|
||||
var param = new RESIZE_VIRTUAL_DISK_PARAMETERS(newSize);
|
||||
return ResizeVirtualDisk(Handle, RESIZE_VIRTUAL_DISK_FLAG.RESIZE_VIRTUAL_DISK_FLAG_NONE, param, ref vhdOverlap);
|
||||
return ResizeVirtualDisk(Handle, RESIZE_VIRTUAL_DISK_FLAG.RESIZE_VIRTUAL_DISK_FLAG_NONE, param, vhdOverlap);
|
||||
}
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Resizes a virtual disk without checking the virtual disk's partition table to ensure that this truncation is safe.
|
||||
/// <note type="warning">This method can cause unrecoverable data loss; use with care.</note>
|
||||
/// Resizes a virtual disk without checking the virtual disk's partition table to ensure that this truncation is safe. <note
|
||||
/// type="warning">This method can cause unrecoverable data loss; use with care.</note>
|
||||
/// </summary>
|
||||
/// <param name="newSize">New size, in bytes, for the expansion request.</param>
|
||||
public void UnsafeResize(ulong newSize)
|
||||
|
@ -634,7 +642,7 @@ namespace Vanara.IO
|
|||
|
||||
var param = new CREATE_VIRTUAL_DISK_PARAMETERS(0, IsPreWin8 ? 1U : 2U);
|
||||
var h = IntPtr.Zero;
|
||||
var b = await RunAsync(cancellationToken, progress, VIRTUAL_DISK_HANDLE.NULL, (ref NativeOverlapped vhdOverlap) =>
|
||||
var b = await RunAsync(cancellationToken, progress, VIRTUAL_DISK_HANDLE.NULL, (in NativeOverlapped vhdOverlap) =>
|
||||
{
|
||||
var sp = new SafeCoTaskMemString(sourcePath);
|
||||
var stType = new VIRTUAL_STORAGE_TYPE();
|
||||
|
@ -644,7 +652,7 @@ namespace Vanara.IO
|
|||
else
|
||||
param.Version2.SourcePath = sp;
|
||||
var flags = CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_NONE;
|
||||
var err = CreateVirtualDisk(stType, path, mask, PSECURITY_DESCRIPTOR.NULL, flags, 0, param, ref vhdOverlap, out var hVhd);
|
||||
var err = CreateVirtualDisk(stType, path, mask, PSECURITY_DESCRIPTOR.NULL, flags, 0, param, vhdOverlap, out var hVhd);
|
||||
if (err.Succeeded)
|
||||
{
|
||||
h = hVhd.DangerousGetHandle();
|
||||
|
@ -670,7 +678,7 @@ namespace Vanara.IO
|
|||
progress?.Report(0);
|
||||
while (true)
|
||||
{
|
||||
var perr = GetVirtualDiskOperationProgress(phVhd, ref reset, out var prog);
|
||||
var perr = GetVirtualDiskOperationProgress(phVhd, reset, out var prog);
|
||||
perr.ThrowIfFailed();
|
||||
if (cancellationToken.IsCancellationRequested) return false;
|
||||
switch (prog.OperationStatus)
|
||||
|
@ -700,7 +708,7 @@ namespace Vanara.IO
|
|||
{
|
||||
var vhdOverlapEvent = new ManualResetEvent(false);
|
||||
var vhdOverlap = new NativeOverlapped { EventHandle = vhdOverlapEvent.SafeWaitHandle.DangerousGetHandle() };
|
||||
var err = method(ref vhdOverlap);
|
||||
var err = method(in vhdOverlap);
|
||||
if (err != Win32Error.ERROR_IO_PENDING) err.ThrowIfFailed();
|
||||
return await GetProgress(hVhd, vhdOverlap, cancellationToken, progress);
|
||||
}
|
||||
|
@ -819,19 +827,29 @@ namespace Vanara.IO
|
|||
{
|
||||
get
|
||||
{
|
||||
if (!supported) return new Guid[0];
|
||||
if (parent.Handle.IsClosed) throw new InvalidOperationException("Virtual disk not valid.");
|
||||
uint count = 0;
|
||||
var err = EnumerateVirtualDiskMetadata(parent.Handle, ref count, IntPtr.Zero);
|
||||
if (err != Win32Error.ERROR_MORE_DATA && err != Win32Error.ERROR_INSUFFICIENT_BUFFER) err.ThrowIfFailed();
|
||||
if (count == 0) return new Guid[0];
|
||||
var mem = new SafeCoTaskMemHandle(Marshal.SizeOf(typeof(Guid)) * (int)count);
|
||||
EnumerateVirtualDiskMetadata(parent.Handle, ref count, mem).ThrowIfFailed();
|
||||
return mem.ToArray<Guid>((int)count);
|
||||
var ret = new Guid[0];
|
||||
if (supported)
|
||||
{
|
||||
if (parent.Handle.IsClosed)
|
||||
throw new InvalidOperationException("Virtual disk not valid.");
|
||||
uint count = 0;
|
||||
var err = EnumerateVirtualDiskMetadata(parent.Handle, ref count, null);
|
||||
if (err != Win32Error.ERROR_MORE_DATA && err != Win32Error.ERROR_INSUFFICIENT_BUFFER)
|
||||
err.ThrowIfFailed();
|
||||
if (count != 0)
|
||||
{
|
||||
ret = new Guid[count];
|
||||
EnumerateVirtualDiskMetadata(parent.Handle, ref count, ret).ThrowIfFailed();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets an <see cref="ICollection{SafeCoTaskMemHandle}"/> containing the values in the <see cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>.</summary>
|
||||
/// <summary>
|
||||
/// Gets an <see cref="ICollection{SafeCoTaskMemHandle}"/> containing the values in the <see cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>.
|
||||
/// </summary>
|
||||
public ICollection<SafeCoTaskMemHandle> Values => Keys.Select(k => this[k]).ToList();
|
||||
|
||||
/// <summary>Gets the number of elements contained in the <see cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>.</summary>
|
||||
|
@ -880,8 +898,8 @@ namespace Vanara.IO
|
|||
/// at a particular <see cref="T:System.Array"/> index.
|
||||
/// </summary>
|
||||
/// <param name="array">
|
||||
/// The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from
|
||||
/// <see cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>. The <see cref="T:System.Array"/> must have zero-based indexing.
|
||||
/// The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see
|
||||
/// cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>. The <see cref="T:System.Array"/> must have zero-based indexing.
|
||||
/// </param>
|
||||
/// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
public void CopyTo(KeyValuePair<Guid, SafeCoTaskMemHandle>[] array, int arrayIndex)
|
||||
|
@ -946,7 +964,8 @@ namespace Vanara.IO
|
|||
/// <param name="item">The object to remove from the <see cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>.</param>
|
||||
/// <returns>
|
||||
/// true if <paramref name="item"/> was successfully removed from the <see cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>;
|
||||
/// otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>.
|
||||
/// otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see
|
||||
/// cref="IDictionary{Guid, SafeCoTaskMemHandle}"/>.
|
||||
/// </returns>
|
||||
bool ICollection<KeyValuePair<Guid, SafeCoTaskMemHandle>>.Remove(KeyValuePair<Guid, SafeCoTaskMemHandle> item) => Remove(item.Key);
|
||||
|
||||
|
|
Loading…
Reference in New Issue