From 8120a5a86983f07bbf6100629c4e5fb09ba63dae Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Wed, 14 Sep 2016 14:25:08 +0100 Subject: [PATCH] Adds support for Squash file system, closes #17. --- .../DiscImageChef.Filesystems.csproj | 1 + DiscImageChef.Filesystems/Squash.cs | 219 ++++++++++++++++++ README.md | 1 + TODO | 1 - 4 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 DiscImageChef.Filesystems/Squash.cs diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj index c8f7db7d..a3f7e27d 100644 --- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj +++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj @@ -109,6 +109,7 @@ + diff --git a/DiscImageChef.Filesystems/Squash.cs b/DiscImageChef.Filesystems/Squash.cs new file mode 100644 index 00000000..acbd0664 --- /dev/null +++ b/DiscImageChef.Filesystems/Squash.cs @@ -0,0 +1,219 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Squash.cs +// Author(s) : Natalia Portillo +// +// Component : Squash file system plugin. +// +// --[ Description ] ---------------------------------------------------------- +// +// Identifies the Squash file system and shows information. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace DiscImageChef.Filesystems +{ + class Squash : Filesystem + { + public Squash() + { + Name = "Squash filesystem"; + PluginUUID = new Guid("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09"); + } + + public Squash(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd) + { + Name = "Squash filesystem"; + PluginUUID = new Guid("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09"); + } + + enum SquashCompression : ushort + { + Zlib = 1, + Lzma = 2, + Lzo = 3, + Xz = 4, + Lz4 = 5 + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct SquashSuperBlock + { + public uint magic; + public uint inodes; + public uint mkfs_time; + public uint block_size; + public uint fragments; + public ushort compression; + public ushort block_log; + public ushort flags; + public ushort no_ids; + public ushort s_major; + public ushort s_minor; + public ulong root_inode; + public ulong bytes_used; + public ulong id_table_start; + public ulong xattr_id_table_start; + public ulong inode_table_start; + public ulong directory_table_start; + public ulong fragment_table_start; + public ulong lookup_table_start; + } + + /// + /// Identifier for Squash + /// + const uint Squash_MAGIC = 0x73717368; + + public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd) + { + if(partitionStart >= partitionEnd) + return false; + + byte[] sector = imagePlugin.ReadSector(partitionStart); + + uint magic = BitConverter.ToUInt32(sector, 0x00); + + return magic == Squash_MAGIC; + } + + public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information) + { + byte[] sector = imagePlugin.ReadSector(partitionStart); + + SquashSuperBlock sqSb = new SquashSuperBlock(); + IntPtr sqSbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(sqSb)); + Marshal.Copy(sector, 0, sqSbPtr, Marshal.SizeOf(sqSb)); + sqSb = (SquashSuperBlock)Marshal.PtrToStructure(sqSbPtr, typeof(SquashSuperBlock)); + Marshal.FreeHGlobal(sqSbPtr); + + StringBuilder sbInformation = new StringBuilder(); + + sbInformation.AppendLine("Squash file system"); + + sbInformation.AppendFormat("Volume version {0}.{1}", sqSb.s_major, sqSb.s_minor).AppendLine(); + sbInformation.AppendFormat("Volume has {0} bytes", sqSb.bytes_used).AppendLine(); + sbInformation.AppendFormat("Volume has {0} bytes per block", sqSb.block_size).AppendLine(); + sbInformation.AppendFormat("Volume created on {0}", DateHandlers.UNIXUnsignedToDateTime(sqSb.mkfs_time)).AppendLine(); + sbInformation.AppendFormat("Volume has {0} inodes", sqSb.inodes).AppendLine(); + switch(sqSb.compression) + { + case (ushort)SquashCompression.Lz4: + sbInformation.AppendLine("Volume is compressed using LZ4"); + break; + case (ushort)SquashCompression.Lzo: + sbInformation.AppendLine("Volume is compressed using LZO"); + break; + case (ushort)SquashCompression.Lzma: + sbInformation.AppendLine("Volume is compressed using LZMA"); + break; + case (ushort)SquashCompression.Xz: + sbInformation.AppendLine("Volume is compressed using XZ"); + break; + case (ushort)SquashCompression.Zlib: + sbInformation.AppendLine("Volume is compressed using GZIP"); + break; + default: + sbInformation.AppendFormat("Volume is compressed using unknown algorithm {0}", sqSb.compression).AppendLine(); + break; + } + + information = sbInformation.ToString(); + + xmlFSType = new Schemas.FileSystemType(); + xmlFSType.Type = "Squash file system"; + xmlFSType.CreationDate = DateHandlers.UNIXUnsignedToDateTime(sqSb.mkfs_time); + xmlFSType.CreationDateSpecified = true; + xmlFSType.Clusters = (long)(((partitionEnd - partitionStart + 1) * imagePlugin.ImageInfo.sectorSize) / sqSb.block_size); + xmlFSType.ClusterSize = (int)sqSb.block_size; + xmlFSType.Files = sqSb.inodes; + xmlFSType.FilesSpecified = true; + xmlFSType.FreeClusters = 0; + xmlFSType.FreeClustersSpecified = true; + } + + 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 fb80ea25..26f591c2 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ Supported file systems for identification and information only * SmartFileSystem * VMware file system (VMFS) * Veritas file system +* Squash file system Supported checksums =================== diff --git a/TODO b/TODO index 3ebc5d30..cae6924d 100644 --- a/TODO +++ b/TODO @@ -15,7 +15,6 @@ Filesystem plugins: --- Add support for UDF --- Add support for CramFS --- Add support for NwFS ---- Add support for Squashfs --- Add support for X-Box filesystems --- Add support for ReFS --- Add support for ECMA-67