// /*************************************************************************** // The Disc Image Chef // ---------------------------------------------------------------------------- // // Filename : VxFS.cs // Author(s) : Natalia Portillo // // Component : Veritas File System plugin. // // --[ Description ] ---------------------------------------------------------- // // Identifies the Veritas 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-2018 Natalia Portillo // ****************************************************************************/ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.DiscImages; using Schemas; namespace DiscImageChef.Filesystems { public class VxFS : Filesystem { /// /// Identifier for VxFS /// const uint VXFS_MAGIC = 0xA501FCF5; const uint VXFS_BASE = 0x400; public VxFS() { Name = "Veritas filesystem"; PluginUuid = new Guid("EC372605-7687-453C-8BEA-7E0DFF79CB03"); CurrentEncoding = Encoding.UTF8; } public VxFS(Encoding encoding) { Name = "Veritas filesystem"; PluginUuid = new Guid("EC372605-7687-453C-8BEA-7E0DFF79CB03"); CurrentEncoding = encoding ?? Encoding.UTF8; } public VxFS(ImagePlugin imagePlugin, Partition partition, Encoding encoding) { Name = "Veritas filesystem"; PluginUuid = new Guid("EC372605-7687-453C-8BEA-7E0DFF79CB03"); CurrentEncoding = encoding ?? Encoding.UTF8; } public override bool Identify(ImagePlugin imagePlugin, Partition partition) { ulong vmfsSuperOff = VXFS_BASE / imagePlugin.ImageInfo.SectorSize; if(partition.Start + vmfsSuperOff >= partition.End) return false; byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); uint magic = BitConverter.ToUInt32(sector, 0x00); return magic == VXFS_MAGIC; } public override void GetInformation(ImagePlugin imagePlugin, Partition partition, out string information) { ulong vmfsSuperOff = VXFS_BASE / imagePlugin.ImageInfo.SectorSize; byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); VxSuperBlock vxSb = new VxSuperBlock(); IntPtr vxSbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vxSb)); Marshal.Copy(sector, 0, vxSbPtr, Marshal.SizeOf(vxSb)); vxSb = (VxSuperBlock)Marshal.PtrToStructure(vxSbPtr, typeof(VxSuperBlock)); Marshal.FreeHGlobal(vxSbPtr); StringBuilder sbInformation = new StringBuilder(); sbInformation.AppendLine("Veritas file system"); sbInformation.AppendFormat("Volume version {0}", vxSb.vs_version).AppendLine(); sbInformation.AppendFormat("Volume name {0}", StringHandlers.CToString(vxSb.vs_fname, CurrentEncoding)) .AppendLine(); sbInformation.AppendFormat("Volume has {0} blocks of {1} bytes each", vxSb.vs_bsize, vxSb.vs_size) .AppendLine(); sbInformation.AppendFormat("Volume has {0} inodes per block", vxSb.vs_inopb).AppendLine(); sbInformation.AppendFormat("Volume has {0} free inodes", vxSb.vs_ifree).AppendLine(); sbInformation.AppendFormat("Volume has {0} free blocks", vxSb.vs_free).AppendLine(); sbInformation.AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(vxSb.vs_ctime, vxSb.vs_cutime)).AppendLine(); sbInformation.AppendFormat("Volume last modified on {0}", DateHandlers.UnixUnsignedToDateTime(vxSb.vs_wtime, vxSb.vs_wutime)).AppendLine(); if(vxSb.vs_clean != 0) sbInformation.AppendLine("Volume is dirty"); information = sbInformation.ToString(); XmlFsType = new FileSystemType { Type = "Veritas file system", CreationDate = DateHandlers.UnixUnsignedToDateTime(vxSb.vs_ctime, vxSb.vs_cutime), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(vxSb.vs_wtime, vxSb.vs_wutime), ModificationDateSpecified = true, Clusters = vxSb.vs_size, ClusterSize = vxSb.vs_bsize, Dirty = vxSb.vs_clean != 0, FreeClusters = vxSb.vs_free, 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; } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct VxSuperBlock { /// Magic number public uint vs_magic; /// VxFS version public int vs_version; /// create time - secs public uint vs_ctime; /// create time - usecs public uint vs_cutime; /// unused public int __unused1; /// unused public int __unused2; /// obsolete public int vs_old_logstart; /// obsolete public int vs_old_logend; /// block size public int vs_bsize; /// number of blocks public int vs_size; /// number of data blocks public int vs_dsize; /// obsolete public uint vs_old_ninode; /// obsolete public int vs_old_nau; /// unused public int __unused3; /// obsolete public int vs_old_defiextsize; /// obsolete public int vs_old_ilbsize; /// size of immediate data area public int vs_immedlen; /// number of direct extentes public int vs_ndaddr; /// address of first AU public int vs_firstau; /// offset of extent map in AU public int vs_emap; /// offset of inode map in AU public int vs_imap; /// offset of ExtOp. map in AU public int vs_iextop; /// offset of inode list in AU public int vs_istart; /// offset of fdblock in AU public int vs_bstart; /// aufirst + emap public int vs_femap; /// aufirst + imap public int vs_fimap; /// aufirst + iextop public int vs_fiextop; /// aufirst + istart public int vs_fistart; /// aufirst + bstart public int vs_fbstart; /// number of entries in indir public int vs_nindir; /// length of AU in blocks public int vs_aulen; /// length of imap in blocks public int vs_auimlen; /// length of emap in blocks public int vs_auemlen; /// length of ilist in blocks public int vs_auilen; /// length of pad in blocks public int vs_aupad; /// data blocks in AU public int vs_aublocks; /// log base 2 of aublocks public int vs_maxtier; /// number of inodes per blk public int vs_inopb; /// obsolete public int vs_old_inopau; /// obsolete public int vs_old_inopilb; /// obsolete public int vs_old_ndiripau; /// size of indirect addr ext. public int vs_iaddrlen; /// log base 2 of bsize public int vs_bshift; /// log base 2 of inobp public int vs_inoshift; /// ~( bsize - 1 ) public int vs_bmask; /// bsize - 1 public int vs_boffmask; /// old_inopilb - 1 public int vs_old_inomask; /// checksum of V1 data public int vs_checksum; /// number of free blocks public int vs_free; /// number of free inodes public int vs_ifree; /// number of free extents by size [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public int[] vs_efree; /// flags ?!? public int vs_flags; /// filesystem has been changed public byte vs_mod; /// clean FS public byte vs_clean; /// unused public ushort __unused4; /// mount time log ID public uint vs_firstlogid; /// last time written - sec public uint vs_wtime; /// last time written - usec public uint vs_wutime; /// FS name [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] vs_fname; /// FS pack name [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] vs_fpack; /// log format version public int vs_logversion; /// unused public int __unused5; /// OLT extent and replica [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public int[] vs_oltext; /// OLT extent size public int vs_oltsize; /// size of inode map public int vs_iauimlen; /// size of IAU in blocks public int vs_iausize; /// size of inode in bytes public int vs_dinosize; /// indir levels per inode public int vs_old_dniaddr; /// checksum of V2 RO public int vs_checksum2; } } }