// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : DragonFlyBSD.cs // Author(s) : Natalia Portillo // // Component : Partitioning scheme plugins. // // --[ Description ] ---------------------------------------------------------- // // Manages DragonFly BSD 64-bit disklabels. // // --[ License ] -------------------------------------------------------------- // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2025 Natalia Portillo // ****************************************************************************/ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Marshal = Aaru.Helpers.Marshal; namespace Aaru.Partitions; /// /// Implements decoding of DragonFly BSD disklabels [SuppressMessage("ReSharper", "UnusedMember.Local")] public sealed class DragonFlyBSD : IPartition { const uint DISK_MAGIC64 = 0xC4464C59; #region IPartition Members /// public string Name => Localization.DragonFlyBSD_Name; /// public Guid Id => new("D49E41A6-D952-4760-9D94-03DAE2450C5F"); /// public string Author => Authors.NATALIA_PORTILLO; /// public bool GetInformation(IMediaImage imagePlugin, out List partitions, ulong sectorOffset) { partitions = []; uint nSectors = 2048 / imagePlugin.Info.SectorSize; if(2048 % imagePlugin.Info.SectorSize > 0) nSectors++; if(sectorOffset + nSectors >= imagePlugin.Info.Sectors) return false; ErrorNumber errno = imagePlugin.ReadSectors(sectorOffset, false, nSectors, out byte[] sectors, out _); if(errno != ErrorNumber.NoError || sectors.Length < 2048) return false; Disklabel64 disklabel = Marshal.ByteArrayToStructureLittleEndian(sectors); if(disklabel.d_magic != 0xC4464C59) return false; ulong counter = 0; foreach(Partition64 entry in disklabel.d_partitions) { var part = new Partition { Start = entry.p_boffset / imagePlugin.Info.SectorSize + sectorOffset, Offset = entry.p_boffset + sectorOffset * imagePlugin.Info.SectorSize, Size = entry.p_bsize, Length = entry.p_bsize / imagePlugin.Info.SectorSize, Name = entry.p_stor_uuid.ToString(), Sequence = counter, Scheme = Name, Type = (BSD.fsType)entry.p_fstype == BSD.fsType.Other ? entry.p_type_uuid.ToString() : BSD.FSTypeToString((BSD.fsType)entry.p_fstype) }; if(entry.p_bsize % imagePlugin.Info.SectorSize > 0) part.Length++; if(entry.p_bsize <= 0 || entry.p_boffset <= 0) continue; partitions.Add(part); counter++; } return true; } #endregion #region Nested type: Disklabel64 [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct Disklabel64 { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public readonly byte[] d_reserved0; public readonly uint d_magic; public readonly uint d_crc; public readonly uint d_align; public readonly uint d_npartitions; public readonly Guid d_stor_uuid; public readonly ulong d_total_size; public readonly ulong d_bbase; public readonly ulong d_pbase; public readonly ulong d_pstop; public readonly ulong d_abase; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public readonly byte[] d_packname; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public readonly byte[] d_reserved; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public readonly Partition64[] d_partitions; } #endregion #region Nested type: Partition64 [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct Partition64 { public readonly ulong p_boffset; public readonly ulong p_bsize; public readonly byte p_fstype; public readonly byte p_unused01; public readonly byte p_unused02; public readonly byte p_unused03; public readonly uint p_unused04; public readonly uint p_unused05; public readonly uint p_unused06; public readonly Guid p_type_uuid; public readonly Guid p_stor_uuid; } #endregion }