From 31ae326f0c9f0849a0db22c1d60eda750777db50 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 7 Aug 2017 16:15:57 +0100 Subject: [PATCH] Added support for the fossil file system. --- .../DiscImageChef.Filesystems.csproj | 3 +- DiscImageChef.Filesystems/Fossil.cs | 241 +++++++++++++++++- README.md | 1 + 3 files changed, 241 insertions(+), 4 deletions(-) diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj index c9f4b556d..c3ca696b7 100644 --- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj +++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj @@ -127,6 +127,7 @@ + @@ -187,7 +188,7 @@ - + diff --git a/DiscImageChef.Filesystems/Fossil.cs b/DiscImageChef.Filesystems/Fossil.cs index dde9b8d84..7b718ac67 100644 --- a/DiscImageChef.Filesystems/Fossil.cs +++ b/DiscImageChef.Filesystems/Fossil.cs @@ -9,7 +9,7 @@ // // --[ Description ] ---------------------------------------------------------- // -// Description +// Identifies the Fossil filesystem and shows information. // // --[ License ] -------------------------------------------------------------- // @@ -29,13 +29,248 @@ // ---------------------------------------------------------------------------- // Copyright © 2011-2017 Natalia Portillo // ****************************************************************************/ + using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using DiscImageChef.CommonTypes; +using DiscImageChef.Console; + namespace DiscImageChef.Filesystems { - public class Fossil + public class Fossil : Filesystem { + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct FossilHeader + { + /// + /// Magic number + /// + public uint magic; + /// + /// Header version + /// + public ushort version; + /// + /// Block size + /// + public ushort blockSize; + /// + /// Block containing superblock + /// + public uint super; + /// + /// Block containing labels + /// + public uint label; + /// + /// Where do data blocks start + /// + public uint data; + /// + /// How many data blocks does it have + /// + public uint end; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct FossilSuperBlock + { + /// + /// Magic number + /// + public uint magic; + /// + /// Header version + /// + public ushort version; + /// + /// file system low epoch + /// + public uint epochLow; + /// + /// file system high(active) epoch + /// + public uint epochHigh; + /// + /// next qid to allocate + /// + public ulong qid; + /// + /// data block number: root of active file system + /// + public int active; + /// + /// data block number: root of next file system to archive + /// + public int next; + /// + /// data block number: root of file system currently being archived + /// + public int current; + /// + /// Venti score of last successful archive + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] last; + /// + /// name of file system(just a comment) + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] + public byte[] name; + } + + const uint Fossil_HdrMagic = 0x3776AE89; + const uint Fossil_SbMagic = 0x2340A3B1; + // Fossil header starts at 128KiB + const ulong HeaderPos = 128 * 1024; + public Fossil() { + Name = "Fossil Filesystem Plugin"; + PluginUUID = new Guid("932BF104-43F6-494F-973C-45EF58A51DA9"); + CurrentEncoding = Encoding.UTF8; + } + + public Fossil(ImagePlugins.ImagePlugin imagePlugin, Partition partition, Encoding encoding) + { + Name = "Fossil Filesystem Plugin"; + PluginUUID = new Guid("932BF104-43F6-494F-973C-45EF58A51DA9"); + // Technically everything on Plan 9 from Bell Labs is in UTF-8 + CurrentEncoding = Encoding.UTF8; + } + + public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, Partition partition) + { + ulong hdrSector = HeaderPos / imagePlugin.GetSectorSize(); + + FossilHeader hdr = new FossilHeader(); + + byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector); + hdr = BigEndianMarshal.ByteArrayToStructureBigEndian(sector); + + DicConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic, Fossil_HdrMagic); + + return hdr.magic == Fossil_HdrMagic; + } + + public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, Partition partition, out string information) + { + information = ""; + if(imagePlugin.GetSectorSize() < 512) + return; + + ulong hdrSector = HeaderPos / imagePlugin.GetSectorSize(); + + FossilHeader hdr = new FossilHeader(); + + byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector); + hdr = BigEndianMarshal.ByteArrayToStructureBigEndian(sector); + + DicConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic, Fossil_HdrMagic); + + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("Fossil"); + sb.AppendFormat("Filesystem version {0}", hdr.version).AppendLine(); + sb.AppendFormat("{0} bytes per block", hdr.blockSize).AppendLine(); + sb.AppendFormat("Superblock resides in block {0}", hdr.super).AppendLine(); + sb.AppendFormat("Labels resides in block {0}", hdr.label).AppendLine(); + sb.AppendFormat("Data starts at block {0}", hdr.data).AppendLine(); + sb.AppendFormat("Volume has {0} blocks", hdr.end).AppendLine(); + + ulong sbLocation = (hdr.super * (hdr.blockSize / imagePlugin.GetSectorSize())) + partition.Start; + + xmlFSType = new Schemas.FileSystemType + { + Type = "Fossil filesystem", + ClusterSize = hdr.blockSize, + Clusters = hdr.end + }; + + if(sbLocation <= partition.End) + { + sector = imagePlugin.ReadSector(sbLocation); + System.Console.WriteLine("Searching for superblock on sector {0}", sbLocation); + FossilSuperBlock fsb = BigEndianMarshal.ByteArrayToStructureBigEndian(sector); + + DicConsole.DebugWriteLine("Fossil plugin", "magic 0x{0:X8} (expected 0x{1:X8})", fsb.magic, Fossil_SbMagic); + + if(fsb.magic == Fossil_SbMagic) + { + sb.AppendFormat("Epoch low {0}", fsb.epochLow).AppendLine(); + sb.AppendFormat("Epoch high {0}", fsb.epochHigh).AppendLine(); + sb.AppendFormat("Next QID {0}", fsb.qid).AppendLine(); + sb.AppendFormat("Active root block {0}", fsb.active).AppendLine(); + sb.AppendFormat("Next root block {0}", fsb.next).AppendLine(); + sb.AppendFormat("Curren root block {0}", fsb.current).AppendLine(); + sb.AppendFormat("Volume label: \"{0}\"", StringHandlers.CToString(fsb.name, CurrentEncoding)).AppendLine(); + xmlFSType.VolumeName = StringHandlers.CToString(fsb.name, CurrentEncoding); + } + } + + information = sb.ToString(); + } + + public override Errno Mount() + { + return Errno.NotImplemented; + } + + public override Errno Mount(bool debug) + { + return Errno.NotImplemented; + } + + public override Errno Unmount() + { + return Errno.NotImplemented; + } + + public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock) + { + return Errno.NotImplemented; + } + + public override Errno GetAttributes(string path, ref FileAttributes attributes) + { + return Errno.NotImplemented; + } + + public override Errno ListXAttr(string path, ref List xattrs) + { + return Errno.NotImplemented; + } + + public override Errno GetXattr(string path, string xattr, ref byte[] buf) + { + return Errno.NotImplemented; + } + + public override Errno Read(string path, long offset, long size, ref byte[] buf) + { + return Errno.NotImplemented; + } + + public override Errno ReadDir(string path, ref List contents) + { + return Errno.NotImplemented; + } + + public override Errno StatFs(ref FileSystemInfo stat) + { + return Errno.NotImplemented; + } + + public override Errno Stat(string path, ref FileEntryInfo stat) + { + return Errno.NotImplemented; + } + + public override Errno ReadLink(string path, ref string dest) + { + return Errno.NotImplemented; } } -} +} \ No newline at end of file diff --git a/README.md b/README.md index b965938bf..bc3a29034 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ Supported file systems for identification and information only * DEC Files-11 (only checked with On Disk Structure 2, ODS-2) * ECMA-67: 130mm Flexible Disk Cartridge Labelling and File Structure for Information Interchange * Flash-Friendly File System (F2FS) +* Fossil file system (from Plan9) * HAMMER file system * IBM Journaling File System (JFS) * ISO9660