Ejemplo n.º 1
0
        public void Open(string path)
        {
            string parentFolder = Path.GetDirectoryName(path);
            string baseFilename = Path.GetFileName(path);

            FileStream finderDatStream =
                new FileStream(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO),
                               FileMode.Open, FileAccess.Read);

            while (finderDatStream.Position + 0x5C <= finderDatStream.Length)
            {
                PCExchangeEntry datEntry   = new PCExchangeEntry();
                byte[]          datEntry_b = new byte[Marshal.SizeOf(datEntry)];
                finderDatStream.Read(datEntry_b, 0, Marshal.SizeOf(datEntry));
                datEntry = BigEndianMarshal.ByteArrayToStructureBigEndian <PCExchangeEntry>(datEntry_b);
                string macName      = StringHandlers.PascalToString(datEntry.macName, Encoding.GetEncoding("macintosh"));
                byte[] tmpDosName_b = new byte[8];
                byte[] tmpDosExt_b  = new byte[3];
                Array.Copy(datEntry.dosName, 0, tmpDosName_b, 0, 8);
                Array.Copy(datEntry.dosName, 8, tmpDosExt_b, 0, 3);
                string dosName = Encoding.ASCII.GetString(tmpDosName_b).Trim() + "." +
                                 Encoding.ASCII.GetString(tmpDosExt_b).Trim();
                string dosNameLow = dosName.ToLower(CultureInfo.CurrentCulture);

                if (baseFilename != macName && baseFilename != dosName && baseFilename != dosNameLow)
                {
                    continue;
                }

                if (File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException())))
                {
                    dataPath = Path.Combine(parentFolder, macName);
                }
Ejemplo n.º 2
0
        public void Open(string path)
        {
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);

            fs.Seek(0, SeekOrigin.Begin);

            byte[] hdr_b = new byte[128];
            fs.Read(hdr_b, 0, 128);
            header = BigEndianMarshal.ByteArrayToStructureBigEndian <MacBinaryHeader>(hdr_b);

            uint blocks = 1;

            blocks += (uint)(header.secondaryHeaderLength / 128);
            if (header.secondaryHeaderLength % 128 > 0)
            {
                blocks++;
            }
            dataForkOff = blocks * 128;
            blocks     += header.dataLength / 128;
            if (header.dataLength % 128 > 0)
            {
                blocks++;
            }
            rsrcForkOff = blocks * 128;

            filename      = StringHandlers.PascalToString(header.filename, Encoding.GetEncoding("macintosh"));
            creationTime  = DateHandlers.MacToDateTime(header.creationTime);
            lastWriteTime = DateHandlers.MacToDateTime(header.modificationTime);

            fs.Close();
            opened   = true;
            isPath   = true;
            basePath = path;
        }
Ejemplo n.º 3
0
        public bool Identify(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            if (stream.Length < 512)
            {
                return(false);
            }

            stream.Seek(-Marshal.SizeOf(footer), SeekOrigin.End);
            byte[] footerB = new byte[Marshal.SizeOf(footer)];

            stream.Read(footerB, 0, Marshal.SizeOf(footer));
            footer = BigEndianMarshal.ByteArrayToStructureBigEndian <UdifFooter>(footerB);

            if (footer.signature == UDIF_SIGNATURE)
            {
                return(true);
            }

            // Old UDIF as created by DiskCopy 6.5 using "OBSOLETE" format. (DiskCopy 5 rumored format?)
            stream.Seek(0, SeekOrigin.Begin);
            byte[] headerB = new byte[Marshal.SizeOf(footer)];

            stream.Read(headerB, 0, Marshal.SizeOf(footer));
            footer = BigEndianMarshal.ByteArrayToStructureBigEndian <UdifFooter>(headerB);

            return(footer.signature == UDIF_SIGNATURE);
        }
Ejemplo n.º 4
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 512)
            {
                return(false);
            }

            UNICOS_Superblock unicosSb = new UNICOS_Superblock();

            uint sbSize = (uint)(Marshal.SizeOf(unicosSb) / imagePlugin.Info.SectorSize);

            if (Marshal.SizeOf(unicosSb) % imagePlugin.Info.SectorSize != 0)
            {
                sbSize++;
            }

            byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);
            if (sector.Length < Marshal.SizeOf(unicosSb))
            {
                return(false);
            }

            unicosSb = BigEndianMarshal.ByteArrayToStructureBigEndian <UNICOS_Superblock>(sector);

            DicConsole.DebugWriteLine("UNICOS plugin", "magic = 0x{0:X16} (expected 0x{1:X16})", unicosSb.s_magic,
                                      UNICOS_Magic);

            return(unicosSb.s_magic == UNICOS_Magic);
        }
Ejemplo n.º 5
0
        public void Open(Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);

            byte[] hdr_b = new byte[128];
            stream.Read(hdr_b, 0, 128);
            header = BigEndianMarshal.ByteArrayToStructureBigEndian <MacBinaryHeader>(hdr_b);

            uint blocks = 1;

            blocks += (uint)(header.secondaryHeaderLength / 128);
            if (header.secondaryHeaderLength % 128 > 0)
            {
                blocks++;
            }
            dataForkOff = blocks * 128;
            blocks     += header.dataLength / 128;
            if (header.dataLength % 128 > 0)
            {
                blocks++;
            }
            rsrcForkOff = blocks * 128;

            filename      = StringHandlers.PascalToString(header.filename, Encoding.GetEncoding("macintosh"));
            creationTime  = DateHandlers.MacToDateTime(header.creationTime);
            lastWriteTime = DateHandlers.MacToDateTime(header.modificationTime);

            stream.Seek(0, SeekOrigin.Begin);
            opened      = true;
            isStream    = true;
            this.stream = stream;
        }
