// 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; }
}