diff --git a/DiscImageChef.Partitions/SGI.cs b/DiscImageChef.Partitions/SGI.cs index 04b8c6de6..c6ce02750 100644 --- a/DiscImageChef.Partitions/SGI.cs +++ b/DiscImageChef.Partitions/SGI.cs @@ -34,6 +34,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; +using DiscImageChef.Console; using DiscImageChef.ImagePlugins; namespace DiscImageChef.PartPlugins @@ -52,37 +53,69 @@ namespace DiscImageChef.PartPlugins { partitions = new List(); - // TODO: This is not working - return false; - byte[] sector = imagePlugin.ReadSector(sectorOffset); if(sector.Length < 512) return false; - SGILabel disklabel = BigEndianMarshal.ByteArrayToStructureBigEndian(sector); - for(int i = 0; i < disklabel.volume.Length; i++) - disklabel.volume[i] = BigEndianMarshal.SwapStructureMembersEndian(disklabel.volume[i]); - for(int i = 0; i < disklabel.partitions.Length; i++) - disklabel.partitions[i] = BigEndianMarshal.SwapStructureMembersEndian(disklabel.partitions[i]); + SGILabel dvh = BigEndianMarshal.ByteArrayToStructureBigEndian(sector); + for(int i = 0; i < dvh.volume.Length; i++) + dvh.volume[i] = BigEndianMarshal.SwapStructureMembersEndian(dvh.volume[i]); + for(int i = 0; i < dvh.partitions.Length; i++) + dvh.partitions[i] = BigEndianMarshal.SwapStructureMembersEndian(dvh.partitions[i]); + dvh.device_params = BigEndianMarshal.SwapStructureMembersEndian(dvh.device_params); - if(disklabel.magic != SGI_MAGIC) + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.magic = 0x{0:X8} (should be 0x{1:X8})", dvh.magic, SGI_MAGIC); + + if(dvh.magic != SGI_MAGIC) return false; + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.root_part_num = {0}", dvh.root_part_num); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.swap_part_num = {0}", dvh.swap_part_num); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.boot_file = \"{0}\"", StringHandlers.CToString(dvh.boot_file)); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_skew = {0}", dvh.device_params.dp_skew); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_gap1 = {0}", dvh.device_params.dp_gap1); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_gap2 = {0}", dvh.device_params.dp_gap2); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_spares_cyl = {0}", dvh.device_params.dp_spares_cyl); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_cyls = {0}", dvh.device_params.dp_cyls); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_shd0 = {0}", dvh.device_params.dp_shd0); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_trks0 = {0}", dvh.device_params.dp_trks0); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_ctq_depth = {0}", dvh.device_params.dp_ctq_depth); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_cylshi = {0}", dvh.device_params.dp_cylshi); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_secs = {0}", dvh.device_params.dp_secs); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_secbytes = {0}", dvh.device_params.dp_secbytes); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_interleave = {0}", dvh.device_params.dp_interleave); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_flags = {0}", dvh.device_params.dp_flags); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_datarate = {0}", dvh.device_params.dp_datarate); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_nretries = {0}", dvh.device_params.dp_nretries); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_mspw = {0}", dvh.device_params.dp_mspw); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xgap1 = {0}", dvh.device_params.dp_xgap1); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xsync = {0}", dvh.device_params.dp_xsync); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xrdly = {0}", dvh.device_params.dp_xrdly); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xgap2 = {0}", dvh.device_params.dp_xgap2); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xrgate = {0}", dvh.device_params.dp_xrgate); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xwcont = {0}", dvh.device_params.dp_xwcont); + ulong counter = 0; - foreach(SGIPartition entry in disklabel.partitions) + for(int i = 0; i < dvh.partitions.Length; i++) { - Partition part = new Partition() + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.partitions[{0}].num_blocks = {1}", i, dvh.partitions[i].num_blocks); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.partitions[{0}].first_block = {1}", i, dvh.partitions[i].first_block); + // TODO: Solve big endian marshal with enumerations + dvh.partitions[i].type = (SGIType)Swapping.Swap((uint)dvh.partitions[i].type); + DicConsole.DebugWriteLine("SGIVH plugin", "dvh.partitions[{0}].type = {1}", i, dvh.partitions[i].type); + + Partition part = new Partition { - Start = entry.first_block, - Offset = (entry.first_block * 512), - Size = entry.num_blocks, - Length = (entry.num_blocks * 512), - Type = string.Format("{0}", entry.type), + Start = (dvh.partitions[i].first_block * dvh.device_params.dp_secbytes) / imagePlugin.GetSectorSize(), + Offset = (dvh.partitions[i].first_block * dvh.device_params.dp_secbytes), + Length = (dvh.partitions[i].num_blocks * dvh.device_params.dp_secbytes) / imagePlugin.GetSectorSize(), + Size = (dvh.partitions[i].num_blocks * dvh.device_params.dp_secbytes), + Type = TypeToString(dvh.partitions[i].type), Sequence = counter, Scheme = Name }; - if(part.Size > 0) + if(part.Size > 0 && dvh.partitions[i].type != SGIType.Header && dvh.partitions[i].type != SGIType.Volume) { partitions.Add(part); counter++; @@ -98,15 +131,14 @@ namespace DiscImageChef.PartPlugins /// public uint magic; /// - public ushort root_part_num; + public short root_part_num; /// - public ushort swap_part_num; + public short swap_part_num; /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] boot_file; /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] - public byte[] device_params; + public SGIDeviceParameters device_params; /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] public SGIVolume[] volume; @@ -131,6 +163,69 @@ namespace DiscImageChef.PartPlugins public uint num_bytes; } + enum SGIType : uint + { + Header = 0, + TrkRepl = 1, + SecRepl = 2, + Swap = 3, + Bsd = 4, + SystemV = 5, + Volume = 6, + EFS = 7, + Lvol = 8, + Rlvol = 9, + XFS = 0xA, + Xlvol = 0xB, + Rxlvol = 0xC, + Xvm = 0x0D, + LinuxSwap = 0x82, + Linux = 0x83, + LinuxRAID = 0xFD, + } + + static string TypeToString(SGIType typ) + { + switch(typ) + { + case SGIType.Header: + return "Volume header"; + case SGIType.TrkRepl: + return "Track replacements"; + case SGIType.SecRepl: + return "Sector replacements"; + case SGIType.Swap: + return "Raw data (swap)"; + case SGIType.Bsd: + return "4.2BSD Fast File System"; + case SGIType.SystemV: + return "UNIX System V"; + case SGIType.Volume: + return "Whole device"; + case SGIType.EFS: + return "EFS"; + case SGIType.Lvol: + return "Logical volume"; + case SGIType.Rlvol: + return "Raw logical volume"; + case SGIType.XFS: + return "XFS"; + case SGIType.Xlvol: + return "XFS log device"; + case SGIType.Rxlvol: + return "XLV volume"; + case SGIType.Xvm: + return "SGI XVM"; + case SGIType.LinuxSwap: + return "Linux swap"; + case SGIType.Linux: + return "Linux"; + case SGIType.LinuxRAID: + return "Linux RAID"; + default: + return "Unknown"; + } + } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct SGIPartition { @@ -139,7 +234,34 @@ namespace DiscImageChef.PartPlugins /// public uint first_block; /// - public uint type; + public SGIType type; + } + + struct SGIDeviceParameters + { + public byte dp_skew; + public byte dp_gap1; + public byte dp_gap2; + public byte dp_spares_cyl; + public ushort dp_cyls; + public ushort dp_shd0; + public ushort dp_trks0; + public byte dp_ctq_depth; + public byte dp_cylshi; + public ushort dp_unused; + public ushort dp_secs; + public ushort dp_secbytes; + public ushort dp_interleave; + public uint dp_flags; + public uint dp_datarate; + public uint dp_nretries; + public uint dp_mspw; + public ushort dp_xgap1; + public ushort dp_xsync; + public ushort dp_xrdly; + public ushort dp_xgap2; + public ushort dp_xrgate; + public ushort dp_xwcont; } } } \ No newline at end of file