Ejemplo n.º 6
0
        public bool Identify(string path)
        {
            string parentFolder = Path.GetDirectoryName(path);

            if (!File.Exists(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO)))
            {
                return(false);
            }

            if (!Directory.Exists(Path.Combine(parentFolder, RESOURCES)))
            {
                return(false);
            }

            string baseFilename = Path.GetFileName(path);

            bool dataFound = false;
            bool rsrcFound = false;

            FileStream finderDatStream =
                new FileStream(Path.Combine(parentFolder, FINDER_INFO), FileMode.Open, FileAccess.Read);

            while (finderDatStream.Position + 0x5C <= finderDatStream.Length)
            {
                PCExchangeEntry datEntry   = new PCExchangeEntry();
                byte[]          datEntry_b = new byte[Marshal.SizeOf(datEntry)];
                finderDatStream.Read(datEntry_b, 0, Marshal.SizeOf(datEntry));
                datEntry = BigEndianMarshal.ByteArrayToStructureBigEndian <PCExchangeEntry>(datEntry_b);
                // TODO: Add support for encoding on filters
                string macName =
                    StringHandlers.PascalToString(datEntry.macName, Encoding.GetEncoding("macintosh"));
                byte[] tmpDosName_b = new byte[8];
                byte[] tmpDosExt_b  = new byte[3];
                Array.Copy(datEntry.dosName, 0, tmpDosName_b, 0, 8);
                Array.Copy(datEntry.dosName, 8, tmpDosExt_b, 0, 3);
                string dosName = Encoding.ASCII.GetString(tmpDosName_b).Trim() + "." +
                                 Encoding.ASCII.GetString(tmpDosExt_b).Trim();
                string dosNameLow = dosName.ToLower(CultureInfo.CurrentCulture);

                if (baseFilename != macName && baseFilename != dosName && baseFilename != dosNameLow)
                {
                    continue;
                }

                dataFound |=
                    File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException())) ||
                    File.Exists(Path.Combine(parentFolder, dosName)) ||
                    File.Exists(Path.Combine(parentFolder, dosNameLow));

                rsrcFound |= File.Exists(Path.Combine(parentFolder, RESOURCES, dosName)) ||
                             File.Exists(Path.Combine(parentFolder, RESOURCES, dosNameLow));

                break;
            }

            finderDatStream.Close();

            return(dataFound && rsrcFound);
        }
Ejemplo n.º 7
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            // Technically everything on Plan 9 from Bell Labs is in UTF-8
            Encoding    = Encoding.UTF8;
            information = "";
            if (imagePlugin.Info.SectorSize < 512)
            {
                return;
            }

            ulong hdrSector = HEADER_POS / imagePlugin.Info.SectorSize;

            byte[]       sector = imagePlugin.ReadSector(partition.Start + hdrSector);
            FossilHeader hdr    = BigEndianMarshal.ByteArrayToStructureBigEndian <FossilHeader>(sector);

            DicConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic,
                                      FOSSIL_HDR_MAGIC);

            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.Info.SectorSize) + partition.Start;

            XmlFsType = new FileSystemType
            {
                Type = "Fossil filesystem", ClusterSize = hdr.blockSize, Clusters = hdr.end
            };

            if (sbLocation <= partition.End)
            {
                sector = imagePlugin.ReadSector(sbLocation);
                FossilSuperBlock fsb = BigEndianMarshal.ByteArrayToStructureBigEndian <FossilSuperBlock>(sector);

                DicConsole.DebugWriteLine("Fossil plugin", "magic 0x{0:X8} (expected 0x{1:X8})", fsb.magic,
                                          FOSSIL_SB_MAGIC);

                if (fsb.magic == FOSSIL_SB_MAGIC)
                {
                    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, Encoding)).AppendLine();
                    XmlFsType.VolumeName = StringHandlers.CToString(fsb.name, Encoding);
                }
            }

            information = sb.ToString();
        }
Ejemplo n.º 8
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 512)
            {
                return(false);
            }

            byte[] sector = imagePlugin.ReadSector(partition.Start);

            FATX_Superblock fatxSb = BigEndianMarshal.ByteArrayToStructureBigEndian <FATX_Superblock>(sector);

            return(fatxSb.magic == FATX_MAGIC);
        }
Ejemplo n.º 9
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 256)
            {
                return(false);
            }

            byte[]         sector = imagePlugin.ReadSector(partition.Start);
            LifSystemBlock lifSb  = BigEndianMarshal.ByteArrayToStructureBigEndian <LifSystemBlock>(sector);

            DicConsole.DebugWriteLine("LIF plugin", "magic 0x{0:X8} (expected 0x{1:X8})", lifSb.magic, LIF_MAGIC);

            return(lifSb.magic == LIF_MAGIC);
        }
Ejemplo n.º 10
0
        public bool Identify(byte[] buffer)
        {
            if (buffer == null || buffer.Length < 26)
            {
                return(false);
            }

            byte[] hdr_b = new byte[26];
            Array.Copy(buffer, 0, hdr_b, 0, 26);
            header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleSingleHeader>(hdr_b);

            return(header.magic == AppleSingleMagic &&
                   (header.version == AppleSingleVersion || header.version == AppleSingleVersion2));
        }
Ejemplo n.º 11
0
        public void Update(byte[] data, bool bigEndian)
        {
            VersionInfo versionInfo = bigEndian
                                          ? BigEndianMarshal.ByteArrayToStructureBigEndian <VersionInfo>(data)
                                          : BigEndianMarshal.ByteArrayToStructureLittleEndian <VersionInfo>(data);

            txtMajorVersion.Text  = $"{versionInfo.major}";
            txtMiddleVersion.Text = $"{versionInfo.middle}";
            txtMinorVersion.Text  = $"{versionInfo.minor}";
            txtVariety.Text       = $"{versionInfo.variety}";
            txtInternal.Text      = $"{versionInfo.interna1}";
            txtShortInfo.Text     = StringHandlers.CToString(versionInfo.short_info, Encoding.UTF8);
            txtLongInfo.Text      = StringHandlers.CToString(versionInfo.long_info, Encoding.UTF8);
        }
