static dk_label SwapDiskLabel(dk_label label) { DicConsole.DebugWriteLine("Sun plugin", "Swapping dk_label"); label = (dk_label)Marshal.SwapStructureMembersEndian(label); for (int i = 0; i < label.dkl_map.Length; i++) { label.dkl_map[i] = (dk_map)Marshal.SwapStructureMembersEndian(label.dkl_map[i]); } return(label); }
public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset) { partitions = new List <Partition>(); if (imagePlugin.Info.SectorSize < 512) { return(false); } if (sectorOffset + 2 >= imagePlugin.Info.Sectors) { return(false); } bool useDkl = false, useDkl8 = false, useDkl16 = false; byte[] sunSector = imagePlugin.ReadSector(sectorOffset); dk_label dkl = Marshal.ByteArrayToStructureLittleEndian <dk_label>(sunSector); dk_label8 dkl8 = Marshal.ByteArrayToStructureLittleEndian <dk_label8>(sunSector); dk_label16 dkl16 = Marshal.ByteArrayToStructureLittleEndian <dk_label16>(sunSector); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_magic = 0x{0:X4}", dkl.dkl_magic); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_sanity = 0x{0:X8}", dkl8.dkl_vtoc.v_sanity); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sanity = 0x{0:X8}", dkl16.dkl_vtoc.v_sanity); if (dkl.dkl_magic == DKL_MAGIC || dkl.dkl_magic == DKL_CIGAM) { if (dkl16.dkl_vtoc.v_sanity == VTOC_SANE || dkl16.dkl_vtoc.v_sanity == VTOC_ENAS) { useDkl16 = true; } else if (dkl8.dkl_vtoc.v_sanity == VTOC_SANE || dkl8.dkl_vtoc.v_sanity == VTOC_ENAS) { useDkl8 = true; } else { useDkl = true; } } if (!useDkl && !useDkl8 && !useDkl16) { sunSector = imagePlugin.ReadSector(sectorOffset + 1); dkl = Marshal.ByteArrayToStructureLittleEndian <dk_label>(sunSector); dkl8 = Marshal.ByteArrayToStructureLittleEndian <dk_label8>(sunSector); dkl16 = Marshal.ByteArrayToStructureLittleEndian <dk_label16>(sunSector); if (dkl.dkl_magic == DKL_MAGIC || dkl.dkl_magic == DKL_CIGAM) { if (dkl16.dkl_vtoc.v_sanity == VTOC_SANE || dkl16.dkl_vtoc.v_sanity == VTOC_ENAS) { useDkl16 = true; } else if (dkl8.dkl_vtoc.v_sanity == VTOC_SANE || dkl8.dkl_vtoc.v_sanity == VTOC_ENAS) { useDkl8 = true; } else { useDkl = true; } } } if (!useDkl && !useDkl8 && !useDkl16) { return(false); } if (useDkl16 && dkl16.dkl_magic == DKL_CIGAM) { dkl16 = SwapDiskLabel(dkl16); } else if (useDkl8 && dkl8.dkl_magic == DKL_CIGAM) { dkl8 = SwapDiskLabel(dkl8); } else if (useDkl && dkl.dkl_magic == DKL_CIGAM) { dkl = SwapDiskLabel(dkl); } if (useDkl) { ulong sectorsPerCylinder = (ulong)(dkl.dkl_nsect * dkl.dkl_nhead); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_asciilabel = \"{0}\"", StringHandlers.CToString(dkl.dkl_asciilabel)); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_rpm = {0}", dkl.dkl_rpm); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_pcyl = {0}", dkl.dkl_pcyl); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_apc = {0}", dkl.dkl_apc); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_gap1 = {0}", dkl.dkl_gap1); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_gap2 = {0}", dkl.dkl_gap2); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_intrlv = {0}", dkl.dkl_intrlv); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_ncyl = {0}", dkl.dkl_ncyl); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_acyl = {0}", dkl.dkl_acyl); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_nhead = {0}", dkl.dkl_nhead); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_nsect = {0}", dkl.dkl_nsect); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_bhead = {0}", dkl.dkl_bhead); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_ppart = {0}", dkl.dkl_ppart); for (int i = 0; i < NDKMAP; i++) { DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_map[{0}].dkl_cylno = {1}", i, dkl.dkl_map[i].dkl_cylno); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_map[{0}].dkl_nblk = {1}", i, dkl.dkl_map[i].dkl_nblk); } DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_magic = 0x{0:X4}", dkl.dkl_magic); DicConsole.DebugWriteLine("Sun plugin", "dkl.dkl_cksum = 0x{0:X4}", dkl.dkl_cksum); DicConsole.DebugWriteLine("Sun plugin", "sectorsPerCylinder = {0}", sectorsPerCylinder); for (int i = 0; i < NDKMAP; i++) { if (dkl.dkl_map[i].dkl_cylno > 0 && dkl.dkl_map[i].dkl_nblk > 0) { Partition part = new Partition { Size = (ulong)dkl.dkl_map[i].dkl_nblk * DK_LABEL_SIZE, Length = (ulong)(dkl.dkl_map[i].dkl_nblk * DK_LABEL_SIZE / imagePlugin.Info.SectorSize), Sequence = (ulong)i, Offset = ((ulong)dkl.dkl_map[i].dkl_cylno * sectorsPerCylinder + sectorOffset) * DK_LABEL_SIZE, Start = ((ulong)dkl.dkl_map[i].dkl_cylno * sectorsPerCylinder + sectorOffset) * DK_LABEL_SIZE / imagePlugin.Info.SectorSize, Type = "SunOS partition", Scheme = Name }; if (part.Start < imagePlugin.Info.Sectors && part.End <= imagePlugin.Info.Sectors) { partitions.Add(part); } } } } else if (useDkl8) { ulong sectorsPerCylinder = (ulong)(dkl8.dkl_nsect * dkl8.dkl_nhead); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_asciilabel = \"{0}\"", StringHandlers.CToString(dkl8.dkl_asciilabel)); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_version = {0}", dkl8.dkl_vtoc.v_version); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_volume = \"{0}\"", StringHandlers.CToString(dkl8.dkl_vtoc.v_volume)); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_nparts = {0}", dkl8.dkl_vtoc.v_nparts); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_sanity = 0x{0:X8}", dkl8.dkl_vtoc.v_sanity); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_write_reinstruct = {0}", dkl8.dkl_write_reinstruct); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_read_reinstruct = {0}", dkl8.dkl_read_reinstruct); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_rpm = {0}", dkl8.dkl_rpm); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_pcyl = {0}", dkl8.dkl_pcyl); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_apc = {0}", dkl8.dkl_apc); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs1 = {0}", dkl8.dkl_obs1); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs2 = {0}", dkl8.dkl_obs2); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_intrlv = {0}", dkl8.dkl_intrlv); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_ncyl = {0}", dkl8.dkl_ncyl); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_acyl = {0}", dkl8.dkl_acyl); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_nhead = {0}", dkl8.dkl_nhead); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_nsect = {0}", dkl8.dkl_nsect); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs3 = {0}", dkl8.dkl_obs3); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs4 = {0}", dkl8.dkl_obs4); for (int i = 0; i < NDKMAP; i++) { DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_map[{0}].dkl_cylno = {1}", i, dkl8.dkl_map[i].dkl_cylno); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_map[{0}].dkl_nblk = {1}", i, dkl8.dkl_map[i].dkl_nblk); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_part[{0}].p_tag = {1} ({2})", i, dkl8.dkl_vtoc.v_part[i].p_tag, (ushort)dkl8.dkl_vtoc.v_part[i].p_tag); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_part[{0}].p_flag = {1} ({2})", i, dkl8.dkl_vtoc.v_part[i].p_flag, (ushort)dkl8.dkl_vtoc.v_part[i].p_flag); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_timestamp[{0}] = {1}", i, DateHandlers.UnixToDateTime(dkl8.dkl_vtoc.v_timestamp[i])); } DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_magic = 0x{0:X4}", dkl8.dkl_magic); DicConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_cksum = 0x{0:X4}", dkl8.dkl_cksum); DicConsole.DebugWriteLine("Sun plugin", "sectorsPerCylinder = {0}", sectorsPerCylinder); if (dkl8.dkl_vtoc.v_nparts > NDKMAP) { return(false); } for (int i = 0; i < dkl8.dkl_vtoc.v_nparts; i++) { if (dkl8.dkl_map[i].dkl_nblk > 0 && dkl8.dkl_vtoc.v_part[i].p_tag != SunTag.SunEmpty && dkl8.dkl_vtoc.v_part[i].p_tag != SunTag.SunWholeDisk) { Partition part = new Partition { Description = SunFlagsToString(dkl8.dkl_vtoc.v_part[i].p_flag), Size = (ulong)dkl8.dkl_map[i].dkl_nblk * DK_LABEL_SIZE, Length = (ulong)(dkl8.dkl_map[i].dkl_nblk * DK_LABEL_SIZE / imagePlugin.Info.SectorSize), Sequence = (ulong)i, Offset = ((ulong)dkl8.dkl_map[i].dkl_cylno * sectorsPerCylinder + sectorOffset) * DK_LABEL_SIZE, Start = ((ulong)dkl8.dkl_map[i].dkl_cylno * sectorsPerCylinder + sectorOffset) * DK_LABEL_SIZE / imagePlugin.Info.SectorSize, Type = SunIdToString(dkl8.dkl_vtoc.v_part[i].p_tag), Scheme = Name }; if (dkl8.dkl_vtoc.v_timestamp[i] != 0) { part.Description += $"\nPartition timestamped on {DateHandlers.UnixToDateTime(dkl8.dkl_vtoc.v_timestamp[i])}"; } if (part.Start < imagePlugin.Info.Sectors && part.End <= imagePlugin.Info.Sectors) { partitions.Add(part); } } } } else { DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sanity = 0x{0:X8}", dkl16.dkl_vtoc.v_sanity); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_version = {0}", dkl16.dkl_vtoc.v_version); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_volume = \"{0}\"", StringHandlers.CToString(dkl16.dkl_vtoc.v_volume)); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sectorsz = {0}", dkl16.dkl_vtoc.v_sectorsz); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_nparts = {0}", dkl16.dkl_vtoc.v_nparts); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_asciilabel = \"{0}\"", StringHandlers.CToString(dkl16.dkl_vtoc.v_asciilabel)); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_pcyl = {0}", dkl16.dkl_pcyl); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_ncyl = {0}", dkl16.dkl_ncyl); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_acyl = {0}", dkl16.dkl_acyl); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_bcyl = {0}", dkl16.dkl_bcyl); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_nhead = {0}", dkl16.dkl_nhead); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_nsect = {0}", dkl16.dkl_nsect); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_intrlv = {0}", dkl16.dkl_intrlv); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_skew = {0}", dkl16.dkl_skew); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_apc = {0}", dkl16.dkl_apc); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_rpm = {0}", dkl16.dkl_rpm); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_write_reinstruct = {0}", dkl16.dkl_write_reinstruct); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_read_reinstruct = {0}", dkl16.dkl_read_reinstruct); for (int i = 0; i < NDKMAP16; i++) { DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_start = {1}", i, dkl16.dkl_vtoc.v_part[i].p_start); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_size = {1}", i, dkl16.dkl_vtoc.v_part[i].p_size); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_tag = {1} ({2})", i, dkl16.dkl_vtoc.v_part[i].p_tag, (ushort)dkl16.dkl_vtoc.v_part[i].p_tag); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_flag = {1} ({2})", i, dkl16.dkl_vtoc.v_part[i].p_flag, (ushort)dkl16.dkl_vtoc.v_part[i].p_flag); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_timestamp[{0}] = {1}", i, DateHandlers.UnixToDateTime(dkl16.dkl_vtoc.v_timestamp[i])); } DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_magic = 0x{0:X4}", dkl16.dkl_magic); DicConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_cksum = 0x{0:X4}", dkl16.dkl_cksum); if (dkl16.dkl_vtoc.v_nparts > NDKMAP16) { return(false); } for (int i = 0; i < dkl16.dkl_vtoc.v_nparts; i++) { if (dkl16.dkl_vtoc.v_part[i].p_size > 0 && dkl16.dkl_vtoc.v_part[i].p_tag != SunTag.SunEmpty && dkl16.dkl_vtoc.v_part[i].p_tag != SunTag.SunWholeDisk) { Partition part = new Partition { Description = SunFlagsToString(dkl16.dkl_vtoc.v_part[i].p_flag), Size = (ulong)dkl16.dkl_vtoc.v_part[i].p_size * dkl16.dkl_vtoc.v_sectorsz, Length = (ulong)(dkl16.dkl_vtoc.v_part[i].p_size * dkl16.dkl_vtoc.v_sectorsz / imagePlugin.Info.SectorSize), Sequence = (ulong)i, Offset = ((ulong)dkl16.dkl_vtoc.v_part[i].p_start + sectorOffset) * dkl16.dkl_vtoc.v_sectorsz, Start = ((ulong)dkl16.dkl_vtoc.v_part[i].p_start + sectorOffset) * dkl16.dkl_vtoc.v_sectorsz / imagePlugin.Info.SectorSize, Type = SunIdToString(dkl16.dkl_vtoc.v_part[i].p_tag), Scheme = Name }; if (dkl16.dkl_vtoc.v_timestamp[i] != 0) { part.Description += $"\nPartition timestamped on {DateHandlers.UnixToDateTime(dkl16.dkl_vtoc.v_timestamp[i])}"; } if (part.Start < imagePlugin.Info.Sectors && part.End <= imagePlugin.Info.Sectors) { partitions.Add(part); } } } } return(partitions.Count > 0); }