public HttpResponseMessage UploadReport(long timestamp) { DicServerContext ctx = new DicServerContext(); SyncDto sync = new SyncDto(); DateTime lastSync = DateHandlers.UnixToDateTime(timestamp); sync.UsbVendors = new List <UsbVendorDto>(); foreach (UsbVendor vendor in ctx.UsbVendors.Where(v => v.ModifiedWhen > lastSync)) { sync.UsbVendors.Add(new UsbVendorDto { VendorId = (ushort)vendor.VendorId, Vendor = vendor.Vendor }); } sync.UsbProducts = new List <UsbProductDto>(); foreach (UsbProduct product in ctx.UsbProducts.Where(p => p.ModifiedWhen > lastSync)) { sync.UsbProducts.Add(new UsbProductDto { Id = product.Id, Product = product.Product, ProductId = (ushort)product.ProductId, VendorId = (ushort)product.Vendor.VendorId }); } sync.Offsets = new List <CdOffsetDto>(); foreach (CompactDiscOffset offset in ctx.CdOffsets.Where(o => o.ModifiedWhen > lastSync)) { sync.Offsets.Add(new CdOffsetDto(offset, offset.Id)); } sync.Devices = new List <DeviceDto>(); foreach (Device device in ctx.Devices.Where(d => d.ModifiedWhen > lastSync).ToList()) { sync.Devices.Add(new DeviceDto(JsonConvert.DeserializeObject <DeviceReportV2>(JsonConvert.SerializeObject(device, Formatting.None, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore })), device.Id, device.OptimalMultipleSectorsRead)); } JsonSerializer js = JsonSerializer.Create(); StringWriter sw = new StringWriter(); js.Serialize(sw, sync); return(new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent(sw.ToString(), Encoding.UTF8, "application/json") }); }
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); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } if (partition.Start != 0) { return; } spcl16 oldHdr = new spcl16(); spcl_aix aixHdr = new spcl_aix(); s_spcl newHdr = new s_spcl(); uint sbSize = (uint)(Marshal.SizeOf(newHdr) / imagePlugin.Info.SectorSize); if (Marshal.SizeOf(newHdr) % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf(newHdr)) { return; } IntPtr oldPtr = Marshal.AllocHGlobal(Marshal.SizeOf(oldHdr)); Marshal.Copy(sector, 0, oldPtr, Marshal.SizeOf(oldHdr)); oldHdr = (spcl16)Marshal.PtrToStructure(oldPtr, typeof(spcl16)); Marshal.FreeHGlobal(oldPtr); IntPtr aixPtr = Marshal.AllocHGlobal(Marshal.SizeOf(aixHdr)); Marshal.Copy(sector, 0, aixPtr, Marshal.SizeOf(aixHdr)); aixHdr = (spcl_aix)Marshal.PtrToStructure(aixPtr, typeof(spcl_aix)); Marshal.FreeHGlobal(aixPtr); IntPtr newPtr = Marshal.AllocHGlobal(Marshal.SizeOf(newHdr)); Marshal.Copy(sector, 0, newPtr, Marshal.SizeOf(newHdr)); newHdr = (s_spcl)Marshal.PtrToStructure(newPtr, typeof(s_spcl)); Marshal.FreeHGlobal(newPtr); bool useOld = false; bool useAix = false; if (newHdr.c_magic == OFS_MAGIC || newHdr.c_magic == NFS_MAGIC || newHdr.c_magic == OFS_CIGAM || newHdr.c_magic == NFS_CIGAM || newHdr.c_magic == UFS2_MAGIC || newHdr.c_magic == UFS2_CIGAM) { if (newHdr.c_magic == OFS_CIGAM || newHdr.c_magic == NFS_CIGAM || newHdr.c_magic == UFS2_CIGAM) { newHdr = BigEndianMarshal.ByteArrayToStructureBigEndian <s_spcl>(sector); } } else if (aixHdr.c_magic == XIX_MAGIC || aixHdr.c_magic == XIX_CIGAM) { useAix = true; if (aixHdr.c_magic == XIX_CIGAM) { aixHdr = BigEndianMarshal.ByteArrayToStructureBigEndian <spcl_aix>(sector); } } else if (oldHdr.c_magic == OFS_MAGIC) { useOld = true; // Swap PDP-11 endian oldHdr.c_date = (int)Swapping.PDPFromLittleEndian((uint)oldHdr.c_date); oldHdr.c_ddate = (int)Swapping.PDPFromLittleEndian((uint)oldHdr.c_ddate); } else { information = "Could not read dump(8) header block"; return; } StringBuilder sb = new StringBuilder(); XmlFsType = new FileSystemType { ClusterSize = 1024, Clusters = (long)(partition.Size / 1024) }; if (useOld) { XmlFsType.Type = "Old 16-bit dump(8)"; sb.AppendLine(XmlFsType.Type); if (oldHdr.c_date > 0) { XmlFsType.CreationDate = DateHandlers.UnixToDateTime(oldHdr.c_date); XmlFsType.CreationDateSpecified = true; sb.AppendFormat("Dump created on {0}", XmlFsType.CreationDate).AppendLine(); } if (oldHdr.c_ddate > 0) { XmlFsType.BackupDate = DateHandlers.UnixToDateTime(oldHdr.c_ddate); XmlFsType.BackupDateSpecified = true; sb.AppendFormat("Previous dump created on {0}", XmlFsType.BackupDate).AppendLine(); } sb.AppendFormat("Dump volume number: {0}", oldHdr.c_volume).AppendLine(); } else if (useAix) { XmlFsType.Type = "AIX dump(8)"; sb.AppendLine(XmlFsType.Type); if (aixHdr.c_date > 0) { XmlFsType.CreationDate = DateHandlers.UnixToDateTime(aixHdr.c_date); XmlFsType.CreationDateSpecified = true; sb.AppendFormat("Dump created on {0}", XmlFsType.CreationDate).AppendLine(); } if (aixHdr.c_ddate > 0) { XmlFsType.BackupDate = DateHandlers.UnixToDateTime(aixHdr.c_ddate); XmlFsType.BackupDateSpecified = true; sb.AppendFormat("Previous dump created on {0}", XmlFsType.BackupDate).AppendLine(); } sb.AppendFormat("Dump volume number: {0}", aixHdr.c_volume).AppendLine(); } else { XmlFsType.Type = "dump(8)"; sb.AppendLine(XmlFsType.Type); if (newHdr.c_ndate > 0) { XmlFsType.CreationDate = DateHandlers.UnixToDateTime(newHdr.c_ndate); XmlFsType.CreationDateSpecified = true; sb.AppendFormat("Dump created on {0}", XmlFsType.CreationDate).AppendLine(); } else if (newHdr.c_date > 0) { XmlFsType.CreationDate = DateHandlers.UnixToDateTime(newHdr.c_date); XmlFsType.CreationDateSpecified = true; sb.AppendFormat("Dump created on {0}", XmlFsType.CreationDate).AppendLine(); } if (newHdr.c_nddate > 0) { XmlFsType.BackupDate = DateHandlers.UnixToDateTime(newHdr.c_nddate); XmlFsType.BackupDateSpecified = true; sb.AppendFormat("Previous dump created on {0}", XmlFsType.BackupDate).AppendLine(); } else if (newHdr.c_ddate > 0) { XmlFsType.BackupDate = DateHandlers.UnixToDateTime(newHdr.c_ddate); XmlFsType.BackupDateSpecified = true; sb.AppendFormat("Previous dump created on {0}", XmlFsType.BackupDate).AppendLine(); } sb.AppendFormat("Dump volume number: {0}", newHdr.c_volume).AppendLine(); sb.AppendFormat("Dump level: {0}", newHdr.c_level).AppendLine(); string dumpname = StringHandlers.CToString(newHdr.c_label); if (!string.IsNullOrEmpty(dumpname)) { XmlFsType.VolumeName = dumpname; sb.AppendFormat("Dump label: {0}", dumpname).AppendLine(); } string str = StringHandlers.CToString(newHdr.c_filesys); if (!string.IsNullOrEmpty(str)) { sb.AppendFormat("Dumped filesystem name: {0}", str).AppendLine(); } str = StringHandlers.CToString(newHdr.c_dev); if (!string.IsNullOrEmpty(str)) { sb.AppendFormat("Dumped device: {0}", str).AppendLine(); } str = StringHandlers.CToString(newHdr.c_host); if (!string.IsNullOrEmpty(str)) { sb.AppendFormat("Dump hostname: {0}", str).AppendLine(); } } information = sb.ToString(); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; StringBuilder sb = new StringBuilder(); BigEndianBitConverter.IsLittleEndian = true; // Start in little endian until we know what are we handling here int start = 0; bool xenix = false; bool sysv = false; bool sys7th = false; bool coherent = false; bool xenix3 = false; byte[] sb_sector; byte sb_size_in_sectors; int offset = 0; if (imagePlugin.Info.SectorSize <= 0x400 ) // Check if underlying device sector size is smaller than SuperBlock size { sb_size_in_sectors = (byte)(0x400 / imagePlugin.Info.SectorSize); } else { sb_size_in_sectors = 1; // If not a single sector can store it } // Sectors in a cylinder int spc = (int)(imagePlugin.Info.Heads * imagePlugin.Info.SectorsPerTrack); // Superblock can start on 0x000, 0x200, 0x600 and 0x800, not aligned, so we assume 16 (128 bytes/sector) sectors as a safe value int[] locations = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // Superblock can also skip one cylinder (for boot) spc }; foreach (int i in locations) { sb_sector = imagePlugin.ReadSectors((ulong)i + partition.Start, sb_size_in_sectors); uint magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x3F8); if (magic == XENIX_MAGIC || magic == SYSV_MAGIC) { BigEndianBitConverter.IsLittleEndian = true; // Little endian if (magic == SYSV_MAGIC) { sysv = true; offset = 0x200; } else { xenix = true; } start = i; break; } if (magic == XENIX_CIGAM || magic == SYSV_CIGAM) { BigEndianBitConverter.IsLittleEndian = false; // Big endian if (magic == SYSV_CIGAM) { sysv = true; offset = 0x200; } else { xenix = true; } start = i; break; } magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F0); // XENIX 3 magic location if (magic == XENIX_MAGIC) { BigEndianBitConverter.IsLittleEndian = true; // Little endian xenix3 = true; start = i; break; } if (magic == XENIX_CIGAM) { BigEndianBitConverter.IsLittleEndian = false; // Big endian xenix3 = true; start = i; break; } magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8); // XENIX magic location if (magic == SYSV_MAGIC) { BigEndianBitConverter.IsLittleEndian = true; // Little endian sysv = true; start = i; break; } if (magic == SYSV_CIGAM) { BigEndianBitConverter.IsLittleEndian = false; // Big endian sysv = true; start = i; break; } byte[] coherent_string = new byte[6]; Array.Copy(sb_sector, 0x1E4, coherent_string, 0, 6); // Coherent UNIX s_fname location string s_fname = StringHandlers.CToString(coherent_string, Encoding); Array.Copy(sb_sector, 0x1EA, coherent_string, 0, 6); // Coherent UNIX s_fpack location string s_fpack = StringHandlers.CToString(coherent_string, Encoding); if (s_fname == COH_FNAME && s_fpack == COH_FPACK || s_fname == COH_XXXXX && s_fpack == COH_XXXXX || s_fname == COH_XXXXS && s_fpack == COH_XXXXN) { BigEndianBitConverter.IsLittleEndian = true; // Coherent is in PDP endianness, use helper for that coherent = true; start = i; break; } // Now try to identify 7th edition uint s_fsize = BitConverter.ToUInt32(sb_sector, 0x002); ushort s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); ushort s_ninode = BitConverter.ToUInt16(sb_sector, 0x0D0); if (s_fsize <= 0 || s_fsize >= 0xFFFFFFFF || s_nfree <= 0 || s_nfree >= 0xFFFF || s_ninode <= 0 || s_ninode >= 0xFFFF) { continue; } if ((s_fsize & 0xFF) == 0x00 && (s_nfree & 0xFF) == 0x00 && (s_ninode & 0xFF) == 0x00) { // Byteswap s_fsize = ((s_fsize & 0xFF) << 24) + ((s_fsize & 0xFF00) << 8) + ((s_fsize & 0xFF0000) >> 8) + ((s_fsize & 0xFF000000) >> 24); s_nfree = (ushort)(s_nfree >> 8); s_ninode = (ushort)(s_ninode >> 8); } if ((s_fsize & 0xFF000000) != 0x00 || (s_nfree & 0xFF00) != 0x00 || (s_ninode & 0xFF00) != 0x00) { continue; } if (s_fsize >= V7_MAXSIZE || s_nfree >= V7_NICFREE || s_ninode >= V7_NICINOD) { continue; } if (s_fsize * 1024 != (partition.End - partition.Start) * imagePlugin.Info.SectorSize && s_fsize * 512 != (partition.End - partition.Start) * imagePlugin.Info.SectorSize) { continue; } sys7th = true; BigEndianBitConverter.IsLittleEndian = true; start = i; break; } if (!sys7th && !sysv && !coherent && !xenix && !xenix3) { return; } XmlFsType = new FileSystemType(); if (xenix || xenix3) { byte[] xenix_strings = new byte[6]; XenixSuperBlock xnx_sb = new XenixSuperBlock(); sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); if (xenix3) { xnx_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000); xnx_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002); xnx_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x006); xnx_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D0); xnx_sb.s_flock = sb_sector[0x19A]; xnx_sb.s_ilock = sb_sector[0x19B]; xnx_sb.s_fmod = sb_sector[0x19C]; xnx_sb.s_ronly = sb_sector[0x19D]; xnx_sb.s_time = BigEndianBitConverter.ToInt32(sb_sector, 0x19E); xnx_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x1A2); xnx_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A6); xnx_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8); xnx_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA); xnx_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AC); xnx_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AE); Array.Copy(sb_sector, 0x1B0, xenix_strings, 0, 6); xnx_sb.s_fname = StringHandlers.CToString(xenix_strings, Encoding); Array.Copy(sb_sector, 0x1B6, xenix_strings, 0, 6); xnx_sb.s_fpack = StringHandlers.CToString(xenix_strings, Encoding); xnx_sb.s_clean = sb_sector[0x1BC]; xnx_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F0); xnx_sb.s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F4); } else { xnx_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000); xnx_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002); xnx_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x006); xnx_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x198); xnx_sb.s_flock = sb_sector[0x262]; xnx_sb.s_ilock = sb_sector[0x263]; xnx_sb.s_fmod = sb_sector[0x264]; xnx_sb.s_ronly = sb_sector[0x265]; xnx_sb.s_time = BigEndianBitConverter.ToInt32(sb_sector, 0x266); xnx_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x26A); xnx_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x26E); xnx_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x270); xnx_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x272); xnx_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x274); xnx_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x276); Array.Copy(sb_sector, 0x278, xenix_strings, 0, 6); xnx_sb.s_fname = StringHandlers.CToString(xenix_strings, Encoding); Array.Copy(sb_sector, 0x27E, xenix_strings, 0, 6); xnx_sb.s_fpack = StringHandlers.CToString(xenix_strings, Encoding); xnx_sb.s_clean = sb_sector[0x284]; xnx_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x3F8); xnx_sb.s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x3FC); } uint bs = 512; sb.AppendLine("XENIX filesystem"); XmlFsType.Type = "XENIX fs"; switch (xnx_sb.s_type) { case 1: sb.AppendLine("512 bytes per block"); XmlFsType.ClusterSize = 512; break; case 2: sb.AppendLine("1024 bytes per block"); bs = 1024; XmlFsType.ClusterSize = 1024; break; case 3: sb.AppendLine("2048 bytes per block"); bs = 2048; XmlFsType.ClusterSize = 2048; break; default: sb.AppendFormat("Unknown s_type value: 0x{0:X8}", xnx_sb.s_type).AppendLine(); break; } if (imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 || imagePlugin.Info.SectorSize == 2448) { if (bs != 2048) { sb .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", bs, 2048).AppendLine(); } } else { if (bs != imagePlugin.Info.SectorSize) { sb .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", bs, imagePlugin.Info.SectorSize).AppendLine(); } } sb.AppendFormat("{0} zones on volume ({1} bytes)", xnx_sb.s_fsize, xnx_sb.s_fsize * bs).AppendLine(); sb.AppendFormat("{0} free zones on volume ({1} bytes)", xnx_sb.s_tfree, xnx_sb.s_tfree * bs) .AppendLine(); sb.AppendFormat("{0} free blocks on list ({1} bytes)", xnx_sb.s_nfree, xnx_sb.s_nfree * bs) .AppendLine(); sb.AppendFormat("{0} blocks per cylinder ({1} bytes)", xnx_sb.s_cylblks, xnx_sb.s_cylblks * bs) .AppendLine(); sb.AppendFormat("{0} blocks per gap ({1} bytes)", xnx_sb.s_gapblks, xnx_sb.s_gapblks * bs).AppendLine(); sb.AppendFormat("First data zone: {0}", xnx_sb.s_isize).AppendLine(); sb.AppendFormat("{0} free inodes on volume", xnx_sb.s_tinode).AppendLine(); sb.AppendFormat("{0} free inodes on list", xnx_sb.s_ninode).AppendLine(); if (xnx_sb.s_flock > 0) { sb.AppendLine("Free block list is locked"); } if (xnx_sb.s_ilock > 0) { sb.AppendLine("inode cache is locked"); } if (xnx_sb.s_fmod > 0) { sb.AppendLine("Superblock is being modified"); } if (xnx_sb.s_ronly > 0) { sb.AppendLine("Volume is mounted read-only"); } sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixToDateTime(xnx_sb.s_time)) .AppendLine(); if (xnx_sb.s_time != 0) { XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(xnx_sb.s_time); XmlFsType.ModificationDateSpecified = true; } sb.AppendFormat("Volume name: {0}", xnx_sb.s_fname).AppendLine(); XmlFsType.VolumeName = xnx_sb.s_fname; sb.AppendFormat("Pack name: {0}", xnx_sb.s_fpack).AppendLine(); if (xnx_sb.s_clean == 0x46) { sb.AppendLine("Volume is clean"); } else { sb.AppendLine("Volume is dirty"); XmlFsType.Dirty = true; } } if (sysv) { sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); byte[] sysv_strings = new byte[6]; SystemVRelease4SuperBlock sysv_sb = new SystemVRelease4SuperBlock { s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x1FC + offset) }; uint bs = 512; switch (sysv_sb.s_type) { case 1: XmlFsType.ClusterSize = 512; break; case 2: bs = 1024; XmlFsType.ClusterSize = 1024; break; case 3: bs = 2048; XmlFsType.ClusterSize = 2048; break; default: sb.AppendFormat("Unknown s_type value: 0x{0:X8}", sysv_sb.s_type).AppendLine(); break; } sysv_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002 + offset); bool sysvr4 = sysv_sb.s_fsize * bs <= 0 || sysv_sb.s_fsize * bs != partition.Size; if (sysvr4) { sysv_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000 + offset); sysv_sb.s_state = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F4 + offset); sysv_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8 + offset); sysv_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x004 + offset); sysv_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x008 + offset); sysv_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D4 + offset); sysv_sb.s_flock = sb_sector[0x1A0 + offset]; sysv_sb.s_ilock = sb_sector[0x1A1 + offset]; sysv_sb.s_fmod = sb_sector[0x1A2 + offset]; sysv_sb.s_ronly = sb_sector[0x1A3 + offset]; sysv_sb.s_time = BigEndianBitConverter.ToUInt32(sb_sector, 0x1A4 + offset); sysv_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8 + offset); sysv_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA + offset); sysv_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AC + offset); sysv_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AE + offset); sysv_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x1B0 + offset); sysv_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1B4 + offset); Array.Copy(sb_sector, 0x1B6 + offset, sysv_strings, 0, 6); sysv_sb.s_fname = StringHandlers.CToString(sysv_strings, Encoding); Array.Copy(sb_sector, 0x1BC + offset, sysv_strings, 0, 6); sysv_sb.s_fpack = StringHandlers.CToString(sysv_strings, Encoding); sb.AppendLine("System V Release 4 filesystem"); XmlFsType.Type = "SVR4 fs"; } else { sysv_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000 + offset); sysv_sb.s_state = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F4 + offset); sysv_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8 + offset); sysv_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002 + offset); sysv_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x006 + offset); sysv_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D0 + offset); sysv_sb.s_flock = sb_sector[0x19A + offset]; sysv_sb.s_ilock = sb_sector[0x19B + offset]; sysv_sb.s_fmod = sb_sector[0x19C + offset]; sysv_sb.s_ronly = sb_sector[0x19D + offset]; sysv_sb.s_time = BigEndianBitConverter.ToUInt32(sb_sector, 0x19E + offset); sysv_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A2 + offset); sysv_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A4 + offset); sysv_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A6 + offset); sysv_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8 + offset); sysv_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x1AA + offset); sysv_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AE + offset); Array.Copy(sb_sector, 0x1B0 + offset, sysv_strings, 0, 6); sysv_sb.s_fname = StringHandlers.CToString(sysv_strings, Encoding); Array.Copy(sb_sector, 0x1B6 + offset, sysv_strings, 0, 6); sysv_sb.s_fpack = StringHandlers.CToString(sysv_strings, Encoding); sb.AppendLine("System V Release 2 filesystem"); XmlFsType.Type = "SVR2 fs"; } sb.AppendFormat("{0} bytes per block", bs).AppendLine(); XmlFsType.Clusters = sysv_sb.s_fsize; sb.AppendFormat("{0} zones on volume ({1} bytes)", sysv_sb.s_fsize, sysv_sb.s_fsize * bs).AppendLine(); sb.AppendFormat("{0} free zones on volume ({1} bytes)", sysv_sb.s_tfree, sysv_sb.s_tfree * bs) .AppendLine(); sb.AppendFormat("{0} free blocks on list ({1} bytes)", sysv_sb.s_nfree, sysv_sb.s_nfree * bs) .AppendLine(); sb.AppendFormat("{0} blocks per cylinder ({1} bytes)", sysv_sb.s_cylblks, sysv_sb.s_cylblks * bs) .AppendLine(); sb.AppendFormat("{0} blocks per gap ({1} bytes)", sysv_sb.s_gapblks, sysv_sb.s_gapblks * bs) .AppendLine(); sb.AppendFormat("First data zone: {0}", sysv_sb.s_isize).AppendLine(); sb.AppendFormat("{0} free inodes on volume", sysv_sb.s_tinode).AppendLine(); sb.AppendFormat("{0} free inodes on list", sysv_sb.s_ninode).AppendLine(); if (sysv_sb.s_flock > 0) { sb.AppendLine("Free block list is locked"); } if (sysv_sb.s_ilock > 0) { sb.AppendLine("inode cache is locked"); } if (sysv_sb.s_fmod > 0) { sb.AppendLine("Superblock is being modified"); } if (sysv_sb.s_ronly > 0) { sb.AppendLine("Volume is mounted read-only"); } sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixUnsignedToDateTime(sysv_sb.s_time)) .AppendLine(); if (sysv_sb.s_time != 0) { XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(sysv_sb.s_time); XmlFsType.ModificationDateSpecified = true; } sb.AppendFormat("Volume name: {0}", sysv_sb.s_fname).AppendLine(); XmlFsType.VolumeName = sysv_sb.s_fname; sb.AppendFormat("Pack name: {0}", sysv_sb.s_fpack).AppendLine(); if (sysv_sb.s_state == 0x7C269D38 - sysv_sb.s_time) { sb.AppendLine("Volume is clean"); } else { sb.AppendLine("Volume is dirty"); XmlFsType.Dirty = true; } } if (coherent) { sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); CoherentSuperBlock coh_sb = new CoherentSuperBlock(); byte[] coh_strings = new byte[6]; coh_sb.s_isize = BitConverter.ToUInt16(sb_sector, 0x000); coh_sb.s_fsize = Swapping.PDPFromLittleEndian(BitConverter.ToUInt32(sb_sector, 0x002)); coh_sb.s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); coh_sb.s_ninode = BitConverter.ToUInt16(sb_sector, 0x108); coh_sb.s_flock = sb_sector[0x1D2]; coh_sb.s_ilock = sb_sector[0x1D3]; coh_sb.s_fmod = sb_sector[0x1D4]; coh_sb.s_ronly = sb_sector[0x1D5]; coh_sb.s_time = Swapping.PDPFromLittleEndian(BitConverter.ToUInt32(sb_sector, 0x1D6)); coh_sb.s_tfree = Swapping.PDPFromLittleEndian(BitConverter.ToUInt32(sb_sector, 0x1DA)); coh_sb.s_tinode = BitConverter.ToUInt16(sb_sector, 0x1DE); coh_sb.s_int_m = BitConverter.ToUInt16(sb_sector, 0x1E0); coh_sb.s_int_n = BitConverter.ToUInt16(sb_sector, 0x1E2); Array.Copy(sb_sector, 0x1E4, coh_strings, 0, 6); coh_sb.s_fname = StringHandlers.CToString(coh_strings, Encoding); Array.Copy(sb_sector, 0x1EA, coh_strings, 0, 6); coh_sb.s_fpack = StringHandlers.CToString(coh_strings, Encoding); XmlFsType.Type = "Coherent fs"; XmlFsType.ClusterSize = 512; XmlFsType.Clusters = coh_sb.s_fsize; sb.AppendLine("Coherent UNIX filesystem"); if (imagePlugin.Info.SectorSize != 512) { sb .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", 512, 2048).AppendLine(); } sb.AppendFormat("{0} zones on volume ({1} bytes)", coh_sb.s_fsize, coh_sb.s_fsize * 512).AppendLine(); sb.AppendFormat("{0} free zones on volume ({1} bytes)", coh_sb.s_tfree, coh_sb.s_tfree * 512) .AppendLine(); sb.AppendFormat("{0} free blocks on list ({1} bytes)", coh_sb.s_nfree, coh_sb.s_nfree * 512) .AppendLine(); sb.AppendFormat("First data zone: {0}", coh_sb.s_isize).AppendLine(); sb.AppendFormat("{0} free inodes on volume", coh_sb.s_tinode).AppendLine(); sb.AppendFormat("{0} free inodes on list", coh_sb.s_ninode).AppendLine(); if (coh_sb.s_flock > 0) { sb.AppendLine("Free block list is locked"); } if (coh_sb.s_ilock > 0) { sb.AppendLine("inode cache is locked"); } if (coh_sb.s_fmod > 0) { sb.AppendLine("Superblock is being modified"); } if (coh_sb.s_ronly > 0) { sb.AppendLine("Volume is mounted read-only"); } sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixUnsignedToDateTime(coh_sb.s_time)) .AppendLine(); if (coh_sb.s_time != 0) { XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(coh_sb.s_time); XmlFsType.ModificationDateSpecified = true; } sb.AppendFormat("Volume name: {0}", coh_sb.s_fname).AppendLine(); XmlFsType.VolumeName = coh_sb.s_fname; sb.AppendFormat("Pack name: {0}", coh_sb.s_fpack).AppendLine(); } if (sys7th) { sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); UNIX7thEditionSuperBlock v7_sb = new UNIX7thEditionSuperBlock(); byte[] sys7_strings = new byte[6]; v7_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000); v7_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002); v7_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x006); v7_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D0); v7_sb.s_flock = sb_sector[0x19A]; v7_sb.s_ilock = sb_sector[0x19B]; v7_sb.s_fmod = sb_sector[0x19C]; v7_sb.s_ronly = sb_sector[0x19D]; v7_sb.s_time = BigEndianBitConverter.ToUInt32(sb_sector, 0x19E); v7_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x1A2); v7_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A6); v7_sb.s_int_m = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8); v7_sb.s_int_n = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA); Array.Copy(sb_sector, 0x1AC, sys7_strings, 0, 6); v7_sb.s_fname = StringHandlers.CToString(sys7_strings, Encoding); Array.Copy(sb_sector, 0x1B2, sys7_strings, 0, 6); v7_sb.s_fpack = StringHandlers.CToString(sys7_strings, Encoding); XmlFsType.Type = "UNIX 7th Edition fs"; XmlFsType.ClusterSize = 512; XmlFsType.Clusters = v7_sb.s_fsize; sb.AppendLine("UNIX 7th Edition filesystem"); if (imagePlugin.Info.SectorSize != 512) { sb .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", 512, 2048).AppendLine(); } sb.AppendFormat("{0} zones on volume ({1} bytes)", v7_sb.s_fsize, v7_sb.s_fsize * 512).AppendLine(); sb.AppendFormat("{0} free zones on volume ({1} bytes)", v7_sb.s_tfree, v7_sb.s_tfree * 512) .AppendLine(); sb.AppendFormat("{0} free blocks on list ({1} bytes)", v7_sb.s_nfree, v7_sb.s_nfree * 512).AppendLine(); sb.AppendFormat("First data zone: {0}", v7_sb.s_isize).AppendLine(); sb.AppendFormat("{0} free inodes on volume", v7_sb.s_tinode).AppendLine(); sb.AppendFormat("{0} free inodes on list", v7_sb.s_ninode).AppendLine(); if (v7_sb.s_flock > 0) { sb.AppendLine("Free block list is locked"); } if (v7_sb.s_ilock > 0) { sb.AppendLine("inode cache is locked"); } if (v7_sb.s_fmod > 0) { sb.AppendLine("Superblock is being modified"); } if (v7_sb.s_ronly > 0) { sb.AppendLine("Volume is mounted read-only"); } sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixUnsignedToDateTime(v7_sb.s_time)) .AppendLine(); if (v7_sb.s_time != 0) { XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(v7_sb.s_time); XmlFsType.ModificationDateSpecified = true; } sb.AppendFormat("Volume name: {0}", v7_sb.s_fname).AppendLine(); XmlFsType.VolumeName = v7_sb.s_fname; sb.AppendFormat("Pack name: {0}", v7_sb.s_fpack).AppendLine(); } information = sb.ToString(); BigEndianBitConverter.IsLittleEndian = false; // Return to default (bigendian) }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; StringBuilder sbInformation = new StringBuilder(); uint magic = 0; uint sb_size_in_sectors; byte[] ufs_sb_sectors; ulong sb_offset = partition.Start; bool fs_type_42bsd = false; bool fs_type_43bsd = false; bool fs_type_44bsd = false; bool fs_type_ufs = false; bool fs_type_ufs2 = false; bool fs_type_sun = false; bool fs_type_sun86 = false; if (imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 || imagePlugin.Info.SectorSize == 2448) { sb_size_in_sectors = block_size / 2048; } else { sb_size_in_sectors = block_size / imagePlugin.Info.SectorSize; } ulong[] locations = { sb_start_floppy, sb_start_boot, sb_start_long_boot, sb_start_piggy, sb_start_att_dsdd, 8192 / imagePlugin.Info.SectorSize, 65536 / imagePlugin.Info.SectorSize, 262144 / imagePlugin.Info.SectorSize }; foreach (ulong loc in locations.Where(loc => partition.End > partition.Start + loc + sb_size_in_sectors)) { ufs_sb_sectors = imagePlugin.ReadSectors(partition.Start + loc, sb_size_in_sectors); magic = BitConverter.ToUInt32(ufs_sb_sectors, 0x055C); if (magic == UFS_MAGIC || magic == UFS_CIGAM || magic == UFS_MAGIC_BW || magic == UFS_CIGAM_BW || magic == UFS2_MAGIC || magic == UFS2_CIGAM || magic == UFS_BAD_MAGIC || magic == UFS_BAD_CIGAM) { sb_offset = partition.Start + loc; break; } magic = 0; } if (magic == 0) { information = "Not a UFS filesystem, I shouldn't have arrived here!"; return; } XmlFsType = new FileSystemType(); switch (magic) { case UFS_MAGIC: sbInformation.AppendLine("UFS filesystem"); XmlFsType.Type = "UFS"; break; case UFS_CIGAM: sbInformation.AppendLine("Big-endian UFS filesystem"); XmlFsType.Type = "UFS"; break; case UFS_MAGIC_BW: sbInformation.AppendLine("BorderWare UFS filesystem"); XmlFsType.Type = "UFS"; break; case UFS_CIGAM_BW: sbInformation.AppendLine("Big-endian BorderWare UFS filesystem"); XmlFsType.Type = "UFS"; break; case UFS2_MAGIC: sbInformation.AppendLine("UFS2 filesystem"); XmlFsType.Type = "UFS2"; break; case UFS2_CIGAM: sbInformation.AppendLine("Big-endian UFS2 filesystem"); XmlFsType.Type = "UFS2"; break; case UFS_BAD_MAGIC: sbInformation.AppendLine("Incompletely initialized UFS filesystem"); sbInformation.AppendLine("BEWARE!!! Following information may be completely wrong!"); XmlFsType.Type = "UFS"; break; case UFS_BAD_CIGAM: sbInformation.AppendLine("Incompletely initialized big-endian UFS filesystem"); sbInformation.AppendLine("BEWARE!!! Following information may be completely wrong!"); XmlFsType.Type = "UFS"; break; } // Fun with seeking follows on superblock reading! ufs_sb_sectors = imagePlugin.ReadSectors(sb_offset, sb_size_in_sectors); IntPtr sbPtr = Marshal.AllocHGlobal(ufs_sb_sectors.Length); Marshal.Copy(ufs_sb_sectors, 0, sbPtr, ufs_sb_sectors.Length); UFSSuperBlock ufs_sb = (UFSSuperBlock)Marshal.PtrToStructure(sbPtr, typeof(UFSSuperBlock)); Marshal.FreeHGlobal(sbPtr); UFSSuperBlock bs_sfu = BigEndianMarshal.ByteArrayToStructureBigEndian <UFSSuperBlock>(ufs_sb_sectors); if (bs_sfu.fs_magic == UFS_MAGIC && ufs_sb.fs_magic == UFS_CIGAM || bs_sfu.fs_magic == UFS_MAGIC_BW && ufs_sb.fs_magic == UFS_CIGAM_BW || bs_sfu.fs_magic == UFS2_MAGIC && ufs_sb.fs_magic == UFS2_CIGAM || bs_sfu.fs_magic == UFS_BAD_MAGIC && ufs_sb.fs_magic == UFS_BAD_CIGAM) { ufs_sb = bs_sfu; ufs_sb.fs_old_cstotal.cs_nbfree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nbfree); ufs_sb.fs_old_cstotal.cs_ndir = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_ndir); ufs_sb.fs_old_cstotal.cs_nffree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nffree); ufs_sb.fs_old_cstotal.cs_nifree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nifree); ufs_sb.fs_cstotal.cs_numclusters = Swapping.Swap(ufs_sb.fs_cstotal.cs_numclusters); ufs_sb.fs_cstotal.cs_nbfree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nbfree); ufs_sb.fs_cstotal.cs_ndir = Swapping.Swap(ufs_sb.fs_cstotal.cs_ndir); ufs_sb.fs_cstotal.cs_nffree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nffree); ufs_sb.fs_cstotal.cs_nifree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nifree); ufs_sb.fs_cstotal.cs_spare[0] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[0]); ufs_sb.fs_cstotal.cs_spare[1] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[1]); ufs_sb.fs_cstotal.cs_spare[2] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[2]); } DicConsole.DebugWriteLine("FFS plugin", "ufs_sb offset: 0x{0:X8}", sb_offset); DicConsole.DebugWriteLine("FFS plugin", "fs_rlink: 0x{0:X8}", ufs_sb.fs_rlink); DicConsole.DebugWriteLine("FFS plugin", "fs_sblkno: 0x{0:X8}", ufs_sb.fs_sblkno); DicConsole.DebugWriteLine("FFS plugin", "fs_cblkno: 0x{0:X8}", ufs_sb.fs_cblkno); DicConsole.DebugWriteLine("FFS plugin", "fs_iblkno: 0x{0:X8}", ufs_sb.fs_iblkno); DicConsole.DebugWriteLine("FFS plugin", "fs_dblkno: 0x{0:X8}", ufs_sb.fs_dblkno); DicConsole.DebugWriteLine("FFS plugin", "fs_size: 0x{0:X8}", ufs_sb.fs_size); DicConsole.DebugWriteLine("FFS plugin", "fs_dsize: 0x{0:X8}", ufs_sb.fs_dsize); DicConsole.DebugWriteLine("FFS plugin", "fs_ncg: 0x{0:X8}", ufs_sb.fs_ncg); DicConsole.DebugWriteLine("FFS plugin", "fs_bsize: 0x{0:X8}", ufs_sb.fs_bsize); DicConsole.DebugWriteLine("FFS plugin", "fs_fsize: 0x{0:X8}", ufs_sb.fs_fsize); DicConsole.DebugWriteLine("FFS plugin", "fs_frag: 0x{0:X8}", ufs_sb.fs_frag); DicConsole.DebugWriteLine("FFS plugin", "fs_minfree: 0x{0:X8}", ufs_sb.fs_minfree); DicConsole.DebugWriteLine("FFS plugin", "fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask); DicConsole.DebugWriteLine("FFS plugin", "fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask); DicConsole.DebugWriteLine("FFS plugin", "fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift); DicConsole.DebugWriteLine("FFS plugin", "fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift); DicConsole.DebugWriteLine("FFS plugin", "fs_maxcontig: 0x{0:X8}", ufs_sb.fs_maxcontig); DicConsole.DebugWriteLine("FFS plugin", "fs_maxbpg: 0x{0:X8}", ufs_sb.fs_maxbpg); DicConsole.DebugWriteLine("FFS plugin", "fs_fragshift: 0x{0:X8}", ufs_sb.fs_fragshift); DicConsole.DebugWriteLine("FFS plugin", "fs_fsbtodb: 0x{0:X8}", ufs_sb.fs_fsbtodb); DicConsole.DebugWriteLine("FFS plugin", "fs_sbsize: 0x{0:X8}", ufs_sb.fs_sbsize); DicConsole.DebugWriteLine("FFS plugin", "fs_csmask: 0x{0:X8}", ufs_sb.fs_csmask); DicConsole.DebugWriteLine("FFS plugin", "fs_csshift: 0x{0:X8}", ufs_sb.fs_csshift); DicConsole.DebugWriteLine("FFS plugin", "fs_nindir: 0x{0:X8}", ufs_sb.fs_nindir); DicConsole.DebugWriteLine("FFS plugin", "fs_inopb: 0x{0:X8}", ufs_sb.fs_inopb); DicConsole.DebugWriteLine("FFS plugin", "fs_optim: 0x{0:X8}", ufs_sb.fs_optim); DicConsole.DebugWriteLine("FFS plugin", "fs_id_1: 0x{0:X8}", ufs_sb.fs_id_1); DicConsole.DebugWriteLine("FFS plugin", "fs_id_2: 0x{0:X8}", ufs_sb.fs_id_2); DicConsole.DebugWriteLine("FFS plugin", "fs_csaddr: 0x{0:X8}", ufs_sb.fs_csaddr); DicConsole.DebugWriteLine("FFS plugin", "fs_cssize: 0x{0:X8}", ufs_sb.fs_cssize); DicConsole.DebugWriteLine("FFS plugin", "fs_cgsize: 0x{0:X8}", ufs_sb.fs_cgsize); DicConsole.DebugWriteLine("FFS plugin", "fs_ipg: 0x{0:X8}", ufs_sb.fs_ipg); DicConsole.DebugWriteLine("FFS plugin", "fs_fpg: 0x{0:X8}", ufs_sb.fs_fpg); DicConsole.DebugWriteLine("FFS plugin", "fs_fmod: 0x{0:X2}", ufs_sb.fs_fmod); DicConsole.DebugWriteLine("FFS plugin", "fs_clean: 0x{0:X2}", ufs_sb.fs_clean); DicConsole.DebugWriteLine("FFS plugin", "fs_ronly: 0x{0:X2}", ufs_sb.fs_ronly); DicConsole.DebugWriteLine("FFS plugin", "fs_flags: 0x{0:X2}", ufs_sb.fs_flags); DicConsole.DebugWriteLine("FFS plugin", "fs_magic: 0x{0:X8}", ufs_sb.fs_magic); if (ufs_sb.fs_magic == UFS2_MAGIC) { fs_type_ufs2 = true; } else { const uint SunOSEpoch = 0x1A54C580; // We are supposing there cannot be a Sun's fs created before 1/1/1982 00:00:00 fs_type_43bsd = true; // There is no way of knowing this is the version, but there is of knowing it is not. if (ufs_sb.fs_link > 0) { fs_type_42bsd = true; // It was used in 4.2BSD fs_type_43bsd = false; } if ((ufs_sb.fs_maxfilesize & 0xFFFFFFFF) > SunOSEpoch && DateHandlers.UnixUnsignedToDateTime(ufs_sb.fs_maxfilesize & 0xFFFFFFFF) < DateTime.Now) { fs_type_42bsd = false; fs_type_sun = true; fs_type_43bsd = false; } // This is for sure, as it is shared with a sectors/track with non-x86 SunOS, Epoch is absurdly high for that if (ufs_sb.fs_old_npsect > SunOSEpoch && DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect) < DateTime.Now ) { fs_type_42bsd = false; fs_type_sun86 = true; fs_type_sun = false; fs_type_43bsd = false; } if (ufs_sb.fs_cgrotor > 0x00000000 && (uint)ufs_sb.fs_cgrotor < 0xFFFFFFFF) { fs_type_42bsd = false; fs_type_sun = false; fs_type_sun86 = false; fs_type_ufs = true; fs_type_43bsd = false; } // 4.3BSD code does not use these fields, they are always set up to 0 fs_type_43bsd &= ufs_sb.fs_id_2 == 0 && ufs_sb.fs_id_1 == 0; // This is the only 4.4BSD inode format fs_type_44bsd |= ufs_sb.fs_old_inodefmt == 2; } if (!fs_type_ufs2) { sbInformation.AppendLine("There are a lot of variants of UFS using overlapped values on same fields"); sbInformation .AppendLine("I will try to guess which one it is, but unless it's UFS2, I may be surely wrong"); } if (fs_type_42bsd) { sbInformation.AppendLine("Guessed as 42BSD FFS"); } if (fs_type_43bsd) { sbInformation.AppendLine("Guessed as 43BSD FFS"); } if (fs_type_44bsd) { sbInformation.AppendLine("Guessed as 44BSD FFS"); } if (fs_type_sun) { sbInformation.AppendLine("Guessed as SunOS FFS"); } if (fs_type_sun86) { sbInformation.AppendLine("Guessed as SunOS/x86 FFS"); } if (fs_type_ufs) { sbInformation.AppendLine("Guessed as UFS"); } if (fs_type_42bsd) { sbInformation.AppendFormat("Linked list of filesystems: 0x{0:X8}", ufs_sb.fs_link).AppendLine(); } sbInformation.AppendFormat("Superblock LBA: {0}", ufs_sb.fs_sblkno).AppendLine(); sbInformation.AppendFormat("Cylinder-block LBA: {0}", ufs_sb.fs_cblkno).AppendLine(); sbInformation.AppendFormat("inode-block LBA: {0}", ufs_sb.fs_iblkno).AppendLine(); sbInformation.AppendFormat("First data block LBA: {0}", ufs_sb.fs_dblkno).AppendLine(); sbInformation.AppendFormat("Cylinder group offset in cylinder: {0}", ufs_sb.fs_old_cgoffset).AppendLine(); sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_time)) .AppendLine(); XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(ufs_sb.fs_old_time); XmlFsType.ModificationDateSpecified = true; sbInformation.AppendFormat("{0} blocks in volume ({1} bytes)", ufs_sb.fs_old_size, (long)ufs_sb.fs_old_size * ufs_sb.fs_fsize).AppendLine(); XmlFsType.Clusters = ufs_sb.fs_old_size; XmlFsType.ClusterSize = ufs_sb.fs_fsize; sbInformation.AppendFormat("{0} data blocks in volume ({1} bytes)", ufs_sb.fs_old_dsize, (long)ufs_sb.fs_old_dsize * ufs_sb.fs_fsize).AppendLine(); sbInformation.AppendFormat("{0} cylinder groups in volume", ufs_sb.fs_ncg).AppendLine(); sbInformation.AppendFormat("{0} bytes in a basic block", ufs_sb.fs_bsize).AppendLine(); sbInformation.AppendFormat("{0} bytes in a frag block", ufs_sb.fs_fsize).AppendLine(); sbInformation.AppendFormat("{0} frags in a block", ufs_sb.fs_frag).AppendLine(); sbInformation.AppendFormat("{0}% of blocks must be free", ufs_sb.fs_minfree).AppendLine(); sbInformation.AppendFormat("{0}ms for optimal next block", ufs_sb.fs_old_rotdelay).AppendLine(); sbInformation.AppendFormat("disk rotates {0} times per second ({1}rpm)", ufs_sb.fs_old_rps, ufs_sb.fs_old_rps * 60).AppendLine(); /* sbInformation.AppendFormat("fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask).AppendLine(); * sbInformation.AppendFormat("fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask).AppendLine(); * sbInformation.AppendFormat("fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift).AppendLine(); * sbInformation.AppendFormat("fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift).AppendLine();*/ sbInformation.AppendFormat("{0} contiguous blocks at maximum", ufs_sb.fs_maxcontig).AppendLine(); sbInformation.AppendFormat("{0} blocks per cylinder group at maximum", ufs_sb.fs_maxbpg).AppendLine(); sbInformation.AppendFormat("Superblock is {0} bytes", ufs_sb.fs_sbsize).AppendLine(); sbInformation.AppendFormat("NINDIR: 0x{0:X8}", ufs_sb.fs_nindir).AppendLine(); sbInformation.AppendFormat("INOPB: 0x{0:X8}", ufs_sb.fs_inopb).AppendLine(); sbInformation.AppendFormat("NSPF: 0x{0:X8}", ufs_sb.fs_old_nspf).AppendLine(); switch (ufs_sb.fs_optim) { case 0: sbInformation.AppendLine("Filesystem will minimize allocation time"); break; case 1: sbInformation.AppendLine("Filesystem will minimize volume fragmentation"); break; default: sbInformation.AppendFormat("Unknown optimization value: 0x{0:X8}", ufs_sb.fs_optim).AppendLine(); break; } if (fs_type_sun) { sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_old_npsect).AppendLine(); } else if (fs_type_sun86) { sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect)) .AppendLine(); } sbInformation.AppendFormat("Hardware sector interleave: {0}", ufs_sb.fs_old_interleave).AppendLine(); sbInformation.AppendFormat("Sector 0 skew: {0}/track", ufs_sb.fs_old_trackskew).AppendLine(); if (!fs_type_43bsd && ufs_sb.fs_id_1 > 0 && ufs_sb.fs_id_2 > 0) { sbInformation.AppendFormat("Volume ID: 0x{0:X8}{1:X8}", ufs_sb.fs_id_1, ufs_sb.fs_id_2).AppendLine(); } else if (fs_type_43bsd && ufs_sb.fs_id_1 > 0 && ufs_sb.fs_id_2 > 0) { sbInformation.AppendFormat("{0} µsec for head switch", ufs_sb.fs_id_1).AppendLine(); sbInformation.AppendFormat("{0} µsec for track-to-track seek", ufs_sb.fs_id_2).AppendLine(); } sbInformation.AppendFormat("Cylinder group summary LBA: {0}", ufs_sb.fs_old_csaddr).AppendLine(); sbInformation.AppendFormat("{0} bytes in cylinder group summary", ufs_sb.fs_cssize).AppendLine(); sbInformation.AppendFormat("{0} bytes in cylinder group", ufs_sb.fs_cgsize).AppendLine(); sbInformation.AppendFormat("{0} tracks/cylinder", ufs_sb.fs_old_ntrak).AppendLine(); sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_old_nsect).AppendLine(); sbInformation.AppendFormat("{0} sectors/cylinder", ufs_sb.fs_old_spc).AppendLine(); sbInformation.AppendFormat("{0} cylinder in volume", ufs_sb.fs_old_ncyl).AppendLine(); sbInformation.AppendFormat("{0} cylinders/group", ufs_sb.fs_old_cpg).AppendLine(); sbInformation.AppendFormat("{0} inodes per cylinder group", ufs_sb.fs_ipg).AppendLine(); sbInformation.AppendFormat("{0} blocks per group", ufs_sb.fs_fpg / ufs_sb.fs_frag).AppendLine(); sbInformation.AppendFormat("{0} directories", ufs_sb.fs_old_cstotal.cs_ndir).AppendLine(); sbInformation.AppendFormat("{0} free blocks ({1} bytes)", ufs_sb.fs_old_cstotal.cs_nbfree, (long)ufs_sb.fs_old_cstotal.cs_nbfree * ufs_sb.fs_fsize).AppendLine(); XmlFsType.FreeClusters = ufs_sb.fs_old_cstotal.cs_nbfree; XmlFsType.FreeClustersSpecified = true; sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_old_cstotal.cs_nifree).AppendLine(); sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_old_cstotal.cs_nffree).AppendLine(); if (ufs_sb.fs_fmod == 1) { sbInformation.AppendLine("Superblock is under modification"); XmlFsType.Dirty = true; } if (ufs_sb.fs_clean == 1) { sbInformation.AppendLine("Volume is clean"); } if (ufs_sb.fs_ronly == 1) { sbInformation.AppendLine("Volume is read-only"); } sbInformation.AppendFormat("Volume flags: 0x{0:X2}", ufs_sb.fs_flags).AppendLine(); if (fs_type_ufs) { sbInformation.AppendFormat("Volume last mounted on \"{0}\"", StringHandlers.CToString(ufs_sb.fs_fsmnt)) .AppendLine(); } else if (fs_type_ufs2) { sbInformation.AppendFormat("Volume last mounted on \"{0}\"", StringHandlers.CToString(ufs_sb.fs_fsmnt)) .AppendLine(); sbInformation.AppendFormat("Volume name: \"{0}\"", StringHandlers.CToString(ufs_sb.fs_volname)) .AppendLine(); XmlFsType.VolumeName = StringHandlers.CToString(ufs_sb.fs_volname); sbInformation.AppendFormat("Volume ID: 0x{0:X16}", ufs_sb.fs_swuid).AppendLine(); //xmlFSType.VolumeSerial = string.Format("{0:X16}", ufs_sb.fs_swuid); sbInformation.AppendFormat("Last searched cylinder group: {0}", ufs_sb.fs_cgrotor).AppendLine(); sbInformation.AppendFormat("{0} contiguously allocated directories", ufs_sb.fs_contigdirs).AppendLine(); sbInformation.AppendFormat("Standard superblock LBA: {0}", ufs_sb.fs_sblkno).AppendLine(); sbInformation.AppendFormat("{0} directories", ufs_sb.fs_cstotal.cs_ndir).AppendLine(); sbInformation.AppendFormat("{0} free blocks ({1} bytes)", ufs_sb.fs_cstotal.cs_nbfree, ufs_sb.fs_cstotal.cs_nbfree * ufs_sb.fs_fsize).AppendLine(); XmlFsType.FreeClusters = ufs_sb.fs_cstotal.cs_nbfree; XmlFsType.FreeClustersSpecified = true; sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_cstotal.cs_nifree).AppendLine(); sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_cstotal.cs_nffree).AppendLine(); sbInformation.AppendFormat("{0} free clusters", ufs_sb.fs_cstotal.cs_numclusters).AppendLine(); sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_time)) .AppendLine(); XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(ufs_sb.fs_time); XmlFsType.ModificationDateSpecified = true; sbInformation.AppendFormat("{0} blocks ({1} bytes)", ufs_sb.fs_size, ufs_sb.fs_size * ufs_sb.fs_fsize) .AppendLine(); XmlFsType.Clusters = ufs_sb.fs_size; sbInformation .AppendFormat("{0} data blocks ({1} bytes)", ufs_sb.fs_dsize, ufs_sb.fs_dsize * ufs_sb.fs_fsize) .AppendLine(); sbInformation.AppendFormat("Cylinder group summary area LBA: {0}", ufs_sb.fs_csaddr).AppendLine(); sbInformation.AppendFormat("{0} blocks pending of being freed", ufs_sb.fs_pendingblocks).AppendLine(); sbInformation.AppendFormat("{0} inodes pending of being freed", ufs_sb.fs_pendinginodes).AppendLine(); } if (fs_type_sun) { sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect)) .AppendLine(); } else if (fs_type_sun86) { sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_state).AppendLine(); } else if (fs_type_44bsd) { sbInformation.AppendFormat("{0} blocks on cluster summary array", ufs_sb.fs_contigsumsize).AppendLine(); sbInformation.AppendFormat("Maximum length of a symbolic link: {0}", ufs_sb.fs_maxsymlinklen) .AppendLine(); sbInformation.AppendFormat("A file can be {0} bytes at max", ufs_sb.fs_maxfilesize).AppendLine(); sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_state)) .AppendLine(); } if (ufs_sb.fs_old_nrpos > 0) { sbInformation.AppendFormat("{0} rotational positions", ufs_sb.fs_old_nrpos).AppendLine(); } if (ufs_sb.fs_old_rotbloff > 0) { sbInformation.AppendFormat("{0} blocks per rotation", ufs_sb.fs_old_rotbloff).AppendLine(); } information = sbInformation.ToString(); }
public bool Open(IFilter imageFilter) { Header = new ScpHeader(); scpStream = imageFilter.GetDataForkStream(); scpStream.Seek(0, SeekOrigin.Begin); if (scpStream.Length < Marshal.SizeOf(Header)) { return(false); } byte[] hdr = new byte[Marshal.SizeOf(Header)]; scpStream.Read(hdr, 0, Marshal.SizeOf(Header)); IntPtr hdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Header)); Marshal.Copy(hdr, 0, hdrPtr, Marshal.SizeOf(Header)); Header = (ScpHeader)Marshal.PtrToStructure(hdrPtr, typeof(ScpHeader)); Marshal.FreeHGlobal(hdrPtr); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.signature = \"{0}\"", StringHandlers.CToString(Header.signature)); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.version = {0}.{1}", (Header.version & 0xF0) >> 4, Header.version & 0xF); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.type = {0}", Header.type); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.revolutions = {0}", Header.revolutions); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.start = {0}", Header.start); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.end = {0}", Header.end); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.flags = {0}", Header.flags); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.bitCellEncoding = {0}", Header.bitCellEncoding); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.heads = {0}", Header.heads); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.reserved = {0}", Header.reserved); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.checksum = 0x{0:X8}", Header.checksum); if (!scpSignature.SequenceEqual(Header.signature)) { return(false); } ScpTracks = new Dictionary <byte, TrackHeader>(); for (byte t = Header.start; t <= Header.end; t++) { if (t >= Header.offsets.Length) { break; } scpStream.Position = Header.offsets[t]; TrackHeader trk = new TrackHeader { Signature = new byte[3], Entries = new TrackEntry[Header.revolutions] }; scpStream.Read(trk.Signature, 0, trk.Signature.Length); trk.TrackNumber = (byte)scpStream.ReadByte(); if (!trk.Signature.SequenceEqual(trkSignature)) { DicConsole.DebugWriteLine("SuperCardPro plugin", "Track header at {0} contains incorrect signature.", Header.offsets[t]); continue; } if (trk.TrackNumber != t) { DicConsole.DebugWriteLine("SuperCardPro plugin", "Track number at {0} should be {1} but is {2}.", Header.offsets[t], t, trk.TrackNumber); continue; } DicConsole.DebugWriteLine("SuperCardPro plugin", "Found track {0} at {1}.", t, Header.offsets[t]); for (byte r = 0; r < Header.revolutions; r++) { byte[] rev = new byte[Marshal.SizeOf(typeof(TrackEntry))]; scpStream.Read(rev, 0, Marshal.SizeOf(typeof(TrackEntry))); IntPtr revPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TrackEntry))); Marshal.Copy(rev, 0, revPtr, Marshal.SizeOf(typeof(TrackEntry))); trk.Entries[r] = (TrackEntry)Marshal.PtrToStructure(revPtr, typeof(TrackEntry)); Marshal.FreeHGlobal(revPtr); // De-relative offsets trk.Entries[r].dataOffset += Header.offsets[t]; } ScpTracks.Add(t, trk); } if (Header.flags.HasFlag(ScpFlags.HasFooter)) { long position = scpStream.Position; scpStream.Seek(-4, SeekOrigin.End); while (scpStream.Position >= position) { byte[] footerSig = new byte[4]; scpStream.Read(footerSig, 0, 4); uint footerMagic = BitConverter.ToUInt32(footerSig, 0); if (footerMagic == FOOTER_SIGNATURE) { scpStream.Seek(-Marshal.SizeOf(typeof(ScpFooter)), SeekOrigin.Current); DicConsole.DebugWriteLine("SuperCardPro plugin", "Found footer at {0}", scpStream.Position); byte[] ftr = new byte[Marshal.SizeOf(typeof(ScpFooter))]; scpStream.Read(ftr, 0, Marshal.SizeOf(typeof(ScpFooter))); IntPtr ftrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ScpFooter))); Marshal.Copy(ftr, 0, ftrPtr, Marshal.SizeOf(typeof(ScpFooter))); ScpFooter footer = (ScpFooter)Marshal.PtrToStructure(ftrPtr, typeof(ScpFooter)); Marshal.FreeHGlobal(ftrPtr); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.manufacturerOffset = 0x{0:X8}", footer.manufacturerOffset); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.modelOffset = 0x{0:X8}", footer.modelOffset); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.serialOffset = 0x{0:X8}", footer.serialOffset); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.creatorOffset = 0x{0:X8}", footer.creatorOffset); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.applicationOffset = 0x{0:X8}", footer.applicationOffset); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.commentsOffset = 0x{0:X8}", footer.commentsOffset); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.creationTime = {0}", footer.creationTime); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.modificationTime = {0}", footer.modificationTime); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.applicationVersion = {0}.{1}", (footer.applicationVersion & 0xF0) >> 4, footer.applicationVersion & 0xF); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.hardwareVersion = {0}.{1}", (footer.hardwareVersion & 0xF0) >> 4, footer.hardwareVersion & 0xF); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.firmwareVersion = {0}.{1}", (footer.firmwareVersion & 0xF0) >> 4, footer.firmwareVersion & 0xF); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.imageVersion = {0}.{1}", (footer.imageVersion & 0xF0) >> 4, footer.imageVersion & 0xF); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.signature = \"{0}\"", StringHandlers.CToString(BitConverter.GetBytes(footer.signature))); imageInfo.DriveManufacturer = ReadPStringUtf8(scpStream, footer.manufacturerOffset); imageInfo.DriveModel = ReadPStringUtf8(scpStream, footer.modelOffset); imageInfo.DriveSerialNumber = ReadPStringUtf8(scpStream, footer.serialOffset); imageInfo.Creator = ReadPStringUtf8(scpStream, footer.creatorOffset); imageInfo.Application = ReadPStringUtf8(scpStream, footer.applicationOffset); imageInfo.Comments = ReadPStringUtf8(scpStream, footer.commentsOffset); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.driveManufacturer = \"{0}\"", imageInfo.DriveManufacturer); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.driveModel = \"{0}\"", imageInfo.DriveModel); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.driveSerialNumber = \"{0}\"", imageInfo.DriveSerialNumber); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.imageCreator = \"{0}\"", imageInfo.Creator); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.imageApplication = \"{0}\"", imageInfo.Application); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.imageComments = \"{0}\"", imageInfo.Comments); imageInfo.CreationTime = footer.creationTime != 0 ? DateHandlers.UnixToDateTime(footer.creationTime) : imageFilter.GetCreationTime(); imageInfo.LastModificationTime = footer.modificationTime != 0 ? DateHandlers.UnixToDateTime(footer.modificationTime) : imageFilter.GetLastWriteTime(); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.imageCreationTime = {0}", imageInfo.CreationTime); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.imageLastModificationTime = {0}", imageInfo.LastModificationTime); imageInfo.ApplicationVersion = $"{(footer.applicationVersion & 0xF0) >> 4}.{footer.applicationVersion & 0xF}"; imageInfo.DriveFirmwareRevision = $"{(footer.firmwareVersion & 0xF0) >> 4}.{footer.firmwareVersion & 0xF}"; imageInfo.Version = $"{(footer.imageVersion & 0xF0) >> 4}.{footer.imageVersion & 0xF}"; break; } scpStream.Seek(-8, SeekOrigin.Current); } } else { imageInfo.Application = "SuperCardPro"; imageInfo.ApplicationVersion = $"{(Header.version & 0xF0) >> 4}.{Header.version & 0xF}"; imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.Version = "1.5"; } throw new NotImplementedException("Flux decoding is not yet implemented."); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("ibm850"); information = ""; var sb = new StringBuilder(); byte[] hpfsBpbSector = imagePlugin.ReadSector(0 + partition.Start); // Seek to BIOS parameter block, on logical sector 0 byte[] hpfsSbSector = imagePlugin.ReadSector(16 + partition.Start); // Seek to superblock, on logical sector 16 byte[] hpfsSpSector = imagePlugin.ReadSector(17 + partition.Start); // Seek to spareblock, on logical sector 17 BiosParameterBlock bpb = Marshal.ByteArrayToStructureLittleEndian <BiosParameterBlock>(hpfsBpbSector); SuperBlock hpfsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(hpfsSbSector); SpareBlock sp = Marshal.ByteArrayToStructureLittleEndian <SpareBlock>(hpfsSpSector); if (StringHandlers.CToString(bpb.fs_type) != "HPFS " || hpfsSb.magic1 != 0xF995E849 || hpfsSb.magic2 != 0xFA53E9C5 || sp.magic1 != 0xF9911849 || sp.magic2 != 0xFA5229C5) { sb.AppendLine("This may not be HPFS, following information may be not correct."); sb.AppendFormat("File system type: \"{0}\" (Should be \"HPFS \")", bpb.fs_type).AppendLine(); sb.AppendFormat("Superblock magic1: 0x{0:X8} (Should be 0xF995E849)", hpfsSb.magic1).AppendLine(); sb.AppendFormat("Superblock magic2: 0x{0:X8} (Should be 0xFA53E9C5)", hpfsSb.magic2).AppendLine(); sb.AppendFormat("Spareblock magic1: 0x{0:X8} (Should be 0xF9911849)", sp.magic1).AppendLine(); sb.AppendFormat("Spareblock magic2: 0x{0:X8} (Should be 0xFA5229C5)", sp.magic2).AppendLine(); } sb.AppendFormat("OEM name: {0}", StringHandlers.CToString(bpb.oem_name)).AppendLine(); sb.AppendFormat("{0} bytes per sector", bpb.bps).AppendLine(); // sb.AppendFormat("{0} sectors per cluster", hpfs_bpb.spc).AppendLine(); // sb.AppendFormat("{0} reserved sectors", hpfs_bpb.rsectors).AppendLine(); // sb.AppendFormat("{0} FATs", hpfs_bpb.fats_no).AppendLine(); // sb.AppendFormat("{0} entries on root directory", hpfs_bpb.root_ent).AppendLine(); // sb.AppendFormat("{0} mini sectors on volume", hpfs_bpb.sectors).AppendLine(); sb.AppendFormat("Media descriptor: 0x{0:X2}", bpb.media).AppendLine(); // sb.AppendFormat("{0} sectors per FAT", hpfs_bpb.spfat).AppendLine(); // sb.AppendFormat("{0} sectors per track", hpfs_bpb.sptrk).AppendLine(); // sb.AppendFormat("{0} heads", hpfs_bpb.heads).AppendLine(); sb.AppendFormat("{0} sectors hidden before BPB", bpb.hsectors).AppendLine(); sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfsSb.sectors, hpfsSb.sectors * bpb.bps).AppendLine(); // sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfs_bpb.big_sectors, hpfs_bpb.big_sectors * hpfs_bpb.bps).AppendLine(); sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", bpb.drive_no).AppendLine(); sb.AppendFormat("NT Flags: 0x{0:X2}", bpb.nt_flags).AppendLine(); sb.AppendFormat("Signature: 0x{0:X2}", bpb.signature).AppendLine(); sb.AppendFormat("Serial number: 0x{0:X8}", bpb.serial_no).AppendLine(); sb.AppendFormat("Volume label: {0}", StringHandlers.CToString(bpb.volume_label, Encoding)).AppendLine(); // sb.AppendFormat("Filesystem type: \"{0}\"", hpfs_bpb.fs_type).AppendLine(); DateTime lastChk = DateHandlers.UnixToDateTime(hpfsSb.last_chkdsk); DateTime lastOptim = DateHandlers.UnixToDateTime(hpfsSb.last_optim); sb.AppendFormat("HPFS version: {0}", hpfsSb.version).AppendLine(); sb.AppendFormat("Functional version: {0}", hpfsSb.func_version).AppendLine(); sb.AppendFormat("Sector of root directory FNode: {0}", hpfsSb.root_fnode).AppendLine(); sb.AppendFormat("{0} sectors are marked bad", hpfsSb.badblocks).AppendLine(); sb.AppendFormat("Sector of free space bitmaps: {0}", hpfsSb.bitmap_lsn).AppendLine(); sb.AppendFormat("Sector of bad blocks list: {0}", hpfsSb.badblock_lsn).AppendLine(); if (hpfsSb.last_chkdsk > 0) { sb.AppendFormat("Date of last integrity check: {0}", lastChk).AppendLine(); } else { sb.AppendLine("Filesystem integrity has never been checked"); } if (hpfsSb.last_optim > 0) { sb.AppendFormat("Date of last optimization {0}", lastOptim).AppendLine(); } else { sb.AppendLine("Filesystem has never been optimized"); } sb.AppendFormat("Directory band has {0} sectors", hpfsSb.dband_sectors).AppendLine(); sb.AppendFormat("Directory band starts at sector {0}", hpfsSb.dband_start).AppendLine(); sb.AppendFormat("Directory band ends at sector {0}", hpfsSb.dband_last).AppendLine(); sb.AppendFormat("Sector of directory band bitmap: {0}", hpfsSb.dband_bitmap).AppendLine(); sb.AppendFormat("Sector of ACL directory: {0}", hpfsSb.acl_start).AppendLine(); sb.AppendFormat("Sector of Hotfix directory: {0}", sp.hotfix_start).AppendLine(); sb.AppendFormat("{0} used Hotfix entries", sp.hotfix_used).AppendLine(); sb.AppendFormat("{0} total Hotfix entries", sp.hotfix_entries).AppendLine(); sb.AppendFormat("{0} free spare DNodes", sp.spare_dnodes_free).AppendLine(); sb.AppendFormat("{0} total spare DNodes", sp.spare_dnodes).AppendLine(); sb.AppendFormat("Sector of codepage directory: {0}", sp.codepage_lsn).AppendLine(); sb.AppendFormat("{0} codepages used in the volume", sp.codepages).AppendLine(); sb.AppendFormat("SuperBlock CRC32: {0:X8}", sp.sb_crc32).AppendLine(); sb.AppendFormat("SpareBlock CRC32: {0:X8}", sp.sp_crc32).AppendLine(); sb.AppendLine("Flags:"); sb.AppendLine((sp.flags1 & 0x01) == 0x01 ? "Filesystem is dirty." : "Filesystem is clean."); if ((sp.flags1 & 0x02) == 0x02) { sb.AppendLine("Spare directory blocks are in use"); } if ((sp.flags1 & 0x04) == 0x04) { sb.AppendLine("Hotfixes are in use"); } if ((sp.flags1 & 0x08) == 0x08) { sb.AppendLine("Disk contains bad sectors"); } if ((sp.flags1 & 0x10) == 0x10) { sb.AppendLine("Disk has a bad bitmap"); } if ((sp.flags1 & 0x20) == 0x20) { sb.AppendLine("Filesystem was formatted fast"); } if ((sp.flags1 & 0x40) == 0x40) { sb.AppendLine("Unknown flag 0x40 on flags1 is active"); } if ((sp.flags1 & 0x80) == 0x80) { sb.AppendLine("Filesystem has been mounted by an old IFS"); } if ((sp.flags2 & 0x01) == 0x01) { sb.AppendLine("Install DASD limits"); } if ((sp.flags2 & 0x02) == 0x02) { sb.AppendLine("Resync DASD limits"); } if ((sp.flags2 & 0x04) == 0x04) { sb.AppendLine("DASD limits are operational"); } if ((sp.flags2 & 0x08) == 0x08) { sb.AppendLine("Multimedia is active"); } if ((sp.flags2 & 0x10) == 0x10) { sb.AppendLine("DCE ACLs are active"); } if ((sp.flags2 & 0x20) == 0x20) { sb.AppendLine("DASD limits are dirty"); } if ((sp.flags2 & 0x40) == 0x40) { sb.AppendLine("Unknown flag 0x40 on flags2 is active"); } if ((sp.flags2 & 0x80) == 0x80) { sb.AppendLine("Unknown flag 0x80 on flags2 is active"); } XmlFsType = new FileSystemType(); // Theoretically everything from BPB to SB is boot code, should I hash everything or only the sector loaded by BIOS itself? if (bpb.jump[0] == 0xEB && bpb.jump[1] > 0x3C && bpb.jump[1] < 0x80 && bpb.signature2 == 0xAA55) { XmlFsType.Bootable = true; string bootChk = Sha1Context.Data(bpb.boot_code, out byte[] _); sb.AppendLine("Volume is bootable"); sb.AppendFormat("Boot code's SHA1: {0}", bootChk).AppendLine(); } XmlFsType.Dirty |= (sp.flags1 & 0x01) == 0x01; XmlFsType.Clusters = hpfsSb.sectors; XmlFsType.ClusterSize = bpb.bps; XmlFsType.Type = "HPFS"; XmlFsType.VolumeName = StringHandlers.CToString(bpb.volume_label, Encoding); XmlFsType.VolumeSerial = $"{bpb.serial_no:X8}"; XmlFsType.SystemIdentifier = StringHandlers.CToString(bpb.oem_name); information = sb.ToString(); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } var locusSb = new Superblock(); byte[] sector = null; for (ulong location = 0; location <= 8; location++) { uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return; } locusSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); if (locusSb.s_magic == LOCUS_MAGIC || locusSb.s_magic == LOCUS_CIGAM || locusSb.s_magic == LOCUS_MAGIC_OLD || locusSb.s_magic == LOCUS_CIGAM_OLD) { break; } } // We don't care about old version for information if (locusSb.s_magic != LOCUS_MAGIC && locusSb.s_magic != LOCUS_CIGAM && locusSb.s_magic != LOCUS_MAGIC_OLD && locusSb.s_magic != LOCUS_CIGAM_OLD) { return; } // Numerical arrays are not important for information so no need to swap them if (locusSb.s_magic == LOCUS_CIGAM || locusSb.s_magic == LOCUS_CIGAM_OLD) { locusSb = Marshal.ByteArrayToStructureBigEndian <Superblock>(sector); locusSb.s_flags = (Flags)Swapping.Swap((ushort)locusSb.s_flags); } var sb = new StringBuilder(); sb.AppendLine(locusSb.s_magic == LOCUS_MAGIC_OLD ? "Locus filesystem (old)" : "Locus filesystem"); int blockSize = locusSb.s_version == Version.SB_SB4096 ? 4096 : 1024; string s_fsmnt = StringHandlers.CToString(locusSb.s_fsmnt, Encoding); string s_fpack = StringHandlers.CToString(locusSb.s_fpack, Encoding); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_magic = 0x{0:X8}", locusSb.s_magic); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_gfs = {0}", locusSb.s_gfs); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fsize = {0}", locusSb.s_fsize); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_lwm = {0}", locusSb.s_lwm); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_hwm = {0}", locusSb.s_hwm); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_llst = {0}", locusSb.s_llst); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fstore = {0}", locusSb.s_fstore); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_time = {0}", locusSb.s_time); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_tfree = {0}", locusSb.s_tfree); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_isize = {0}", locusSb.s_isize); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_nfree = {0}", locusSb.s_nfree); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_flags = {0}", locusSb.s_flags); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_tinode = {0}", locusSb.s_tinode); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_lasti = {0}", locusSb.s_lasti); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_nbehind = {0}", locusSb.s_nbehind); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_gfspack = {0}", locusSb.s_gfspack); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_ninode = {0}", locusSb.s_ninode); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_flock = {0}", locusSb.s_flock); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_ilock = {0}", locusSb.s_ilock); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fmod = {0}", locusSb.s_fmod); AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_version = {0}", locusSb.s_version); sb.AppendFormat("Superblock last modified on {0}", DateHandlers.UnixToDateTime(locusSb.s_time)). AppendLine(); sb.AppendFormat("Volume has {0} blocks of {1} bytes each (total {2} bytes)", locusSb.s_fsize, blockSize, locusSb.s_fsize * blockSize).AppendLine(); sb.AppendFormat("{0} blocks free ({1} bytes)", locusSb.s_tfree, locusSb.s_tfree * blockSize).AppendLine(); sb.AppendFormat("I-node list uses {0} blocks", locusSb.s_isize).AppendLine(); sb.AppendFormat("{0} free inodes", locusSb.s_tinode).AppendLine(); sb.AppendFormat("Next free inode search will start at inode {0}", locusSb.s_lasti).AppendLine(); sb.AppendFormat("There are an estimate of {0} free inodes before next search start", locusSb.s_nbehind). AppendLine(); if (locusSb.s_flags.HasFlag(Flags.SB_RDONLY)) { sb.AppendLine("Read-only volume"); } if (locusSb.s_flags.HasFlag(Flags.SB_CLEAN)) { sb.AppendLine("Clean volume"); } if (locusSb.s_flags.HasFlag(Flags.SB_DIRTY)) { sb.AppendLine("Dirty volume"); } if (locusSb.s_flags.HasFlag(Flags.SB_RMV)) { sb.AppendLine("Removable volume"); } if (locusSb.s_flags.HasFlag(Flags.SB_PRIMPACK)) { sb.AppendLine("This is the primary pack"); } if (locusSb.s_flags.HasFlag(Flags.SB_REPLTYPE)) { sb.AppendLine("Replicated volume"); } if (locusSb.s_flags.HasFlag(Flags.SB_USER)) { sb.AppendLine("User replicated volume"); } if (locusSb.s_flags.HasFlag(Flags.SB_BACKBONE)) { sb.AppendLine("Backbone volume"); } if (locusSb.s_flags.HasFlag(Flags.SB_NFS)) { sb.AppendLine("NFS volume"); } if (locusSb.s_flags.HasFlag(Flags.SB_BYHAND)) { sb.AppendLine("Volume inhibits automatic fsck"); } if (locusSb.s_flags.HasFlag(Flags.SB_NOSUID)) { sb.AppendLine("Set-uid/set-gid is disabled"); } if (locusSb.s_flags.HasFlag(Flags.SB_SYNCW)) { sb.AppendLine("Volume uses synchronous writes"); } sb.AppendFormat("Volume label: {0}", s_fsmnt).AppendLine(); sb.AppendFormat("Physical volume name: {0}", s_fpack).AppendLine(); sb.AppendFormat("Global File System number: {0}", locusSb.s_gfs).AppendLine(); sb.AppendFormat("Global File System pack number {0}", locusSb.s_gfspack).AppendLine(); information = sb.ToString(); XmlFsType = new FileSystemType { Type = "Locus filesystem", ClusterSize = (uint)blockSize, Clusters = (ulong)locusSb.s_fsize, // Sometimes it uses one, or the other. Use the bigger VolumeName = string.IsNullOrEmpty(s_fsmnt) ? s_fpack : s_fsmnt, ModificationDate = DateHandlers.UnixToDateTime(locusSb.s_time), ModificationDateSpecified = true, Dirty = !locusSb.s_flags.HasFlag(Flags.SB_CLEAN) || locusSb.s_flags.HasFlag(Flags.SB_DIRTY), FreeClusters = (ulong)locusSb.s_tfree, FreeClustersSpecified = true }; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return; } Superblock unicosSb = Marshal.ByteArrayToStructureBigEndian <Superblock>(sector); if (unicosSb.s_magic != UNICOS_MAGIC) { return; } var sb = new StringBuilder(); sb.AppendLine("UNICOS filesystem"); if (unicosSb.s_secure == UNICOS_SECURE) { sb.AppendLine("Volume is secure"); } sb.AppendFormat("Volume contains {0} partitions", unicosSb.s_npart).AppendLine(); sb.AppendFormat("{0} bytes per sector", unicosSb.s_iounit).AppendLine(); sb.AppendLine("4096 bytes per block"); sb.AppendFormat("{0} data blocks in volume", unicosSb.s_fsize).AppendLine(); sb.AppendFormat("Root resides on inode {0}", unicosSb.s_root).AppendLine(); sb.AppendFormat("{0} inodes in volume", unicosSb.s_isize).AppendLine(); sb.AppendFormat("Volume last updated on {0}", DateHandlers.UnixToDateTime(unicosSb.s_time)).AppendLine(); if (unicosSb.s_error > 0) { sb.AppendFormat("Volume is dirty, error code = 0x{0:X16}", unicosSb.s_error).AppendLine(); } sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(unicosSb.s_fname, Encoding)).AppendLine(); information = sb.ToString(); XmlFsType = new FileSystemType { Type = "UNICOS filesystem", ClusterSize = 4096, Clusters = (ulong)unicosSb.s_fsize, VolumeName = StringHandlers.CToString(unicosSb.s_fname, Encoding), ModificationDate = DateHandlers.UnixToDateTime(unicosSb.s_time), ModificationDateSpecified = true }; XmlFsType.Dirty |= unicosSb.s_error > 0; }
public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset) { partitions = new List <Partition>(); uint magic = 0; ulong pdloc = 0; byte[] pdsector = null; bool magicFound = false; bool absolute = false; foreach (ulong i in new ulong[] { 0, 1, 8, 29 }.TakeWhile(i => i + sectorOffset < imagePlugin.Info.Sectors)) { pdsector = imagePlugin.ReadSector(i + sectorOffset); magic = BitConverter.ToUInt32(pdsector, 4); AaruConsole.DebugWriteLine("VTOC plugin", "sanity at {0} is 0x{1:X8} (should be 0x{2:X8} or 0x{3:X8})", i + sectorOffset, magic, PD_MAGIC, PD_CIGAM); if (magic != PD_MAGIC && magic != PD_CIGAM) { continue; } magicFound = true; pdloc = i; break; } if (!magicFound) { return(false); } PDInfo pd; PDInfoOld pdold; if (magic == PD_MAGIC) { pd = Marshal.ByteArrayToStructureLittleEndian <PDInfo>(pdsector); pdold = Marshal.ByteArrayToStructureLittleEndian <PDInfoOld>(pdsector); } else { pd = Marshal.ByteArrayToStructureBigEndian <PDInfo>(pdsector); pdold = Marshal.ByteArrayToStructureBigEndian <PDInfoOld>(pdsector); } AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.driveid = {0}", pd.driveid); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.sanity = 0x{0:X8} (should be 0x{1:X8})", pd.sanity, PD_MAGIC); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.version = {0}", pd.version); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.serial = \"{0}\"", StringHandlers.CToString(pd.serial)); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.cyls = {0}", pd.cyls); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.tracks = {0}", pd.tracks); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.sectors = {0}", pd.sectors); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.bytes = {0}", pd.bytes); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.logicalst = {0}", pd.logicalst); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.errlogst = {0}", pd.errlogst); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.errlogsz = {0}", pd.errlogsz); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.mfgst = {0}", pd.mfgst); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.mfgsz = {0}", pd.mfgsz); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.defectst = {0}", pd.defectst); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.defectsz = {0}", pd.defectsz); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.relno = {0}", pd.relno); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.relst = {0}", pd.relst); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.relsz = {0}", pd.relsz); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.relnext = {0}", pd.relnext); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.allcstrt = {0}", pdold.allcstrt); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.allcend = {0}", pdold.allcend); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.vtoc_ptr = {0}", pd.vtoc_ptr); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.vtoc_len = {0}", pd.vtoc_len); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.vtoc_pad = {0}", pd.vtoc_pad); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.alt_ptr = {0}", pd.alt_ptr); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.alt_len = {0}", pd.alt_len); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pcyls = {0}", pd.pcyls); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.ptracks = {0}", pd.ptracks); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.psectors = {0}", pd.psectors); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pbytes = {0}", pd.pbytes); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.secovhd = {0}", pd.secovhd); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.interleave = {0}", pd.interleave); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.skew = {0}", pd.skew); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[0] = {0}", pd.pad[0]); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[1] = {0}", pd.pad[1]); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[2] = {0}", pd.pad[2]); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[3] = {0}", pd.pad[3]); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[4] = {0}", pd.pad[4]); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[5] = {0}", pd.pad[5]); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[6] = {0}", pd.pad[6]); AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[7] = {0}", pd.pad[7]); magicFound = false; bool useOld = false; byte[] vtocsector = imagePlugin.ReadSector(pdloc + sectorOffset + 1); var vtoc = new vtoc(); var vtocOld = new vtocold(); magic = BitConverter.ToUInt32(vtocsector, 0); if (magic == VTOC_SANE || magic == VTOC_ENAS) { magicFound = true; AaruConsole.DebugWriteLine("VTOC plugin", "New VTOC found at {0}", pdloc + sectorOffset + 1); if (magic == VTOC_SANE) { vtoc = Marshal.ByteArrayToStructureLittleEndian <vtoc>(vtocsector); } else { vtoc = Marshal.ByteArrayToStructureBigEndian <vtoc>(vtocsector); for (int i = 0; i < vtoc.v_part.Length; i++) { vtoc.v_part[i].p_tag = (pTag)Swapping.Swap((ushort)vtoc.v_part[i].p_tag); vtoc.v_part[i].p_flag = (pFlag)Swapping.Swap((ushort)vtoc.v_part[i].p_flag); vtoc.v_part[i].p_start = Swapping.Swap(vtoc.v_part[i].p_start); vtoc.v_part[i].p_size = Swapping.Swap(vtoc.v_part[i].p_size); vtoc.timestamp[i] = Swapping.Swap(vtoc.timestamp[i]); } } } if (!magicFound && pd.version < XPDVERS) { magic = BitConverter.ToUInt32(vtocsector, 12); if (magic == VTOC_SANE || magic == VTOC_ENAS) { magicFound = true; useOld = true; AaruConsole.DebugWriteLine("VTOC plugin", "Old VTOC found at {0}", pdloc + sectorOffset + 1); if (magic == VTOC_SANE) { vtocOld = Marshal.ByteArrayToStructureLittleEndian <vtocold>(vtocsector); } else { vtocOld = Marshal.ByteArrayToStructureBigEndian <vtocold>(vtocsector); for (int i = 0; i < vtocOld.v_part.Length; i++) { vtocOld.v_part[i].p_tag = (pTag)Swapping.Swap((ushort)vtocOld.v_part[i].p_tag); vtocOld.v_part[i].p_flag = (pFlag)Swapping.Swap((ushort)vtocOld.v_part[i].p_flag); vtocOld.v_part[i].p_start = Swapping.Swap(vtocOld.v_part[i].p_start); vtocOld.v_part[i].p_size = Swapping.Swap(vtocOld.v_part[i].p_size); vtocOld.timestamp[i] = Swapping.Swap(vtocOld.timestamp[i]); } } } } if (!magicFound) { AaruConsole.DebugWriteLine("VTOC plugin", "Searching for VTOC on relative byte {0}", pd.vtoc_ptr); ulong relSecPtr = pd.vtoc_ptr / imagePlugin.Info.SectorSize; uint relSecOff = pd.vtoc_ptr % imagePlugin.Info.SectorSize; uint secCount = (relSecOff + pd.vtoc_len) / imagePlugin.Info.SectorSize; if ((relSecOff + pd.vtoc_len) % imagePlugin.Info.SectorSize > 0) { secCount++; } AaruConsole.DebugWriteLine("VTOC plugin", "Going to read {0} sectors from sector {1}, getting VTOC from byte {2}", secCount, relSecPtr + sectorOffset, relSecOff); if (relSecPtr + sectorOffset + secCount >= imagePlugin.Info.Sectors) { AaruConsole.DebugWriteLine("VTOC plugin", "Going to read past device size, aborting..."); return(false); } byte[] tmp = imagePlugin.ReadSectors(relSecPtr + sectorOffset, secCount); vtocsector = new byte[pd.vtoc_len]; Array.Copy(tmp, relSecOff, vtocsector, 0, pd.vtoc_len); magic = BitConverter.ToUInt32(vtocsector, 0); if (magic == VTOC_SANE || magic == VTOC_ENAS) { magicFound = true; AaruConsole.DebugWriteLine("VTOC plugin", "New VTOC found."); if (magic == VTOC_SANE) { vtoc = Marshal.ByteArrayToStructureLittleEndian <vtoc>(vtocsector); } else { vtoc = Marshal.ByteArrayToStructureBigEndian <vtoc>(vtocsector); for (int i = 0; i < vtoc.v_part.Length; i++) { vtoc.v_part[i].p_tag = (pTag)Swapping.Swap((ushort)vtoc.v_part[i].p_tag); vtoc.v_part[i].p_flag = (pFlag)Swapping.Swap((ushort)vtoc.v_part[i].p_flag); vtoc.v_part[i].p_start = Swapping.Swap(vtoc.v_part[i].p_start); vtoc.v_part[i].p_size = Swapping.Swap(vtoc.v_part[i].p_size); vtoc.timestamp[i] = Swapping.Swap(vtoc.timestamp[i]); } } } } if (!magicFound) { AaruConsole.DebugWriteLine("VTOC plugin", "Cannot find VTOC."); return(false); } if (useOld) { AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_sanity = 0x{0:X8} (should be 0x{1:X8})", vtocOld.v_sanity, VTOC_SANE); AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_version = {0}", vtocOld.v_version); AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_volume = \"{0}\"", StringHandlers.CToString(vtocOld.v_volume)); AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_sectorsz = {0}", vtocOld.v_sectorsz); AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_nparts = {0}", vtocOld.v_nparts); for (int i = 0; i < V_NUMPAR; i++) { AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_part[{0}].p_tag = {1} ({2})", i, vtocOld.v_part[i].p_tag, (ushort)vtocOld.v_part[i].p_tag); AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_part[{0}].p_flag = {1} ({2})", i, vtocOld.v_part[i].p_flag, (ushort)vtocOld.v_part[i].p_flag); AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_part[{0}].p_start = {1}", i, vtocOld.v_part[i].p_start); AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_part[{0}].p_size = {1}", i, vtocOld.v_part[i].p_size); AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.timestamp[{0}] = {1}", i, DateHandlers.UnixToDateTime(vtocOld.timestamp[i])); } } else { AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_sanity = 0x{0:X8} (should be 0x{1:X8})", vtoc.v_sanity, VTOC_SANE); AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_version = {0}", vtoc.v_version); AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_volume = \"{0}\"", StringHandlers.CToString(vtoc.v_volume)); AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_pad = {0}", vtoc.v_pad); AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_nparts = {0}", vtoc.v_nparts); for (int i = 0; i < V_NUMPAR; i++) { AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_part[{0}].p_tag = {1} ({2})", i, vtoc.v_part[i].p_tag, (ushort)vtoc.v_part[i].p_tag); AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_part[{0}].p_flag = {1} ({2})", i, vtoc.v_part[i].p_flag, (ushort)vtoc.v_part[i].p_flag); AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_part[{0}].p_start = {1}", i, vtoc.v_part[i].p_start); AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_part[{0}].p_size = {1}", i, vtoc.v_part[i].p_size); AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.timestamp[{0}] = {1}", i, DateHandlers.UnixToDateTime(vtoc.timestamp[i])); } } uint bps; partition[] parts; int[] timestamps; if (useOld) { bps = vtocOld.v_sectorsz; parts = vtocOld.v_part; timestamps = vtocOld.timestamp; } else { bps = pd.bytes; parts = vtoc.v_part; timestamps = vtoc.timestamp; } // Check for a partition describing the VTOC whose start is the same as the start we know. // This means partition starts are absolute, not relative, to the VTOC position for (int i = 0; i < V_NUMPAR; i++) { if (parts[i].p_tag == pTag.V_BACKUP && (ulong)parts[i].p_start == sectorOffset) { absolute = true; break; } } for (int i = 0; i < V_NUMPAR; i++) { if (parts[i].p_tag != pTag.V_UNUSED) { var part = new Partition { Start = (ulong)(parts[i].p_start * bps) / imagePlugin.Info.SectorSize, Length = (ulong)(parts[i].p_size * bps) / imagePlugin.Info.SectorSize, Offset = (ulong)(parts[i].p_start * bps), Size = (ulong)(parts[i].p_size * bps), Sequence = (ulong)i, Type = $"UNIX: {decodeUNIXTAG(parts[i].p_tag, !useOld)}", Scheme = Name }; string info = ""; // Apparently old ones are absolute :? if (!useOld && !absolute) { part.Start += sectorOffset; part.Offset += sectorOffset * imagePlugin.Info.SectorSize; } if (parts[i].p_flag.HasFlag(pFlag.V_VALID)) { info += " (valid)"; } if (parts[i].p_flag.HasFlag(pFlag.V_UNMNT)) { info += " (unmountable)"; } if (parts[i].p_flag.HasFlag(pFlag.V_OPEN)) { info += " (open)"; } if (parts[i].p_flag.HasFlag(pFlag.V_REMAP)) { info += " (alternate sector mapping)"; } if (parts[i].p_flag.HasFlag(pFlag.V_RONLY)) { info += " (read-only)"; } if (timestamps[i] != 0) { info += $" created on {DateHandlers.UnixToDateTime(timestamps[i])}"; } part.Description = "UNIX slice" + info + "."; if (part.End < imagePlugin.Info.Sectors) { partitions.Add(part); } } } return(partitions.Count > 0); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } var efsSb = new Superblock(); // Misaligned if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc) { uint sbSize = (uint)((Marshal.SizeOf <Superblock>() + 0x400) / imagePlugin.Info.SectorSize); if ((Marshal.SizeOf <Superblock>() + 0x400) % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return; } byte[] sbpiece = new byte[Marshal.SizeOf <Superblock>()]; Array.Copy(sector, 0x200, sbpiece, 0, Marshal.SizeOf <Superblock>()); efsSb = Marshal.ByteArrayToStructureBigEndian <Superblock>(sbpiece); AaruConsole.DebugWriteLine("EFS plugin", "magic at 0x{0:X3} = 0x{1:X8} (expected 0x{2:X8} or 0x{3:X8})", 0x200, efsSb.sb_magic, EFS_MAGIC, EFS_MAGIC_NEW); } else { uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start + 1, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return; } efsSb = Marshal.ByteArrayToStructureBigEndian <Superblock>(sector); AaruConsole.DebugWriteLine("EFS plugin", "magic at {0} = 0x{1:X8} (expected 0x{2:X8} or 0x{3:X8})", 1, efsSb.sb_magic, EFS_MAGIC, EFS_MAGIC_NEW); } if (efsSb.sb_magic != EFS_MAGIC && efsSb.sb_magic != EFS_MAGIC_NEW) { return; } var sb = new StringBuilder(); sb.AppendLine("SGI extent filesystem"); if (efsSb.sb_magic == EFS_MAGIC_NEW) { sb.AppendLine("New version"); } sb.AppendFormat("Filesystem size: {0} basic blocks", efsSb.sb_size).AppendLine(); sb.AppendFormat("First cylinder group starts at block {0}", efsSb.sb_firstcg).AppendLine(); sb.AppendFormat("Cylinder group size: {0} basic blocks", efsSb.sb_cgfsize).AppendLine(); sb.AppendFormat("{0} inodes per cylinder group", efsSb.sb_cgisize).AppendLine(); sb.AppendFormat("{0} sectors per track", efsSb.sb_sectors).AppendLine(); sb.AppendFormat("{0} heads per cylinder", efsSb.sb_heads).AppendLine(); sb.AppendFormat("{0} cylinder groups", efsSb.sb_ncg).AppendLine(); sb.AppendFormat("Volume created on {0}", DateHandlers.UnixToDateTime(efsSb.sb_time)).AppendLine(); sb.AppendFormat("{0} bytes on bitmap", efsSb.sb_bmsize).AppendLine(); sb.AppendFormat("{0} free blocks", efsSb.sb_tfree).AppendLine(); sb.AppendFormat("{0} free inodes", efsSb.sb_tinode).AppendLine(); if (efsSb.sb_bmblock > 0) { sb.AppendFormat("Bitmap resides at block {0}", efsSb.sb_bmblock).AppendLine(); } if (efsSb.sb_replsb > 0) { sb.AppendFormat("Replacement superblock resides at block {0}", efsSb.sb_replsb).AppendLine(); } if (efsSb.sb_lastinode > 0) { sb.AppendFormat("Last inode allocated: {0}", efsSb.sb_lastinode).AppendLine(); } if (efsSb.sb_dirty > 0) { sb.AppendLine("Volume is dirty"); } sb.AppendFormat("Checksum: 0x{0:X8}", efsSb.sb_checksum).AppendLine(); sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(efsSb.sb_fname, Encoding)).AppendLine(); sb.AppendFormat("Volume pack: {0}", StringHandlers.CToString(efsSb.sb_fpack, Encoding)).AppendLine(); information = sb.ToString(); XmlFsType = new FileSystemType { Type = "Extent File System", ClusterSize = 512, Clusters = (ulong)efsSb.sb_size, FreeClusters = (ulong)efsSb.sb_tfree, FreeClustersSpecified = true, Dirty = efsSb.sb_dirty > 0, VolumeName = StringHandlers.CToString(efsSb.sb_fname, Encoding), VolumeSerial = $"{efsSb.sb_checksum:X8}", CreationDate = DateHandlers.UnixToDateTime(efsSb.sb_time), CreationDateSpecified = true }; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 256) { return; } var rbfSb = new IdSector(); var rbf9000Sb = new NewIdSector(); foreach (int i in new[] { 0, 4, 15 }) { ulong location = (ulong)i; uint sbSize = (uint)(Marshal.SizeOf <IdSector>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <IdSector>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); if (sector.Length < Marshal.SizeOf <IdSector>()) { return; } rbfSb = Marshal.ByteArrayToStructureBigEndian <IdSector>(sector); rbf9000Sb = Marshal.ByteArrayToStructureBigEndian <NewIdSector>(sector); AaruConsole.DebugWriteLine("RBF plugin", "magic at {0} = 0x{1:X8} or 0x{2:X8} (expected 0x{3:X8} or 0x{4:X8})", location, rbfSb.dd_sync, rbf9000Sb.rid_sync, RBF_SYNC, RBF_CNYS); if (rbfSb.dd_sync == RBF_SYNC || rbf9000Sb.rid_sync == RBF_SYNC || rbf9000Sb.rid_sync == RBF_CNYS) { break; } } if (rbfSb.dd_sync != RBF_SYNC && rbf9000Sb.rid_sync != RBF_SYNC && rbf9000Sb.rid_sync != RBF_CNYS) { return; } if (rbf9000Sb.rid_sync == RBF_CNYS) { rbf9000Sb = (NewIdSector)Marshal.SwapStructureMembersEndian(rbf9000Sb); } var sb = new StringBuilder(); sb.AppendLine("OS-9 Random Block File"); if (rbf9000Sb.rid_sync == RBF_SYNC) { sb.AppendFormat("Volume ID: {0:X8}", rbf9000Sb.rid_diskid).AppendLine(); sb.AppendFormat("{0} blocks in volume", rbf9000Sb.rid_totblocks).AppendLine(); sb.AppendFormat("{0} cylinders", rbf9000Sb.rid_cylinders).AppendLine(); sb.AppendFormat("{0} blocks in cylinder 0", rbf9000Sb.rid_cyl0size).AppendLine(); sb.AppendFormat("{0} blocks per cylinder", rbf9000Sb.rid_cylsize).AppendLine(); sb.AppendFormat("{0} heads", rbf9000Sb.rid_heads).AppendLine(); sb.AppendFormat("{0} bytes per block", rbf9000Sb.rid_blocksize).AppendLine(); // TODO: Convert to flags? sb.AppendLine((rbf9000Sb.rid_format & 0x01) == 0x01 ? "Disk is double sided" : "Disk is single sided"); sb.AppendLine((rbf9000Sb.rid_format & 0x02) == 0x02 ? "Disk is double density" : "Disk is single density"); if ((rbf9000Sb.rid_format & 0x10) == 0x10) { sb.AppendLine("Disk is 384 TPI"); } else if ((rbf9000Sb.rid_format & 0x08) == 0x08) { sb.AppendLine("Disk is 192 TPI"); } else if ((rbf9000Sb.rid_format & 0x04) == 0x04) { sb.AppendLine("Disk is 96 TPI or 135 TPI"); } else { sb.AppendLine("Disk is 48 TPI"); } sb.AppendFormat("Allocation bitmap descriptor starts at block {0}", rbf9000Sb.rid_bitmap == 0 ? 1 : rbf9000Sb.rid_bitmap).AppendLine(); if (rbf9000Sb.rid_firstboot > 0) { sb.AppendFormat("Debugger descriptor starts at block {0}", rbf9000Sb.rid_firstboot).AppendLine(); } if (rbf9000Sb.rid_bootfile > 0) { sb.AppendFormat("Boot file descriptor starts at block {0}", rbf9000Sb.rid_bootfile).AppendLine(); } sb.AppendFormat("Root directory descriptor starts at block {0}", rbf9000Sb.rid_rootdir).AppendLine(); sb.AppendFormat("Disk is owned by group {0} user {1}", rbf9000Sb.rid_group, rbf9000Sb.rid_owner). AppendLine(); sb.AppendFormat("Volume was created on {0}", DateHandlers.UnixToDateTime(rbf9000Sb.rid_ctime)). AppendLine(); sb.AppendFormat("Volume's identification block was last written on {0}", DateHandlers.UnixToDateTime(rbf9000Sb.rid_mtime)).AppendLine(); sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(rbf9000Sb.rid_name, Encoding)). AppendLine(); XmlFsType = new FileSystemType { Type = "OS-9 Random Block File", Bootable = rbf9000Sb.rid_bootfile > 0, ClusterSize = rbf9000Sb.rid_blocksize, Clusters = rbf9000Sb.rid_totblocks, CreationDate = DateHandlers.UnixToDateTime(rbf9000Sb.rid_ctime), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixToDateTime(rbf9000Sb.rid_mtime), ModificationDateSpecified = true, VolumeName = StringHandlers.CToString(rbf9000Sb.rid_name, Encoding), VolumeSerial = $"{rbf9000Sb.rid_diskid:X8}" }; } else { sb.AppendFormat("Volume ID: {0:X4}", rbfSb.dd_dsk).AppendLine(); sb.AppendFormat("{0} blocks in volume", LSNToUInt32(rbfSb.dd_tot)).AppendLine(); sb.AppendFormat("{0} tracks", rbfSb.dd_tks).AppendLine(); sb.AppendFormat("{0} sectors per track", rbfSb.dd_spt).AppendLine(); sb.AppendFormat("{0} bytes per sector", 256 << rbfSb.dd_lsnsize).AppendLine(); sb.AppendFormat("{0} sectors per cluster ({1} bytes)", rbfSb.dd_bit, rbfSb.dd_bit * (256 << rbfSb.dd_lsnsize)).AppendLine(); // TODO: Convert to flags? sb.AppendLine((rbfSb.dd_fmt & 0x01) == 0x01 ? "Disk is double sided" : "Disk is single sided"); sb.AppendLine((rbfSb.dd_fmt & 0x02) == 0x02 ? "Disk is double density" : "Disk is single density"); if ((rbfSb.dd_fmt & 0x10) == 0x10) { sb.AppendLine("Disk is 384 TPI"); } else if ((rbfSb.dd_fmt & 0x08) == 0x08) { sb.AppendLine("Disk is 192 TPI"); } else if ((rbfSb.dd_fmt & 0x04) == 0x04) { sb.AppendLine("Disk is 96 TPI or 135 TPI"); } else { sb.AppendLine("Disk is 48 TPI"); } sb.AppendFormat("Allocation bitmap descriptor starts at block {0}", rbfSb.dd_maplsn == 0 ? 1 : rbfSb.dd_maplsn).AppendLine(); sb.AppendFormat("{0} bytes in allocation bitmap", rbfSb.dd_map).AppendLine(); if (LSNToUInt32(rbfSb.dd_bt) > 0 && rbfSb.dd_bsz > 0) { sb.AppendFormat("Boot file starts at block {0} and has {1} bytes", LSNToUInt32(rbfSb.dd_bt), rbfSb.dd_bsz).AppendLine(); } sb.AppendFormat("Root directory descriptor starts at block {0}", LSNToUInt32(rbfSb.dd_dir)). AppendLine(); sb.AppendFormat("Disk is owned by user {0}", rbfSb.dd_own).AppendLine(); sb.AppendFormat("Volume was created on {0}", DateHandlers.Os9ToDateTime(rbfSb.dd_dat)).AppendLine(); sb.AppendFormat("Volume attributes: {0:X2}", rbfSb.dd_att).AppendLine(); sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(rbfSb.dd_nam, Encoding)).AppendLine(); sb.AppendFormat("Path descriptor options: {0}", StringHandlers.CToString(rbfSb.dd_opt, Encoding)). AppendLine(); XmlFsType = new FileSystemType { Type = "OS-9 Random Block File", Bootable = LSNToUInt32(rbfSb.dd_bt) > 0 && rbfSb.dd_bsz > 0, ClusterSize = (uint)(rbfSb.dd_bit * (256 << rbfSb.dd_lsnsize)), Clusters = LSNToUInt32(rbfSb.dd_tot), CreationDate = DateHandlers.Os9ToDateTime(rbfSb.dd_dat), CreationDateSpecified = true, VolumeName = StringHandlers.CToString(rbfSb.dd_nam, Encoding), VolumeSerial = $"{rbfSb.dd_dsk:X4}" }; } information = sb.ToString(); }