Ejemplo n.º 12
0
        public bool Identify(Stream stream)
        {
            if (stream == null || stream.Length < 26)
            {
                return(false);
            }

            byte[] hdr_b = new byte[26];
            stream.Seek(0, SeekOrigin.Begin);
            stream.Read(hdr_b, 0, 26);
            header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleSingleHeader>(hdr_b);

            return(header.magic == AppleSingleMagic &&
                   (header.version == AppleSingleVersion || header.version == AppleSingleVersion2));
        }
Ejemplo n.º 13
0
        public bool Identify(byte[] buffer)
        {
            if (buffer == null || buffer.Length < 128)
            {
                return(false);
            }

            byte[] hdr_b = new byte[128];
            Array.Copy(buffer, 0, hdr_b, 0, 128);
            header = BigEndianMarshal.ByteArrayToStructureBigEndian <MacBinaryHeader>(hdr_b);

            return(header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
                   header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
                   (header.dataLength > 0 || header.resourceLength > 0));
        }
Ejemplo n.º 14
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
            byte[] sector = imagePlugin.ReadSector(partition.Start);
            uint   magic  = BitConverter.ToUInt32(sector, 0x00);

            CramSuperBlock crSb         = new CramSuperBlock();
            bool           littleEndian = true;

            switch (magic)
            {
            case CRAM_MAGIC:
                IntPtr crSbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(crSb));
                Marshal.Copy(sector, 0, crSbPtr, Marshal.SizeOf(crSb));
                crSb = (CramSuperBlock)Marshal.PtrToStructure(crSbPtr, typeof(CramSuperBlock));
                Marshal.FreeHGlobal(crSbPtr);
                break;

            case CRAM_CIGAM:
                crSb         = BigEndianMarshal.ByteArrayToStructureBigEndian <CramSuperBlock>(sector);
                littleEndian = false;
                break;
            }

            StringBuilder sbInformation = new StringBuilder();

            sbInformation.AppendLine("Cram file system");
            sbInformation.AppendLine(littleEndian ? "Little-endian" : "Big-endian");
            sbInformation.AppendFormat("Volume edition {0}", crSb.edition).AppendLine();
            sbInformation.AppendFormat("Volume name: {0}", StringHandlers.CToString(crSb.name, Encoding)).AppendLine();
            sbInformation.AppendFormat("Volume has {0} bytes", crSb.size).AppendLine();
            sbInformation.AppendFormat("Volume has {0} blocks", crSb.blocks).AppendLine();
            sbInformation.AppendFormat("Volume has {0} files", crSb.files).AppendLine();

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                VolumeName            = StringHandlers.CToString(crSb.name, Encoding),
                Type                  = "Cram file system",
                Clusters              = crSb.blocks,
                Files                 = crSb.files,
                FilesSpecified        = true,
                FreeClusters          = 0,
                FreeClustersSpecified = true
            };
        }
Ejemplo n.º 15
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
            byte[]    rootBlockSector = imagePlugin.ReadSector(partition.Start);
            RootBlock rootBlock       = BigEndianMarshal.ByteArrayToStructureBigEndian <RootBlock>(rootBlockSector);

            StringBuilder sbInformation = new StringBuilder();

            sbInformation.AppendLine("SmartFileSystem");

            sbInformation.AppendFormat("Volume version {0}", rootBlock.version).AppendLine();
            sbInformation.AppendFormat("Volume starts on device byte {0} and ends on byte {1}", rootBlock.firstbyte,
                                       rootBlock.lastbyte).AppendLine();
            sbInformation
            .AppendFormat("Volume has {0} blocks of {1} bytes each", rootBlock.totalblocks, rootBlock.blocksize)
            .AppendLine();
            sbInformation.AppendFormat("Volume created on {0}",
                                       DateHandlers.UnixUnsignedToDateTime(rootBlock.datecreated).AddYears(8))
            .AppendLine();
            sbInformation.AppendFormat("Bitmap starts in block {0}", rootBlock.bitmapbase).AppendLine();
            sbInformation.AppendFormat("Admin space container starts in block {0}", rootBlock.adminspacecontainer)
            .AppendLine();
            sbInformation.AppendFormat("Root object container starts in block {0}", rootBlock.rootobjectcontainer)
            .AppendLine();
            sbInformation.AppendFormat("Root node of the extent B-tree resides in block {0}", rootBlock.extentbnoderoot)
            .AppendLine();
            sbInformation.AppendFormat("Root node of the object B-tree resides in block {0}", rootBlock.objectnoderoot)
            .AppendLine();
            if (rootBlock.bits.HasFlag(SFSFlags.CaseSensitive))
            {
                sbInformation.AppendLine("Volume is case sensitive");
            }
            if (rootBlock.bits.HasFlag(SFSFlags.RecyledFolder))
            {
                sbInformation.AppendLine("Volume moves deleted files to a recycled folder");
            }
            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                CreationDate          = DateHandlers.UnixUnsignedToDateTime(rootBlock.datecreated).AddYears(8),
                CreationDateSpecified = true,
                Clusters    = rootBlock.totalblocks,
                ClusterSize = (int)rootBlock.blocksize,
                Type        = "SmartFileSystem"
            };
        }
Ejemplo n.º 16
0
        public bool Identify(Stream stream)
        {
            if (stream == null || stream.Length < 128)
            {
                return(false);
            }

            byte[] hdr_b = new byte[128];
            stream.Seek(0, SeekOrigin.Begin);
            stream.Read(hdr_b, 0, 128);
            header = BigEndianMarshal.ByteArrayToStructureBigEndian <MacBinaryHeader>(hdr_b);

            return(header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
                   header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
                   (header.dataLength > 0 || header.resourceLength > 0));
        }
Ejemplo n.º 17
0
        static RootBlock MarshalRootBlock(byte[] block)
        {
            byte[] tmp = new byte[228];
            Array.Copy(block, 0, tmp, 0, 24);
            Array.Copy(block, block.Length - 200, tmp, 28, 200);
            RootBlock root = BigEndianMarshal.ByteArrayToStructureBigEndian <RootBlock>(tmp);

            root.hashTable = new uint[(block.Length - 224) / 4];
            BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
            for (int i = 0; i < root.hashTable.Length; i++)
            {
                root.hashTable[i] = BigEndianBitConverter.ToUInt32(block, 24 + i * 4);
            }

            return(root);
        }
