// Copyright (c) 2026 Duplicati Inc. All rights reserved. using System; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; using Duplicati.Proprietary.DiskImage.Disk; using Duplicati.Proprietary.DiskImage.General; namespace Duplicati.Proprietary.DiskImage.Partition; /// /// A reconstructed partition table for restore operations. /// This is a lightweight implementation that stores metadata from the backup. /// It exists only to satisfy the IPartition.PartitionTable reference during restore. /// internal class ReconstructedPartitionTable : IPartitionTable { private readonly IRawDisk _rawDisk; private readonly GeometryMetadata _geometry; private bool _disposed = false; /// /// Initializes a new instance of the class. /// /// The raw disk. /// The geometry metadata. /// The partition table type (GPT or MBR). public ReconstructedPartitionTable(IRawDisk rawDisk, GeometryMetadata geometry, PartitionTableType tableType) { _rawDisk = rawDisk; _geometry = geometry; TableType = tableType; } /// public IRawDisk? RawDisk => _rawDisk; /// public PartitionTableType TableType { get; } /// public IAsyncEnumerable EnumeratePartitions(CancellationToken cancellationToken) { throw new NotSupportedException("Enumeration not supported on reconstructed partition table."); } /// public Task GetPartitionAsync(int partitionNumber, CancellationToken cancellationToken) { throw new NotSupportedException("GetPartitionAsync not supported on reconstructed partition table."); } /// public Task GetProtectiveMbrAsync(CancellationToken cancellationToken) { if (TableType == PartitionTableType.MBR) { throw new NotSupportedException("MBR does not have a protective MBR."); } throw new NotSupportedException("GetProtectiveMbrAsync not supported on reconstructed partition table."); } /// public Task GetPartitionTableDataAsync(CancellationToken cancellationToken) { throw new NotSupportedException("GetPartitionTableDataAsync not supported on reconstructed partition table."); } /// public void Dispose() { if (!_disposed) { _disposed = true; } } }