// Copyright (c) 2026 Duplicati Inc. All rights reserved. using System; using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; namespace Duplicati.Proprietary.DiskImage.General; /// /// Represents the consolidated geometry metadata for a disk image. /// This metadata is stored as a single file during backup and used during restore /// to reconstruct the disk, partition table, partition, and filesystem structures. /// public class GeometryMetadata { /// /// The version of the metadata format. /// public int Version { get; set; } = 1; /// /// Disk-level geometry information. /// public DiskGeometry? Disk { get; set; } /// /// Partition table-level geometry information. /// public PartitionTableGeometry? PartitionTable { get; set; } /// /// Array of partition geometries. /// public List? Partitions { get; set; } /// /// Array of filesystem geometries, keyed by partition number. /// public List? Filesystems { get; set; } /// /// JSON serialization options. /// private static readonly JsonSerializerOptions _jsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }, WriteIndented = true }; /// /// Serializes this metadata to a JSON string. /// public string ToJson() { return JsonSerializer.Serialize(this, _jsonOptions); } /// /// Deserializes a JSON string to a GeometryMetadata instance. /// public static GeometryMetadata? FromJson(string json) { return JsonSerializer.Deserialize(json, _jsonOptions); } } /// /// Disk-level geometry information. /// public class DiskGeometry { /// /// The device path of the source disk. /// public string? DevicePath { get; set; } /// /// The total size of the disk in bytes. /// public long Size { get; set; } /// /// The sector size in bytes. /// public int SectorSize { get; set; } /// /// The number of sectors on the disk. /// public int Sectors { get; set; } /// /// The type of partition table on the disk. /// public PartitionTableType TableType { get; set; } } /// /// Partition table-level geometry information. /// public class PartitionTableGeometry { /// /// The type of partition table (MBR, GPT, etc.). /// public PartitionTableType Type { get; set; } /// /// The size of the partition table data in bytes. /// public long Size { get; set; } /// /// The sector size of the disk. /// public int SectorSize { get; set; } /// /// For GPT: whether the disk has a protective MBR. /// public bool HasProtectiveMbr { get; set; } /// /// For GPT: the size of the GPT header in bytes. /// public int HeaderSize { get; set; } /// /// For MBR: the size of the MBR in bytes (typically 512). /// public int MbrSize { get; set; } } /// /// Partition-level geometry information. /// public class PartitionGeometry { /// /// The partition number (1-based). /// public int Number { get; set; } /// /// The partition type. /// public PartitionType Type { get; set; } /// /// The starting offset of the partition in bytes. /// public long StartOffset { get; set; } /// /// The size of the partition in bytes. /// public long Size { get; set; } /// /// The partition name (if available). /// public string? Name { get; set; } /// /// The filesystem type detected for this partition. /// public FileSystemType FilesystemType { get; set; } /// /// The volume GUID for GPT partitions. /// public Guid? VolumeGuid { get; set; } /// /// The partition table type this partition belongs to. /// public PartitionTableType TableType { get; set; } } /// /// Filesystem-level geometry information. /// public class FilesystemGeometry { /// /// The partition number this filesystem resides on. /// public int PartitionNumber { get; set; } /// /// The type of filesystem. /// public FileSystemType Type { get; set; } /// /// The starting offset of the partition in bytes. /// public long PartitionStartOffset { get; set; } /// /// The block size used by the filesystem. /// public int BlockSize { get; set; } /// /// Filesystem-specific metadata as a JSON string. /// public string? Metadata { get; set; } }