Ejemplo n.º 18
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 256)
            {
                return(false);
            }

            // Documentation says ID should be sector 0
            // I've found that OS-9/X68000 has it on sector 4
            // I've read OS-9/Apple2 has it on sector 15
            foreach (int i in new[] { 0, 4, 15 })
            {
                ulong        location = (ulong)i;
                RBF_IdSector rbfSb    = new RBF_IdSector();

                uint sbSize = (uint)(Marshal.SizeOf(rbfSb) / imagePlugin.Info.SectorSize);
                if (Marshal.SizeOf(rbfSb) % imagePlugin.Info.SectorSize != 0)
                {
                    sbSize++;
                }

                if (partition.Start + location + sbSize >= imagePlugin.Info.Sectors)
                {
                    break;
                }

                byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize);
                if (sector.Length < Marshal.SizeOf(rbfSb))
                {
                    return(false);
                }

                rbfSb = BigEndianMarshal.ByteArrayToStructureBigEndian <RBF_IdSector>(sector);
                RBF_NewIdSector rbf9000Sb = BigEndianMarshal.ByteArrayToStructureBigEndian <RBF_NewIdSector>(sector);

                DicConsole.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)
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 19
0
        public bool Identify(string path)
        {
            FileStream fstream = new FileStream(path, FileMode.Open, FileAccess.Read);

            if (fstream.Length < 26)
            {
                return(false);
            }

            byte[] hdr_b = new byte[26];
            fstream.Read(hdr_b, 0, 26);
            header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleSingleHeader>(hdr_b);

            fstream.Close();
            return(header.magic == AppleSingleMagic &&
                   (header.version == AppleSingleVersion || header.version == AppleSingleVersion2));
        }
Ejemplo n.º 20
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            ulong hdrSector = HEADER_POS / imagePlugin.Info.SectorSize;

            if (partition.Start + hdrSector > imagePlugin.Info.Sectors)
            {
                return(false);
            }

            byte[]       sector = imagePlugin.ReadSector(partition.Start + hdrSector);
            FossilHeader hdr    = BigEndianMarshal.ByteArrayToStructureBigEndian <FossilHeader>(sector);

            DicConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic,
                                      FOSSIL_HDR_MAGIC);

            return(hdr.magic == FOSSIL_HDR_MAGIC);
        }
Ejemplo n.º 21
0
        public bool Identify(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            stream.Seek(0, SeekOrigin.Begin);

            if (stream.Length < 512)
            {
                return(false);
            }

            byte[] qHdrB = new byte[48];
            stream.Read(qHdrB, 0, 48);
            qHdr = BigEndianMarshal.ByteArrayToStructureBigEndian <QCowHeader>(qHdrB);

            return(qHdr.magic == QCOW_MAGIC && qHdr.version == QCOW_VERSION);
        }
Ejemplo n.º 22
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 < 256)
            {
                return;
            }

            byte[]         sector = imagePlugin.ReadSector(partition.Start);
            LifSystemBlock lifSb  = BigEndianMarshal.ByteArrayToStructureBigEndian <LifSystemBlock>(sector);

            if (lifSb.magic != LIF_MAGIC)
            {
                return;
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("HP Logical Interchange Format");
            sb.AppendFormat("Directory starts at cluster {0}", lifSb.directoryStart).AppendLine();
            sb.AppendFormat("LIF identifier: {0}", lifSb.lifId).AppendLine();
            sb.AppendFormat("Directory size: {0} clusters", lifSb.directorySize).AppendLine();
            sb.AppendFormat("LIF version: {0}", lifSb.lifVersion).AppendLine();
            // How is this related to volume size? I have only CDs to test and makes no sense there
            sb.AppendFormat("{0} tracks", lifSb.tracks).AppendLine();
            sb.AppendFormat("{0} heads", lifSb.heads).AppendLine();
            sb.AppendFormat("{0} sectors", lifSb.sectors).AppendLine();
            sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(lifSb.volumeLabel, Encoding)).AppendLine();
            sb.AppendFormat("Volume created on {0}", DateHandlers.LifToDateTime(lifSb.creationDate)).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type                  = "HP Logical Interchange Format",
                ClusterSize           = 256,
                Clusters              = (long)(partition.Size / 256),
                CreationDate          = DateHandlers.LifToDateTime(lifSb.creationDate),
                CreationDateSpecified = true,
                VolumeName            = StringHandlers.CToString(lifSb.volumeLabel, Encoding)
            };
        }
Ejemplo n.º 23
0
        public bool Identify(string path)
        {
            FileStream fstream = new FileStream(path, FileMode.Open, FileAccess.Read);

            if (fstream.Length < 128)
            {
                return(false);
            }

            byte[] hdr_b = new byte[128];
            fstream.Read(hdr_b, 0, 128);
            header = BigEndianMarshal.ByteArrayToStructureBigEndian <MacBinaryHeader>(hdr_b);

            fstream.Close();
            return(header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
                   header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
                   (header.dataLength > 0 || header.resourceLength > 0));
        }
Ejemplo n.º 24
0
        public bool Identify(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            stream.Seek(0, SeekOrigin.Begin);

            if (stream.Length < 512)
            {
                return(false);
            }

            byte[] qHdrB = new byte[Marshal.SizeOf(qHdr)];
            stream.Read(qHdrB, 0, Marshal.SizeOf(qHdr));
            qHdr = BigEndianMarshal.ByteArrayToStructureBigEndian <QCow2Header>(qHdrB);

            DicConsole.DebugWriteLine("QCOW plugin", "qHdr.magic = 0x{0:X8}", qHdr.magic);
            DicConsole.DebugWriteLine("QCOW plugin", "qHdr.version = {0}", qHdr.version);

            return(qHdr.magic == QCOW_MAGIC && (qHdr.version == QCOW_VERSION2 || qHdr.version == QCOW_VERSION3));
        }
