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; /// /// Represents an unknown partition table type. /// Treats the entire disk as a single partition when the partition table type cannot be determined. /// internal class UnknownPartitionTable : IPartitionTable { /// /// The raw disk associated with this partition table, if available. May be null if no disk access is possible. /// private readonly IRawDisk? m_rawDisk; /// /// Indicates whether this instance has been disposed. After disposal, the instance should not be used. /// private bool m_disposed = false; /// public IRawDisk? RawDisk => m_rawDisk; /// public PartitionTableType TableType => PartitionTableType.Unknown; /// /// Initializes a new instance of the class. /// /// The raw disk, or null if not available. public UnknownPartitionTable(IRawDisk? disk) { m_rawDisk = disk; } /// public async IAsyncEnumerable EnumeratePartitions([System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken) { var partition = await GetPartitionAsync(1, cancellationToken).ConfigureAwait(false); if (partition != null) yield return partition; } /// public Task GetPartitionAsync(int partitionNumber, CancellationToken cancellationToken) { if (partitionNumber != 1 || m_rawDisk == null) return Task.FromResult(null); return Task.FromResult(new BasePartition { PartitionNumber = 1, Type = PartitionType.Unknown, PartitionTable = this, StartOffset = 0, Size = m_rawDisk.Size, Name = null, FilesystemType = FileSystemType.Unknown, VolumeGuid = null, RawDisk = m_rawDisk, StartingLba = 0, EndingLba = 0, Attributes = 0 }); } /// public Task GetProtectiveMbrAsync(CancellationToken cancellationToken) { throw new NotSupportedException("Unknown partition table does not have a protective MBR."); } /// public Task GetPartitionTableDataAsync(CancellationToken cancellationToken) { // For unknown partition tables, return empty data // The disk will be treated as one big partition with unknown filesystem return Task.FromResult(new MemoryStream(Array.Empty(), writable: false)); } /// public void Dispose() { if (m_disposed) return; m_disposed = true; } }