213 lines
5.5 KiB
C#
213 lines
5.5 KiB
C#
// 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;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
public class GeometryMetadata
|
|
{
|
|
/// <summary>
|
|
/// The version of the metadata format.
|
|
/// </summary>
|
|
public int Version { get; set; } = 1;
|
|
|
|
/// <summary>
|
|
/// Disk-level geometry information.
|
|
/// </summary>
|
|
public DiskGeometry? Disk { get; set; }
|
|
|
|
/// <summary>
|
|
/// Partition table-level geometry information.
|
|
/// </summary>
|
|
public PartitionTableGeometry? PartitionTable { get; set; }
|
|
|
|
/// <summary>
|
|
/// Array of partition geometries.
|
|
/// </summary>
|
|
public List<PartitionGeometry>? Partitions { get; set; }
|
|
|
|
/// <summary>
|
|
/// Array of filesystem geometries, keyed by partition number.
|
|
/// </summary>
|
|
public List<FilesystemGeometry>? Filesystems { get; set; }
|
|
|
|
/// <summary>
|
|
/// JSON serialization options.
|
|
/// </summary>
|
|
private static readonly JsonSerializerOptions _jsonOptions = new()
|
|
{
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
|
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) },
|
|
WriteIndented = true
|
|
};
|
|
|
|
/// <summary>
|
|
/// Serializes this metadata to a JSON string.
|
|
/// </summary>
|
|
public string ToJson()
|
|
{
|
|
return JsonSerializer.Serialize(this, _jsonOptions);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserializes a JSON string to a GeometryMetadata instance.
|
|
/// </summary>
|
|
public static GeometryMetadata? FromJson(string json)
|
|
{
|
|
return JsonSerializer.Deserialize<GeometryMetadata>(json, _jsonOptions);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disk-level geometry information.
|
|
/// </summary>
|
|
public class DiskGeometry
|
|
{
|
|
/// <summary>
|
|
/// The device path of the source disk.
|
|
/// </summary>
|
|
public string? DevicePath { get; set; }
|
|
|
|
/// <summary>
|
|
/// The total size of the disk in bytes.
|
|
/// </summary>
|
|
public long Size { get; set; }
|
|
|
|
/// <summary>
|
|
/// The sector size in bytes.
|
|
/// </summary>
|
|
public int SectorSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// The number of sectors on the disk.
|
|
/// </summary>
|
|
public int Sectors { get; set; }
|
|
|
|
/// <summary>
|
|
/// The type of partition table on the disk.
|
|
/// </summary>
|
|
public PartitionTableType TableType { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Partition table-level geometry information.
|
|
/// </summary>
|
|
public class PartitionTableGeometry
|
|
{
|
|
/// <summary>
|
|
/// The type of partition table (MBR, GPT, etc.).
|
|
/// </summary>
|
|
public PartitionTableType Type { get; set; }
|
|
|
|
/// <summary>
|
|
/// The size of the partition table data in bytes.
|
|
/// </summary>
|
|
public long Size { get; set; }
|
|
|
|
/// <summary>
|
|
/// The sector size of the disk.
|
|
/// </summary>
|
|
public int SectorSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// For GPT: whether the disk has a protective MBR.
|
|
/// </summary>
|
|
public bool HasProtectiveMbr { get; set; }
|
|
|
|
/// <summary>
|
|
/// For GPT: the size of the GPT header in bytes.
|
|
/// </summary>
|
|
public int HeaderSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// For MBR: the size of the MBR in bytes (typically 512).
|
|
/// </summary>
|
|
public int MbrSize { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Partition-level geometry information.
|
|
/// </summary>
|
|
public class PartitionGeometry
|
|
{
|
|
/// <summary>
|
|
/// The partition number (1-based).
|
|
/// </summary>
|
|
public int Number { get; set; }
|
|
|
|
/// <summary>
|
|
/// The partition type.
|
|
/// </summary>
|
|
public PartitionType Type { get; set; }
|
|
|
|
/// <summary>
|
|
/// The starting offset of the partition in bytes.
|
|
/// </summary>
|
|
public long StartOffset { get; set; }
|
|
|
|
/// <summary>
|
|
/// The size of the partition in bytes.
|
|
/// </summary>
|
|
public long Size { get; set; }
|
|
|
|
/// <summary>
|
|
/// The partition name (if available).
|
|
/// </summary>
|
|
public string? Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// The filesystem type detected for this partition.
|
|
/// </summary>
|
|
public FileSystemType FilesystemType { get; set; }
|
|
|
|
/// <summary>
|
|
/// The volume GUID for GPT partitions.
|
|
/// </summary>
|
|
public Guid? VolumeGuid { get; set; }
|
|
|
|
/// <summary>
|
|
/// The partition table type this partition belongs to.
|
|
/// </summary>
|
|
public PartitionTableType TableType { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Filesystem-level geometry information.
|
|
/// </summary>
|
|
public class FilesystemGeometry
|
|
{
|
|
/// <summary>
|
|
/// The partition number this filesystem resides on.
|
|
/// </summary>
|
|
public int PartitionNumber { get; set; }
|
|
|
|
/// <summary>
|
|
/// The type of filesystem.
|
|
/// </summary>
|
|
public FileSystemType Type { get; set; }
|
|
|
|
/// <summary>
|
|
/// The starting offset of the partition in bytes.
|
|
/// </summary>
|
|
public long PartitionStartOffset { get; set; }
|
|
|
|
/// <summary>
|
|
/// The block size used by the filesystem.
|
|
/// </summary>
|
|
public int BlockSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Filesystem-specific metadata as a JSON string.
|
|
/// </summary>
|
|
public string? Metadata { get; set; }
|
|
}
|