// Copyright (C) 2025, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
#nullable enable
namespace Duplicati.UnitTest
{
///
/// Helper class for managing VHD (Virtual Hard Disk) files using PowerShell.
/// This class provides methods to create, attach, format, and detach VHD files
/// for testing disk image backup and restore operations.
///
///
/// This class is now a thin wrapper around
/// for backward compatibility. New code should use the
/// interface and instead.
///
internal static class DiskImageVhdHelper
{
private static readonly DiskImage.WindowsDiskImageHelper _helper = new();
///
/// Runs a PowerShell script using the persistent session.
///
/// The PowerShell script to execute.
/// The output from PowerShell.
public static string RunPowerShell(string script)
{
return DiskImage.WindowsDiskImageHelper.RunPowerShell(script);
}
///
/// Creates a VHD file, attaches it to the system, and returns the physical drive path.
///
/// The path where the VHD file will be created.
/// The size of the VHD in megabytes.
/// The physical drive path (e.g., \\.\PhysicalDriveN).
public static string CreateAndAttachVhd(string vhdPath, long sizeMB)
{
return _helper.CreateAndAttachDisk(vhdPath, sizeMB);
}
///
/// Initializes a disk with the specified partition table type (GPT or MBR).
///
/// The disk number.
/// The partition table type ("gpt" or "mbr").
public static void InitializeDisk(int diskNumber, string tableType)
{
_helper.InitializeDisk(diskNumber, tableType);
}
///
/// Creates a partition on the specified disk, formats it with the specified filesystem,
/// and assigns a drive letter.
///
/// The disk number.
/// The filesystem type ("ntfs" or "fat32").
/// The size of the partition in MB (0 for all available space).
/// The assigned drive letter.
public static char CreateAndFormatPartition(int diskNumber, string fsType, long sizeMB = 0)
{
return _helper.CreateAndFormatPartition(diskNumber, fsType, sizeMB);
}
///
/// Flushes the volume cache to ensure all data is written to disk.
///
/// The drive letter.
public static void FlushVolume(char driveLetter)
{
_helper.FlushVolume(driveLetter);
}
///
/// Populates a drive with test data including files of various sizes and directory structures.
///
/// The drive letter to populate.
/// The number of files to create.
/// The size of each file in KB.
public static void PopulateTestData(char driveLetter, int fileCount = 10, int fileSizeKB = 10)
{
_helper.PopulateTestData(driveLetter, fileCount, fileSizeKB);
}
///
/// Detaches a VHD file from the system.
///
/// The path to the VHD file.
public static void DetachVhd(string vhdPath)
{
_helper.DetachDisk(vhdPath);
}
///
/// Unmounts a VHD for writing operations.
///
/// The path to the VHD file.
/// Optional drive letter to unmount.
public static void UnmountForWriting(string vhdPath, char? driveLetter = null)
{
_helper.UnmountForWriting(vhdPath, driveLetter);
}
///
/// Brings a VHD online for read operations.
///
/// The path to the VHD file.
public static void BringOnline(string vhdPath)
{
_helper.BringOnline(vhdPath);
}
///
/// Mounts a VHD for reading and returns the assigned drive letter.
///
/// The path to the VHD file.
/// Optional preferred drive letter.
/// The assigned drive letter.
public static char MountForReading(string vhdPath, char? driveLetter = null)
{
return _helper.MountForReading(vhdPath, driveLetter);
}
///
/// Gets the disk number for an attached VHD.
///
/// The path to the VHD file.
/// The disk number, or -1 if not found.
public static int GetDiskNumber(string vhdPath)
{
return _helper.GetDiskNumber(vhdPath);
}
///
/// Checks if the current process is running with administrator privileges.
///
/// true if running as administrator; otherwise, false.
public static bool IsAdministrator()
{
return _helper.HasRequiredPrivileges();
}
///
/// Cleans up and deletes a VHD file, ensuring it is detached first.
///
/// The path to the VHD file.
public static void CleanupVhd(string vhdPath)
{
_helper.CleanupDisk(vhdPath);
}
///
/// Gets detailed information about a disk.
///
/// The disk number.
/// The PowerShell output for the disk details.
public static string GetDiskDetails(int diskNumber)
{
return _helper.GetDiskDetails(diskNumber);
}
///
/// Gets the volume information for a drive letter.
///
/// The drive letter.
/// The volume information.
public static string GetVolumeInfo(char driveLetter)
{
return _helper.GetVolumeInfo(driveLetter);
}
///
/// Disposes the shared PowerShell session.
/// Call this when done with all VHD operations.
///
public static void DisposeSession()
{
_helper.Dispose();
}
}
}