Ejemplo n.º 25
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = Encoding.UTF8;
            information = "";
            if (imagePlugin.Info.SectorSize < 512)
            {
                return;
            }

            FATX_Superblock fatxSb;

            byte[] sector = imagePlugin.ReadSector(partition.Start);

            fatxSb = BigEndianMarshal.ByteArrayToStructureBigEndian <FATX_Superblock>(sector);

            if (fatxSb.magic != FATX_MAGIC)
            {
                return;
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("FATX filesystem");
            sb.AppendFormat("Filesystem id {0}", fatxSb.id).AppendLine();
            sb.AppendFormat("{0} sectors ({1} bytes) per cluster", fatxSb.sectorsPerCluster,
                            fatxSb.sectorsPerCluster * imagePlugin.Info.SectorSize).AppendLine();
            sb.AppendFormat("Root directory starts on cluster {0}", fatxSb.rootDirectoryCluster).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type        = "FATX filesystem",
                ClusterSize = (int)(fatxSb.sectorsPerCluster * imagePlugin.Info.SectorSize)
            };
            XmlFsType.Clusters = (long)((partition.End - partition.Start + 1) * imagePlugin.Info.SectorSize /
                                        (ulong)XmlFsType.ClusterSize);
        }
Ejemplo n.º 26
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            uint sectorSize;

            if (imagePlugin.Info.SectorSize == 2352 || imagePlugin.Info.SectorSize == 2448)
            {
                sectorSize = 2048;
            }
            else
            {
                sectorSize =
                    imagePlugin.Info.SectorSize;
            }

            partitions = new List <Partition>();

            if (sectorOffset + 2 >= imagePlugin.Info.Sectors)
            {
                return(false);
            }

            byte[] ddmSector = imagePlugin.ReadSector(sectorOffset);

            ushort maxDrivers = 61;

            if (sectorSize == 256)
            {
                byte[] tmp = new byte[512];
                Array.Copy(ddmSector, 0, tmp, 0, 256);
                ddmSector  = tmp;
                maxDrivers = 29;
            }
            else if (sectorSize < 256)
            {
                return(false);
            }

            AppleDriverDescriptorMap ddm =
                BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDriverDescriptorMap>(ddmSector);

            DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbSig = 0x{0:X4}", ddm.sbSig);
            DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbBlockSize = {0}", ddm.sbBlockSize);
            DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbBlocks = {0}", ddm.sbBlocks);
            DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbDevType = {0}", ddm.sbDevType);
            DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbDevId = {0}", ddm.sbDevId);
            DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbData = 0x{0:X8}", ddm.sbData);
            DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbDrvrCount = {0}", ddm.sbDrvrCount);

            uint sequence = 0;

            if (ddm.sbSig == DDM_MAGIC)
            {
                if (ddm.sbDrvrCount < maxDrivers)
                {
                    ddm.sbMap = new AppleDriverEntry[ddm.sbDrvrCount];
                    for (int i = 0; i < ddm.sbDrvrCount; i++)
                    {
                        byte[] tmp = new byte[8];
                        Array.Copy(ddmSector, 18 + i * 8, tmp, 0, 8);
                        ddm.sbMap[i] = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDriverEntry>(tmp);
                        DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddBlock = {0}",
                                                  ddm.sbMap[i].ddBlock, i);
                        DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddSize = {0}", ddm.sbMap[i].ddSize,
                                                  i);
                        DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddType = {0}", ddm.sbMap[i].ddType,
                                                  i);

                        if (ddm.sbMap[i].ddSize == 0)
                        {
                            continue;
                        }

                        Partition part = new Partition
                        {
                            Size     = (ulong)(ddm.sbMap[i].ddSize * 512),
                            Length   = (ulong)(ddm.sbMap[i].ddSize * 512 / sectorSize),
                            Sequence = sequence,
                            Offset   = ddm.sbMap[i].ddBlock * sectorSize,
                            Start    = ddm.sbMap[i].ddBlock + sectorOffset,
                            Type     = "Apple_Driver"
                        };

                        if (ddm.sbMap[i].ddSize * 512 % sectorSize > 0)
                        {
                            part.Length++;
                        }

                        partitions.Add(part);

                        sequence++;
                    }
                }
            }

            byte[] partSector = imagePlugin.ReadSector(1 + sectorOffset);
            AppleOldDevicePartitionMap oldMap =
                BigEndianMarshal.ByteArrayToStructureBigEndian <AppleOldDevicePartitionMap>(partSector);

            // This is the easy one, no sector size mixing
            if (oldMap.pdSig == APM_MAGIC_OLD)
            {
                for (int i = 2; i < partSector.Length; i += 12)
                {
                    byte[] tmp = new byte[12];
                    Array.Copy(partSector, i, tmp, 0, 12);
                    AppleMapOldPartitionEntry oldEntry =
                        BigEndianMarshal.ByteArrayToStructureBigEndian <AppleMapOldPartitionEntry>(tmp);
                    DicConsole.DebugWriteLine("AppleMap Plugin", "old_map.sbMap[{1}].pdStart = {0}", oldEntry.pdStart,
                                              (i - 2) / 12);
                    DicConsole.DebugWriteLine("AppleMap Plugin", "old_map.sbMap[{1}].pdSize = {0}", oldEntry.pdSize,
                                              (i - 2) / 12);
                    DicConsole.DebugWriteLine("AppleMap Plugin", "old_map.sbMap[{1}].pdFSID = 0x{0:X8}",
                                              oldEntry.pdFSID, (i - 2) / 12);

                    if (oldEntry.pdSize == 0 && oldEntry.pdFSID == 0)
                    {
                        if (oldEntry.pdStart == 0)
                        {
                            break;
                        }

                        continue;
                    }

                    Partition part = new Partition
                    {
                        Size     = oldEntry.pdStart * ddm.sbBlockSize,
                        Length   = oldEntry.pdStart * ddm.sbBlockSize / sectorSize,
                        Sequence = sequence,
                        Offset   = oldEntry.pdSize * ddm.sbBlockSize,
                        Start    = oldEntry.pdSize * ddm.sbBlockSize / sectorSize,
                        Scheme   = Name,
                        Type     = oldEntry.pdFSID == HFS_MAGIC_OLD ? "Apple_HFS" : $"0x{oldEntry.pdFSID:X8}"
                    };

                    partitions.Add(part);

                    sequence++;
                }

                return(partitions.Count > 0);
            }

            AppleMapPartitionEntry entry;
            uint entrySize;
            uint entryCount;
            uint sectorsToRead;
            uint skipDdm;

            // If sector is bigger than 512
            if (sectorSize > 512)
            {
                byte[] tmp = new byte[512];
                Array.Copy(ddmSector, 512, tmp, 0, 512);
                entry = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleMapPartitionEntry>(tmp);
                // Check for a partition entry that's 512-byte aligned
                if (entry.signature == APM_MAGIC)
                {
                    DicConsole.DebugWriteLine("AppleMap Plugin", "Found misaligned entry.");
                    entrySize     = 512;
                    entryCount    = entry.entries;
                    skipDdm       = 512;
                    sectorsToRead = (entryCount + 1) * 512 / sectorSize + 1;
                }
                else
                {
                    entry = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleMapPartitionEntry>(partSector);
                    if (entry.signature == APM_MAGIC)
                    {
                        DicConsole.DebugWriteLine("AppleMap Plugin", "Found aligned entry.");
                        entrySize     = sectorSize;
                        entryCount    = entry.entries;
                        skipDdm       = sectorSize;
                        sectorsToRead = entryCount + 2;
                    }
                    else
                    {
                        return(partitions.Count > 0);
                    }
                }
            }
            else
            {
                entry = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleMapPartitionEntry>(partSector);
                if (entry.signature == APM_MAGIC)
                {
                    DicConsole.DebugWriteLine("AppleMap Plugin", "Found aligned entry.");
                    entrySize     = sectorSize;
                    entryCount    = entry.entries;
                    skipDdm       = sectorSize;
                    sectorsToRead = entryCount + 2;
                }
                else
                {
                    return(partitions.Count > 0);
                }
            }

            byte[] entries = imagePlugin.ReadSectors(sectorOffset, sectorsToRead);
            DicConsole.DebugWriteLine("AppleMap Plugin", "entry_size = {0}", entrySize);
            DicConsole.DebugWriteLine("AppleMap Plugin", "entry_count = {0}", entryCount);
            DicConsole.DebugWriteLine("AppleMap Plugin", "skip_ddm = {0}", skipDdm);
            DicConsole.DebugWriteLine("AppleMap Plugin", "sectors_to_read = {0}", sectorsToRead);

            byte[] copy = new byte[entries.Length - skipDdm];
            Array.Copy(entries, skipDdm, copy, 0, copy.Length);
            entries = copy;

            for (int i = 0; i < entryCount; i++)
            {
                byte[] tmp = new byte[entrySize];
                Array.Copy(entries, i * entrySize, tmp, 0, entrySize);
                entry = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleMapPartitionEntry>(tmp);
                if (entry.signature != APM_MAGIC)
                {
                    continue;
                }

                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].signature = 0x{1:X4}", i, entry.signature);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].reserved1 = 0x{1:X4}", i, entry.reserved1);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entries = {1}", i, entry.entries);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].start = {1}", i, entry.start);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].sectors = {1}", i, entry.sectors);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].name = \"{1}\"", i,
                                          StringHandlers.CToString(entry.name));
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].type = \"{1}\"", i,
                                          StringHandlers.CToString(entry.type));
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].first_data_block = {1}", i,
                                          entry.first_data_block);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].data_sectors = {1}", i, entry.data_sectors);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].flags = {1}", i,
                                          (AppleMapFlags)entry.flags);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].first_boot_block = {1}", i,
                                          entry.first_boot_block);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].boot_size = {1}", i, entry.boot_size);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].load_address = 0x{1:X8}", i,
                                          entry.load_address);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].load_address2 = 0x{1:X8}", i,
                                          entry.load_address2);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entry_point = 0x{1:X8}", i, entry.entry_point);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entry_point2 = 0x{1:X8}", i,
                                          entry.entry_point2);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].checksum = 0x{1:X8}", i, entry.checksum);
                DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].processor = \"{1}\"", i,
                                          StringHandlers.CToString(entry.processor));

                AppleMapFlags flags = (AppleMapFlags)entry.flags;

                // BeOS doesn't mark its partitions as valid
                //if(flags.HasFlag(AppleMapFlags.Valid) &&
                if (StringHandlers.CToString(entry.type) == "Apple_partition_map" || entry.sectors <= 0)
                {
                    continue;
                }

                StringBuilder sb = new StringBuilder();

                Partition partition = new Partition
                {
                    Sequence = sequence,
                    Type     = StringHandlers.CToString(entry.type),
                    Name     = StringHandlers.CToString(entry.name),
                    Offset   = entry.start * entrySize,
                    Size     = entry.sectors * entrySize,
                    Start    = entry.start * entrySize / sectorSize + sectorOffset,
                    Length   = entry.sectors * entrySize / sectorSize,
                    Scheme   = Name
                };
                sb.AppendLine("Partition flags:");
                if (flags.HasFlag(AppleMapFlags.Valid))
                {
                    sb.AppendLine("Partition is valid.");
                }
                if (flags.HasFlag(AppleMapFlags.Allocated))
                {
                    sb.AppendLine("Partition entry is allocated.");
                }
                if (flags.HasFlag(AppleMapFlags.InUse))
                {
                    sb.AppendLine("Partition is in use.");
                }
                if (flags.HasFlag(AppleMapFlags.Bootable))
                {
                    sb.AppendLine("Partition is bootable.");
                }
                if (flags.HasFlag(AppleMapFlags.Readable))
                {
                    sb.AppendLine("Partition is readable.");
                }
                if (flags.HasFlag(AppleMapFlags.Writable))
                {
                    sb.AppendLine("Partition is writable.");
                }

                if (flags.HasFlag(AppleMapFlags.Bootable))
                {
                    sb.AppendFormat("First boot sector: {0}", entry.first_boot_block * entrySize / sectorSize)
                    .AppendLine();
                    sb.AppendFormat("Boot is {0} bytes.", entry.boot_size).AppendLine();
                    sb.AppendFormat("Boot load address: 0x{0:X8}", entry.load_address).AppendLine();
                    sb.AppendFormat("Boot entry point: 0x{0:X8}", entry.entry_point).AppendLine();
                    sb.AppendFormat("Boot code checksum: 0x{0:X8}", entry.checksum).AppendLine();
                    sb.AppendFormat("Processor: {0}", StringHandlers.CToString(entry.processor)).AppendLine();

                    if (flags.HasFlag(AppleMapFlags.PicCode))
                    {
                        sb.AppendLine("Partition's boot code is position independent.");
                    }
                }

                partition.Description = sb.ToString();
                if (partition.Start < imagePlugin.Info.Sectors && partition.End < imagePlugin.Info.Sectors)
                {
                    partitions.Add(partition);
                    sequence++;
                }
                // Some CD and DVDs end with an Apple_Free that expands beyond the disc size...
                else if (partition.Start < imagePlugin.Info.Sectors)
                {
                    DicConsole.DebugWriteLine("AppleMap Plugin", "Cutting last partition end ({0}) to media size ({1})",
                                              partition.End, imagePlugin.Info.Sectors - 1);
                    partition.Length = imagePlugin.Info.Sectors - partition.Start;
                    partitions.Add(partition);
                    sequence++;
                }
                else
                {
                    DicConsole.DebugWriteLine("AppleMap Plugin",
                                              "Not adding partition becaus start ({0}) is outside media size ({1})",
                                              partition.Start, imagePlugin.Info.Sectors - 1);
                }
            }

            return(partitions.Count > 0);
        }
