diff --git a/proprietary/DiskImage/RestoreProvider.cs b/proprietary/DiskImage/RestoreProvider.cs index 3cae0726b..0e8cf0026 100644 --- a/proprietary/DiskImage/RestoreProvider.cs +++ b/proprietary/DiskImage/RestoreProvider.cs @@ -13,6 +13,7 @@ using Duplicati.Library.Utility; using Duplicati.Proprietary.DiskImage.Disk; using Duplicati.Proprietary.DiskImage.Filesystem; using Duplicati.Proprietary.DiskImage.Filesystem.Fat32; +using Duplicati.Proprietary.DiskImage.Filesystem.Ntfs; using Duplicati.Proprietary.DiskImage.General; using Duplicati.Proprietary.DiskImage.Partition; @@ -778,6 +779,7 @@ public sealed class RestoreProvider : IRestoreDestinationProviderModule, IDispos return fsGeom.Type switch { FileSystemType.FAT32 => new Fat32Filesystem(partition, fsGeom.BlockSize), + FileSystemType.NTFS => new NtfsFilesystem(partition, fsGeom.BlockSize), _ => new UnknownFilesystem(partition, fsGeom.BlockSize) }; } diff --git a/proprietary/DiskImage/SourceItems/FilesystemSourceEntry.cs b/proprietary/DiskImage/SourceItems/FilesystemSourceEntry.cs index 1a194f05c..b8783730c 100644 --- a/proprietary/DiskImage/SourceItems/FilesystemSourceEntry.cs +++ b/proprietary/DiskImage/SourceItems/FilesystemSourceEntry.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Duplicati.Library.Interface; using Duplicati.Proprietary.DiskImage.Filesystem; using Duplicati.Proprietary.DiskImage.Filesystem.Fat32; +using Duplicati.Proprietary.DiskImage.Filesystem.Ntfs; using Duplicati.Proprietary.DiskImage.General; namespace Duplicati.Proprietary.DiskImage.SourceItems; @@ -50,13 +51,11 @@ internal class FilesystemSourceEntry(string parentPath, IFilesystem filesystem) int blockSize = 1024 * 1024; // Default 1MB blocks if (fsMetadata is UnkownFilesystemMetadata unknownMeta) - { blockSize = unknownMeta.BlockSize; - } else if (fsMetadata is Fat32FilesystemMetadata fat32Meta) - { blockSize = fat32Meta.BlockSize; - } + else if (fsMetadata is NtfsFilesystemMetadata ntfsMeta) + blockSize = ntfsMeta.BlockSize; return new FilesystemGeometry { @@ -101,6 +100,17 @@ internal class FilesystemSourceEntry(string parentPath, IFilesystem filesystem) metadata["filesystem:AllocatedClusters"] = fat32Meta.AllocatedClusters.ToString(); metadata["filesystem:FreeClusters"] = fat32Meta.FreeClusters.ToString(); } + // For NTFS, extract cluster and MFT information + else if (fsMetadata is NtfsFilesystemMetadata ntfsMeta) + { + metadata["filesystem:BlockSize"] = ntfsMeta.BlockSize.ToString(); + metadata["filesystem:ClusterSize"] = ntfsMeta.ClusterSize.ToString(); + metadata["filesystem:TotalClusters"] = ntfsMeta.TotalClusters.ToString(); + metadata["filesystem:AllocatedClusters"] = ntfsMeta.AllocatedClusters.ToString(); + metadata["filesystem:FreeClusters"] = ntfsMeta.FreeClusters.ToString(); + metadata["filesystem:MftRecordSize"] = ntfsMeta.MftRecordSize.ToString(); + metadata["filesystem:HasJournal"] = ntfsMeta.HasJournal.ToString(); + } } } catch diff --git a/proprietary/DiskImage/SourceItems/PartitionSourceEntry.cs b/proprietary/DiskImage/SourceItems/PartitionSourceEntry.cs index 01fab7965..ebfc1d13b 100644 --- a/proprietary/DiskImage/SourceItems/PartitionSourceEntry.cs +++ b/proprietary/DiskImage/SourceItems/PartitionSourceEntry.cs @@ -12,6 +12,7 @@ using Duplicati.Proprietary.DiskImage.Filesystem; using Duplicati.Library.Utility; using Duplicati.Proprietary.DiskImage.General; using Duplicati.Proprietary.DiskImage.Filesystem.Fat32; +using Duplicati.Proprietary.DiskImage.Filesystem.Ntfs; namespace Duplicati.Proprietary.DiskImage.SourceItems; @@ -46,6 +47,7 @@ internal class PartitionSourceEntry(string parentPath, IPartition partition, boo : partition.FilesystemType switch { FileSystemType.FAT32 => new Fat32Filesystem(partition), + FileSystemType.NTFS => new NtfsFilesystem(partition), _ => new UnknownFilesystem(partition) }; yield return new FilesystemSourceEntry(this.Path, fs);