Ejemplo n.º 27
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();
        }
Ejemplo n.º 28
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

            // Xbox partitions always start on 0
            if (sectorOffset != 0)
            {
                return(false);
            }

            byte[] sector = imagePlugin.ReadSector(0);
            if (sector.Length < 512)
            {
                return(false);
            }

            Xbox360DevKitPartitionTable table =
                BigEndianMarshal.ByteArrayToStructureBigEndian <Xbox360DevKitPartitionTable>(sector);

            if (table.magic == XBOX360_DEVKIT_MAGIC &&
                table.contentOff + table.contentLen <= imagePlugin.Info.Sectors &&
                table.dashboardOff + table.dashboardLen <= imagePlugin.Info.Sectors)
            {
                Partition contentPart = new Partition
                {
                    Description = "Content volume",
                    Size        = (ulong)table.contentLen * imagePlugin.Info.SectorSize,
                    Length      = table.contentLen,
                    Sequence    = 1,
                    Offset      = (ulong)table.contentOff * imagePlugin.Info.SectorSize,
                    Start       = table.contentOff,
                    Scheme      = Name
                };

                Partition dashboardPart = new Partition
                {
                    Description = "Dashboard volume",
                    Size        = (ulong)table.dashboardLen * imagePlugin.Info.SectorSize,
                    Length      = table.dashboardLen,
                    Sequence    = 2,
                    Offset      = (ulong)table.dashboardOff * imagePlugin.Info.SectorSize,
                    Start       = table.dashboardOff,
                    Scheme      = Name
                };

                partitions.Add(contentPart);
                partitions.Add(dashboardPart);

                return(true);
            }

            uint temp;

            if (imagePlugin.Info.Sectors > (ulong)(MemoryUnitDataOff / imagePlugin.Info.SectorSize))
            {
                sector = imagePlugin.ReadSector((ulong)(MemoryUnitDataOff / imagePlugin.Info.SectorSize));
                temp   = BitConverter.ToUInt32(sector, 0);

                if (temp == XboxCigam)
                {
                    Partition sysCachePart = new Partition
                    {
                        Description = "System cache",
                        Size        = MemoryUnitDataOff,
                        Length      = (ulong)(MemoryUnitDataOff / imagePlugin.Info.SectorSize),
                        Sequence    = 1,
                        Offset      = 0,
                        Start       = 0,
                        Scheme      = Name
                    };

                    Partition dataPart = new Partition
                    {
                        Description = "Data volume",
                        Size        = imagePlugin.Info.Sectors * imagePlugin.Info.SectorSize - MemoryUnitDataOff,
                        Length      = imagePlugin.Info.Sectors - sysCachePart.Length,
                        Sequence    = 2,
                        Offset      = MemoryUnitDataOff,
                        Start       = sysCachePart.Length,
                        Scheme      = Name
                    };

                    partitions.Add(sysCachePart);
                    partitions.Add(dataPart);

                    return(true);
                }
            }

            if (imagePlugin.Info.Sectors <= (ulong)(Xbox360DataOff / imagePlugin.Info.SectorSize))
            {
                return(false);
            }

            {
                sector = imagePlugin.ReadSector((ulong)(Xbox360DataOff / imagePlugin.Info.SectorSize));
                temp   = BitConverter.ToUInt32(sector, 0);

                if (temp != XboxCigam)
                {
                    return(false);
                }

                Partition securityPart = new Partition
                {
                    Description = "Security sectors",
                    Size        = Xbox360SecuritySectorLen,
                    Length      = (ulong)(Xbox360SecuritySectorLen / imagePlugin.Info.SectorSize),
                    Sequence    = 1,
                    Offset      = Xbox360SecuritySectorOff,
                    Start       = (ulong)(Xbox360SecuritySectorOff / imagePlugin.Info.SectorSize),
                    Scheme      = Name
                };

                Partition sysCachePart = new Partition
                {
                    Description = "System cache",
                    Size        = Xbox360SystemCacheLen,
                    Length      = (ulong)(Xbox360SystemCacheLen / imagePlugin.Info.SectorSize),
                    Sequence    = 2,
                    Offset      = Xbox360SystemCacheOff,
                    Start       = (ulong)(Xbox360SystemCacheOff / imagePlugin.Info.SectorSize),
                    Scheme      = Name
                };

                Partition gameCachePart = new Partition
                {
                    Description = "Game cache",
                    Size        = Xbox360GameCacheLen,
                    Length      = (ulong)(Xbox360GameCacheLen / imagePlugin.Info.SectorSize),
                    Sequence    = 3,
                    Offset      = Xbox360GameCacheOff,
                    Start       = (ulong)(Xbox360GameCacheOff / imagePlugin.Info.SectorSize),
                    Scheme      = Name
                };

                Partition sysExtPart = new Partition
                {
                    Description = "System volume",
                    Size        = Xbox368SysExtLen,
                    Length      = (ulong)(Xbox368SysExtLen / imagePlugin.Info.SectorSize),
                    Sequence    = 4,
                    Offset      = Xbox368SysExtOff,
                    Start       = (ulong)(Xbox368SysExtOff / imagePlugin.Info.SectorSize),
                    Scheme      = Name
                };

                Partition sysExt2Part = new Partition
                {
                    Description = "System volume 2",
                    Size        = Xbox360SysExt2Len,
                    Length      = (ulong)(Xbox360SysExt2Len / imagePlugin.Info.SectorSize),
                    Sequence    = 5,
                    Offset      = Xbox360SysExt2Off,
                    Start       = (ulong)(Xbox360SysExt2Off / imagePlugin.Info.SectorSize),
                    Scheme      = Name
                };

                Partition xbox1Part = new Partition
                {
                    Description = "Xbox backwards compatibility",
                    Size        = Xbox360CompatLen,
                    Length      = (ulong)(Xbox360CompatLen / imagePlugin.Info.SectorSize),
                    Sequence    = 6,
                    Offset      = Xbox360CompatOff,
                    Start       = (ulong)(Xbox360CompatOff / imagePlugin.Info.SectorSize),
                    Scheme      = Name
                };

                Partition dataPart = new Partition
                {
                    Description = "Data volume",
                    Sequence    = 7,
                    Offset      = Xbox360DataOff,
                    Start       = (ulong)(Xbox360DataOff / imagePlugin.Info.SectorSize),
                    Scheme      = Name
                };
                dataPart.Length = imagePlugin.Info.Sectors - dataPart.Start;
                dataPart.Size   = dataPart.Length * imagePlugin.Info.SectorSize;

                partitions.Add(securityPart);
                partitions.Add(sysCachePart);
                partitions.Add(gameCachePart);
                partitions.Add(sysExtPart);
                partitions.Add(sysExt2Part);
                partitions.Add(xbox1Part);
                partitions.Add(dataPart);

                return(true);
            }
        }
Ejemplo n.º 29
0
        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();
        }
Ejemplo n.º 30
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            // TODO: Find correct default encoding
            Encoding    = Encoding.ASCII;
            information = "";
            StringBuilder superBlockMetadata = new StringBuilder();

            byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start);

            OperaSuperBlock sb = BigEndianMarshal.ByteArrayToStructureBigEndian <OperaSuperBlock>(sbSector);

            sb.sync_bytes = new byte[5];

            if (sb.record_type != 1 || sb.record_version != 1)
            {
                return;
            }
            if (Encoding.ASCII.GetString(sb.sync_bytes) != "ZZZZZ")
            {
                return;
            }

            superBlockMetadata.AppendFormat("Opera filesystem disc.").AppendLine();
            if (!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_label, Encoding)))
            {
                superBlockMetadata
                .AppendFormat("Volume label: {0}", StringHandlers.CToString(sb.volume_label, Encoding))
                .AppendLine();
            }
            if (!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_comment, Encoding)))
            {
                superBlockMetadata
                .AppendFormat("Volume comment: {0}", StringHandlers.CToString(sb.volume_comment, Encoding))
                .AppendLine();
            }
            superBlockMetadata.AppendFormat("Volume identifier: 0x{0:X8}", sb.volume_id).AppendLine();
            superBlockMetadata.AppendFormat("Block size: {0} bytes", sb.block_size).AppendLine();
            if (imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 ||
                imagePlugin.Info.SectorSize == 2448)
            {
                if (sb.block_size != 2048)
                {
                    superBlockMetadata
                    .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block",
                                  sb.block_size, 2048);
                }
            }
            else if (imagePlugin.Info.SectorSize != sb.block_size)
            {
                superBlockMetadata
                .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block",
                              sb.block_size, imagePlugin.Info.SectorSize);
            }
            superBlockMetadata
            .AppendFormat("Volume size: {0} blocks, {1} bytes", sb.block_count, sb.block_size * sb.block_count)
            .AppendLine();
            if ((ulong)sb.block_count > imagePlugin.Info.Sectors)
            {
                superBlockMetadata
                .AppendFormat("WARNING: Filesystem indicates {0} blocks while device indicates {1} blocks",
                              sb.block_count, imagePlugin.Info.Sectors);
            }
            superBlockMetadata.AppendFormat("Root directory identifier: 0x{0:X8}", sb.root_dirid).AppendLine();
            superBlockMetadata.AppendFormat("Root directory block size: {0} bytes", sb.rootdir_bsize).AppendLine();
            superBlockMetadata.AppendFormat("Root directory size: {0} blocks, {1} bytes", sb.rootdir_blocks,
                                            sb.rootdir_bsize * sb.rootdir_blocks).AppendLine();
            superBlockMetadata.AppendFormat("Last root directory copy: {0}", sb.last_root_copy).AppendLine();

            information = superBlockMetadata.ToString();

            XmlFsType = new FileSystemType
            {
                Type        = "Opera",
                VolumeName  = StringHandlers.CToString(sb.volume_label, Encoding),
                ClusterSize = sb.block_size,
                Clusters    = sb.block_count
            };
        }