Пример #1
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);

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

            switch (magic)
            {
            case CRAM_MAGIC:
                crSb = Marshal.ByteArrayToStructureLittleEndian <CramSuperBlock>(sector);

                break;

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

                break;
            }

            var 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
            };
        }
Пример #2
0
        public bool Identify(string path)
        {
            var 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 = Marshal.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)));
        }
Пример #3
0
        public void Open(byte[] buffer)
        {
            var ms = new MemoryStream(buffer);

            ms.Seek(0, SeekOrigin.Begin);

            byte[] hdr_b = new byte[128];
            ms.Read(hdr_b, 0, 128);
            header = Marshal.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);

            ms.Close();
            opened  = true;
            isBytes = true;
            bytes   = buffer;
        }
Пример #4
0
        public void Open(string path)
        {
            var 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 = Marshal.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;
        }
Пример #5
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            var sb = new StringBuilder();

            uint sector = 2;
            uint offset = 0;

            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
            {
                sector = 0;
                offset = 0x400;
            }

            bool   minix3 = false;
            int    filenamesize;
            string minixVersion;

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

            // Optical media
            if (offset > 0)
            {
                byte[] tmp = new byte[0x200];
                Array.Copy(minixSbSector, offset, tmp, 0, 0x200);
                minixSbSector = tmp;
            }

            ushort magic = BitConverter.ToUInt16(minixSbSector, 0x018);

            XmlFsType = new FileSystemType();

            bool littleEndian;

            if (magic == MINIX3_MAGIC ||
                magic == MINIX3_CIGAM ||
                magic == MINIX2_MAGIC ||
                magic == MINIX2_CIGAM ||
                magic == MINIX_MAGIC ||
                magic == MINIX_CIGAM)
            {
                filenamesize = 60;
                littleEndian = magic != MINIX3_CIGAM || magic == MINIX2_CIGAM || magic == MINIX_CIGAM;

                switch (magic)
                {
                case MINIX3_MAGIC:
                case MINIX3_CIGAM:
                    minixVersion   = "Minix v3 filesystem";
                    XmlFsType.Type = "Minix v3";

                    break;

                case MINIX2_MAGIC:
                case MINIX2_CIGAM:
                    minixVersion   = "Minix 3 v2 filesystem";
                    XmlFsType.Type = "Minix 3 v2";

                    break;

                default:
                    minixVersion   = "Minix 3 v1 filesystem";
                    XmlFsType.Type = "Minix 3 v1";

                    break;
                }

                minix3 = true;
            }
            else
            {
                magic = BitConverter.ToUInt16(minixSbSector, 0x010);

                switch (magic)
                {
                case MINIX_MAGIC:
                    filenamesize   = 14;
                    minixVersion   = "Minix v1 filesystem";
                    littleEndian   = true;
                    XmlFsType.Type = "Minix v1";

                    break;

                case MINIX_MAGIC2:
                    filenamesize   = 30;
                    minixVersion   = "Minix v1 filesystem";
                    littleEndian   = true;
                    XmlFsType.Type = "Minix v1";

                    break;

                case MINIX2_MAGIC:
                    filenamesize   = 14;
                    minixVersion   = "Minix v2 filesystem";
                    littleEndian   = true;
                    XmlFsType.Type = "Minix v2";

                    break;

                case MINIX2_MAGIC2:
                    filenamesize   = 30;
                    minixVersion   = "Minix v2 filesystem";
                    littleEndian   = true;
                    XmlFsType.Type = "Minix v2";

                    break;

                case MINIX_CIGAM:
                    filenamesize   = 14;
                    minixVersion   = "Minix v1 filesystem";
                    littleEndian   = false;
                    XmlFsType.Type = "Minix v1";

                    break;

                case MINIX_CIGAM2:
                    filenamesize   = 30;
                    minixVersion   = "Minix v1 filesystem";
                    littleEndian   = false;
                    XmlFsType.Type = "Minix v1";

                    break;

                case MINIX2_CIGAM:
                    filenamesize   = 14;
                    minixVersion   = "Minix v2 filesystem";
                    littleEndian   = false;
                    XmlFsType.Type = "Minix v2";

                    break;

                case MINIX2_CIGAM2:
                    filenamesize   = 30;
                    minixVersion   = "Minix v2 filesystem";
                    littleEndian   = false;
                    XmlFsType.Type = "Minix v2";

                    break;

                default: return;
                }
            }

            if (minix3)
            {
                SuperBlock3 mnxSb = littleEndian ? Marshal.ByteArrayToStructureLittleEndian <SuperBlock3>(minixSbSector)
                                        : Marshal.ByteArrayToStructureBigEndian <SuperBlock3>(minixSbSector);

                if (magic != MINIX3_MAGIC &&
                    magic != MINIX3_CIGAM)
                {
                    mnxSb.s_blocksize = 1024;
                }

                sb.AppendLine(minixVersion);
                sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();

                if (mnxSb.s_zones > 0) // On V2
                {
                    sb.AppendFormat("{0} zones on volume ({1} bytes)", mnxSb.s_zones, mnxSb.s_zones * 1024).
                    AppendLine();
                }
                else
                {
                    sb.AppendFormat("{0} zones on volume ({1} bytes)", mnxSb.s_nzones, mnxSb.s_nzones * 1024).
                    AppendLine();
                }

                sb.AppendFormat("{0} bytes/block", mnxSb.s_blocksize).AppendLine();
                sb.AppendFormat("{0} inodes on volume", mnxSb.s_ninodes).AppendLine();

                sb.AppendFormat("{0} blocks on inode map ({1} bytes)", mnxSb.s_imap_blocks,
                                mnxSb.s_imap_blocks * mnxSb.s_blocksize).AppendLine();

                sb.AppendFormat("{0} blocks on zone map ({1} bytes)", mnxSb.s_zmap_blocks,
                                mnxSb.s_zmap_blocks * mnxSb.s_blocksize).AppendLine();

                sb.AppendFormat("First data zone: {0}", mnxSb.s_firstdatazone).AppendLine();

                //sb.AppendFormat("log2 of blocks/zone: {0}", mnx_sb.s_log_zone_size).AppendLine(); // Apparently 0
                sb.AppendFormat("{0} bytes maximum per file", mnxSb.s_max_size).AppendLine();
                sb.AppendFormat("On-disk filesystem version: {0}", mnxSb.s_disk_version).AppendLine();

                XmlFsType.ClusterSize = mnxSb.s_blocksize;
                XmlFsType.Clusters    = mnxSb.s_zones > 0 ? mnxSb.s_zones : mnxSb.s_nzones;
            }
            else
            {
                SuperBlock mnxSb = littleEndian ? Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(minixSbSector)
                                       : Marshal.ByteArrayToStructureBigEndian <SuperBlock>(minixSbSector);

                sb.AppendLine(minixVersion);
                sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();

                if (mnxSb.s_zones > 0) // On V2
                {
                    sb.AppendFormat("{0} zones on volume ({1} bytes)", mnxSb.s_zones, mnxSb.s_zones * 1024).
                    AppendLine();
                }
                else
                {
                    sb.AppendFormat("{0} zones on volume ({1} bytes)", mnxSb.s_nzones, mnxSb.s_nzones * 1024).
                    AppendLine();
                }

                sb.AppendFormat("{0} inodes on volume", mnxSb.s_ninodes).AppendLine();

                sb.AppendFormat("{0} blocks on inode map ({1} bytes)", mnxSb.s_imap_blocks, mnxSb.s_imap_blocks * 1024).
                AppendLine();

                sb.AppendFormat("{0} blocks on zone map ({1} bytes)", mnxSb.s_zmap_blocks, mnxSb.s_zmap_blocks * 1024).
                AppendLine();

                sb.AppendFormat("First data zone: {0}", mnxSb.s_firstdatazone).AppendLine();

                //sb.AppendFormat("log2 of blocks/zone: {0}", mnx_sb.s_log_zone_size).AppendLine(); // Apparently 0
                sb.AppendFormat("{0} bytes maximum per file", mnxSb.s_max_size).AppendLine();
                sb.AppendFormat("Filesystem state: {0:X4}", mnxSb.s_state).AppendLine();
                XmlFsType.ClusterSize = 1024;
                XmlFsType.Clusters    = mnxSb.s_zones > 0 ? mnxSb.s_zones : mnxSb.s_nzones;
            }

            information = sb.ToString();
        }
Пример #6
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            if (imagePlugin.Info.SectorSize < 512)
            {
                return;
            }

            var efsSb = new EFS_Superblock();

            // Misaligned
            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
            {
                uint sbSize = (uint)((Marshal.SizeOf <EFS_Superblock>() + 0x400) / imagePlugin.Info.SectorSize);

                if ((Marshal.SizeOf <EFS_Superblock>() + 0x400) % imagePlugin.Info.SectorSize != 0)
                {
                    sbSize++;
                }

                byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);

                if (sector.Length < Marshal.SizeOf <EFS_Superblock>())
                {
                    return;
                }

                byte[] sbpiece = new byte[Marshal.SizeOf <EFS_Superblock>()];

                Array.Copy(sector, 0x200, sbpiece, 0, Marshal.SizeOf <EFS_Superblock>());

                efsSb = Marshal.ByteArrayToStructureBigEndian <EFS_Superblock>(sbpiece);

                AaruConsole.DebugWriteLine("EFS plugin", "magic at 0x{0:X3} = 0x{1:X8} (expected 0x{2:X8} or 0x{3:X8})",
                                           0x200, efsSb.sb_magic, EFS_MAGIC, EFS_MAGIC_NEW);
            }
            else
            {
                uint sbSize = (uint)(Marshal.SizeOf <EFS_Superblock>() / imagePlugin.Info.SectorSize);

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

                byte[] sector = imagePlugin.ReadSectors(partition.Start + 1, sbSize);

                if (sector.Length < Marshal.SizeOf <EFS_Superblock>())
                {
                    return;
                }

                efsSb = Marshal.ByteArrayToStructureBigEndian <EFS_Superblock>(sector);

                AaruConsole.DebugWriteLine("EFS plugin", "magic at {0} = 0x{1:X8} (expected 0x{2:X8} or 0x{3:X8})", 1,
                                           efsSb.sb_magic, EFS_MAGIC, EFS_MAGIC_NEW);
            }

            if (efsSb.sb_magic != EFS_MAGIC &&
                efsSb.sb_magic != EFS_MAGIC_NEW)
            {
                return;
            }

            var sb = new StringBuilder();

            sb.AppendLine("SGI extent filesystem");

            if (efsSb.sb_magic == EFS_MAGIC_NEW)
            {
                sb.AppendLine("New version");
            }

            sb.AppendFormat("Filesystem size: {0} basic blocks", efsSb.sb_size).AppendLine();
            sb.AppendFormat("First cylinder group starts at block {0}", efsSb.sb_firstcg).AppendLine();
            sb.AppendFormat("Cylinder group size: {0} basic blocks", efsSb.sb_cgfsize).AppendLine();
            sb.AppendFormat("{0} inodes per cylinder group", efsSb.sb_cgisize).AppendLine();
            sb.AppendFormat("{0} sectors per track", efsSb.sb_sectors).AppendLine();
            sb.AppendFormat("{0} heads per cylinder", efsSb.sb_heads).AppendLine();
            sb.AppendFormat("{0} cylinder groups", efsSb.sb_ncg).AppendLine();
            sb.AppendFormat("Volume created on {0}", DateHandlers.UnixToDateTime(efsSb.sb_time)).AppendLine();
            sb.AppendFormat("{0} bytes on bitmap", efsSb.sb_bmsize).AppendLine();
            sb.AppendFormat("{0} free blocks", efsSb.sb_tfree).AppendLine();
            sb.AppendFormat("{0} free inodes", efsSb.sb_tinode).AppendLine();

            if (efsSb.sb_bmblock > 0)
            {
                sb.AppendFormat("Bitmap resides at block {0}", efsSb.sb_bmblock).AppendLine();
            }

            if (efsSb.sb_replsb > 0)
            {
                sb.AppendFormat("Replacement superblock resides at block {0}", efsSb.sb_replsb).AppendLine();
            }

            if (efsSb.sb_lastinode > 0)
            {
                sb.AppendFormat("Last inode allocated: {0}", efsSb.sb_lastinode).AppendLine();
            }

            if (efsSb.sb_dirty > 0)
            {
                sb.AppendLine("Volume is dirty");
            }

            sb.AppendFormat("Checksum: 0x{0:X8}", efsSb.sb_checksum).AppendLine();
            sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(efsSb.sb_fname, Encoding)).AppendLine();
            sb.AppendFormat("Volume pack: {0}", StringHandlers.CToString(efsSb.sb_fpack, Encoding)).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type                  = "Extent File System", ClusterSize = 512,
                Clusters              = (ulong)efsSb.sb_size,
                FreeClusters          = (ulong)efsSb.sb_tfree, FreeClustersSpecified = true,
                Dirty                 = efsSb.sb_dirty > 0,
                VolumeName            = StringHandlers.CToString(efsSb.sb_fname, Encoding),
                VolumeSerial          = $"{efsSb.sb_checksum:X8}",
                CreationDate          = DateHandlers.UnixToDateTime(efsSb.sb_time),
                CreationDateSpecified = true
            };
        }
Пример #7
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 512)
            {
                return(false);
            }

            // Misaligned
            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
            {
                uint sbSize = (uint)((Marshal.SizeOf <EFS_Superblock>() + 0x200) / imagePlugin.Info.SectorSize);

                if ((Marshal.SizeOf <EFS_Superblock>() + 0x200) % imagePlugin.Info.SectorSize != 0)
                {
                    sbSize++;
                }

                byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);

                if (sector.Length < Marshal.SizeOf <EFS_Superblock>())
                {
                    return(false);
                }

                byte[] sbpiece = new byte[Marshal.SizeOf <EFS_Superblock>()];

                Array.Copy(sector, 0x200, sbpiece, 0, Marshal.SizeOf <EFS_Superblock>());

                EFS_Superblock efsSb = Marshal.ByteArrayToStructureBigEndian <EFS_Superblock>(sbpiece);

                AaruConsole.DebugWriteLine("EFS plugin", "magic at 0x{0:X3} = 0x{1:X8} (expected 0x{2:X8} or 0x{3:X8})",
                                           0x200, efsSb.sb_magic, EFS_MAGIC, EFS_MAGIC_NEW);

                if (efsSb.sb_magic == EFS_MAGIC ||
                    efsSb.sb_magic == EFS_MAGIC_NEW)
                {
                    return(true);
                }
            }
            else
            {
                uint sbSize = (uint)(Marshal.SizeOf <EFS_Superblock>() / imagePlugin.Info.SectorSize);

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

                byte[] sector = imagePlugin.ReadSectors(partition.Start + 1, sbSize);

                if (sector.Length < Marshal.SizeOf <EFS_Superblock>())
                {
                    return(false);
                }

                EFS_Superblock efsSb = Marshal.ByteArrayToStructureBigEndian <EFS_Superblock>(sector);

                AaruConsole.DebugWriteLine("EFS plugin", "magic at {0} = 0x{1:X8} (expected 0x{2:X8} or 0x{3:X8})", 1,
                                           efsSb.sb_magic, EFS_MAGIC, EFS_MAGIC_NEW);

                if (efsSb.sb_magic == EFS_MAGIC ||
                    efsSb.sb_magic == EFS_MAGIC_NEW)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #8
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("ibm850");
            information = "";

            var sb = new StringBuilder();

            byte[] hpofsBpbSector =
                imagePlugin.ReadSector(0 + partition.Start); // Seek to BIOS parameter block, on logical sector 0

            byte[] medInfoSector =
                imagePlugin.ReadSector(13 + partition.Start); // Seek to media information block, on logical sector 13

            byte[] volInfoSector =
                imagePlugin.ReadSector(14 + partition.Start); // Seek to volume information block, on logical sector 14

            BiosParameterBlock     bpb = Marshal.ByteArrayToStructureLittleEndian <BiosParameterBlock>(hpofsBpbSector);
            MediaInformationBlock  mib = Marshal.ByteArrayToStructureBigEndian <MediaInformationBlock>(medInfoSector);
            VolumeInformationBlock vib = Marshal.ByteArrayToStructureBigEndian <VolumeInformationBlock>(volInfoSector);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.oem_name = \"{0}\"",
                                       StringHandlers.CToString(bpb.oem_name));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.bps = {0}", bpb.bps);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.spc = {0}", bpb.spc);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.rsectors = {0}", bpb.rsectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.fats_no = {0}", bpb.fats_no);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.root_ent = {0}", bpb.root_ent);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.sectors = {0}", bpb.sectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.media = 0x{0:X2}", bpb.media);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.spfat = {0}", bpb.spfat);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.sptrk = {0}", bpb.sptrk);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.heads = {0}", bpb.heads);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.hsectors = {0}", bpb.hsectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.big_sectors = {0}", bpb.big_sectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.drive_no = 0x{0:X2}", bpb.drive_no);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.nt_flags = {0}", bpb.nt_flags);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.signature = 0x{0:X2}", bpb.signature);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.serial_no = 0x{0:X8}", bpb.serial_no);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.volume_label = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(bpb.volume_label));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.fs_type = \"{0}\"", StringHandlers.CToString(bpb.fs_type));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.boot_code is empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(bpb.boot_code));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.unknown = {0}", bpb.unknown);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.unknown2 = {0}", bpb.unknown2);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.signature2 = {0}", bpb.signature2);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.blockId = \"{0}\"", StringHandlers.CToString(mib.blockId));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.volumeLabel = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(mib.volumeLabel));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.comment = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(mib.comment));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.serial = 0x{0:X8}", mib.serial);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.creationTimestamp = {0}",
                                       DateHandlers.DosToDateTime(mib.creationDate, mib.creationTime));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.codepageType = {0}", mib.codepageType);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.codepage = {0}", mib.codepage);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.rps = {0}", mib.rps);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.bps = {0}", mib.bps);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.bpc = {0}", mib.bpc);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown2 = {0}", mib.unknown2);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.sectors = {0}", mib.sectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown3 = {0}", mib.unknown3);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown4 = {0}", mib.unknown4);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.major = {0}", mib.major);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.minor = {0}", mib.minor);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown5 = {0}", mib.unknown5);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown6 = {0}", mib.unknown6);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.filler is empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(mib.filler));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.blockId = \"{0}\"", StringHandlers.CToString(vib.blockId));
            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown = {0}", vib.unknown);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown2 = {0}", vib.unknown2);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown3 is empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(vib.unknown3));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown4 = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(vib.unknown4));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.owner = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(vib.owner));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown5 = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(vib.unknown5));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown6 = {0}", vib.unknown6);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.percentFull = {0}", vib.percentFull);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown7 = {0}", vib.unknown7);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.filler is empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(vib.filler));

            sb.AppendLine("High Performance Optical File System");
            sb.AppendFormat("OEM name: {0}", StringHandlers.SpacePaddedToString(bpb.oem_name)).AppendLine();
            sb.AppendFormat("{0} bytes per sector", bpb.bps).AppendLine();
            sb.AppendFormat("{0} sectors per cluster", bpb.spc).AppendLine();
            sb.AppendFormat("Media descriptor: 0x{0:X2}", bpb.media).AppendLine();
            sb.AppendFormat("{0} sectors per track", bpb.sptrk).AppendLine();
            sb.AppendFormat("{0} heads", bpb.heads).AppendLine();
            sb.AppendFormat("{0} sectors hidden before BPB", bpb.hsectors).AppendLine();
            sb.AppendFormat("{0} sectors on volume ({1} bytes)", mib.sectors, mib.sectors * bpb.bps).AppendLine();
            sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", bpb.drive_no).AppendLine();
            sb.AppendFormat("Serial number: 0x{0:X8}", mib.serial).AppendLine();

            sb.AppendFormat("Volume label: {0}", StringHandlers.SpacePaddedToString(mib.volumeLabel, Encoding)).
            AppendLine();

            sb.AppendFormat("Volume comment: {0}", StringHandlers.SpacePaddedToString(mib.comment, Encoding)).
            AppendLine();

            sb.AppendFormat("Volume owner: {0}", StringHandlers.SpacePaddedToString(vib.owner, Encoding)).AppendLine();

            sb.AppendFormat("Volume created on {0}", DateHandlers.DosToDateTime(mib.creationDate, mib.creationTime)).
            AppendLine();

            sb.AppendFormat("Volume uses {0} codepage {1}", mib.codepageType > 0 && mib.codepageType < 3
                                                                ? mib.codepageType == 2
                                                                      ? "EBCDIC"
                                                                      : "ASCII" : "Unknown", mib.codepage).AppendLine();

            sb.AppendFormat("RPS level: {0}", mib.rps).AppendLine();
            sb.AppendFormat("Filesystem version: {0}.{1}", mib.major, mib.minor).AppendLine();
            sb.AppendFormat("Volume can be filled up to {0}%", vib.percentFull).AppendLine();

            XmlFsType = new FileSystemType
            {
                Clusters               = mib.sectors / bpb.spc, ClusterSize = (uint)(bpb.bps * bpb.spc),
                CreationDate           = DateHandlers.DosToDateTime(mib.creationDate, mib.creationTime),
                CreationDateSpecified  = true,
                DataPreparerIdentifier = StringHandlers.SpacePaddedToString(vib.owner, Encoding), Type = "HPOFS",
                VolumeName             = StringHandlers.SpacePaddedToString(mib.volumeLabel, Encoding),
                VolumeSerial           = $"{mib.serial:X8}",
                SystemIdentifier       = StringHandlers.SpacePaddedToString(bpb.oem_name)
            };

            information = sb.ToString();
        }
Пример #9
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (partition.Start >= partition.End)
            {
                return(false);
            }

            // Boot block is unless defined otherwise, 2 blocks
            // Funny, you may need boot block to find root block if it's not in standard place just to know size of
            // block size and then read the whole boot block.
            // However while you can set a block size different from the sector size on formatting, the bootblock block
            // size for floppies is the sector size, and for RDB is usually is the hard disk sector size,
            // so this is not entirely wrong...
            byte[]    sector = imagePlugin.ReadSectors(0 + partition.Start, 2);
            BootBlock bblk   = Marshal.ByteArrayToStructureBigEndian <BootBlock>(sector);

            // AROS boot floppies...
            if (sector.Length >= 512 &&
                sector[510] == 0x55 &&
                sector[511] == 0xAA &&
                (bblk.diskType & FFS_MASK) != FFS_MASK &&
                (bblk.diskType & MUFS_MASK) != MUFS_MASK)
            {
                sector = imagePlugin.ReadSectors(1 + partition.Start, 2);
                bblk   = Marshal.ByteArrayToStructureBigEndian <BootBlock>(sector);
            }

            // Not FFS or MuFS?
            if ((bblk.diskType & FFS_MASK) != FFS_MASK &&
                (bblk.diskType & MUFS_MASK) != MUFS_MASK)
            {
                return(false);
            }

            // Clear checksum on sector
            sector[4] = sector[5] = sector[6] = sector[7] = 0;
            uint bsum = AmigaBootChecksum(sector);

            AaruConsole.DebugWriteLine("AmigaDOS plugin", "bblk.checksum = 0x{0:X8}", bblk.checksum);
            AaruConsole.DebugWriteLine("AmigaDOS plugin", "bsum = 0x{0:X8}", bsum);

            ulong bRootPtr = 0;

            // If bootblock is correct, let's take its rootblock pointer
            if (bsum == bblk.checksum)
            {
                bRootPtr = bblk.root_ptr + partition.Start;
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "Bootblock points to {0} as Rootblock", bRootPtr);
            }

            ulong[] rootPtrs =
            {
                bRootPtr + partition.Start,                                            ((((partition.End - partition.Start) + 1) / 2) + partition.Start) - 2,
                ((((partition.End - partition.Start) + 1) / 2) + partition.Start) - 1,
                (((partition.End - partition.Start) + 1) / 2) +
                partition.Start,
                (((partition.End - partition.Start) + 1) / 2) + partition.Start + 4
            };

            var rblk = new RootBlock();

            // So to handle even number of sectors
            foreach (ulong rootPtr in rootPtrs.Where(rootPtr => rootPtr < partition.End && rootPtr >= partition.Start))
            {
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "Searching for Rootblock in sector {0}", rootPtr);

                sector = imagePlugin.ReadSector(rootPtr);

                rblk.type = BigEndianBitConverter.ToUInt32(sector, 0x00);
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rblk.type = {0}", rblk.type);

                if (rblk.type != TYPE_HEADER)
                {
                    continue;
                }

                rblk.hashTableSize = BigEndianBitConverter.ToUInt32(sector, 0x0C);

                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rblk.hashTableSize = {0}", rblk.hashTableSize);

                uint blockSize       = (rblk.hashTableSize + 56) * 4;
                uint sectorsPerBlock = (uint)(blockSize / sector.Length);

                AaruConsole.DebugWriteLine("AmigaDOS plugin", "blockSize = {0}", blockSize);
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "sectorsPerBlock = {0}", sectorsPerBlock);

                if (blockSize % sector.Length > 0)
                {
                    sectorsPerBlock++;
                }

                if (rootPtr + sectorsPerBlock >= partition.End)
                {
                    continue;
                }

                sector = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock);

                // Clear checksum on sector
                rblk.checksum = BigEndianBitConverter.ToUInt32(sector, 20);
                sector[20]    = sector[21] = sector[22] = sector[23] = 0;
                uint rsum = AmigaChecksum(sector);

                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rblk.checksum = 0x{0:X8}", rblk.checksum);
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rsum = 0x{0:X8}", rsum);

                rblk.sec_type = BigEndianBitConverter.ToUInt32(sector, sector.Length - 4);
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rblk.sec_type = {0}", rblk.sec_type);

                if (rblk.sec_type == SUBTYPE_ROOT &&
                    rblk.checksum == rsum)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #10
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 = Marshal.ByteArrayToStructureBigEndian <AppleDriverDescriptorMap>(ddmSector);

            AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbSig = 0x{0:X4}", ddm.sbSig);
            AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbBlockSize = {0}", ddm.sbBlockSize);
            AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbBlocks = {0}", ddm.sbBlocks);
            AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbDevType = {0}", ddm.sbDevType);
            AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbDevId = {0}", ddm.sbDevId);
            AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbData = 0x{0:X8}", ddm.sbData);
            AaruConsole.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] = Marshal.ByteArrayToStructureBigEndian <AppleDriverEntry>(tmp);

                        AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddBlock = {0}",
                                                   ddm.sbMap[i].ddBlock, i);

                        AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddSize = {0}",
                                                   ddm.sbMap[i].ddSize, i);

                        AaruConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddType = {0}",
                                                   ddm.sbMap[i].ddType, i);

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

                        var 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 =
                Marshal.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 =
                        Marshal.ByteArrayToStructureBigEndian <AppleMapOldPartitionEntry>(tmp);

                    AaruConsole.DebugWriteLine("AppleMap Plugin", "old_map.sbMap[{1}].pdStart = {0}", oldEntry.pdStart,
                                               (i - 2) / 12);

                    AaruConsole.DebugWriteLine("AppleMap Plugin", "old_map.sbMap[{1}].pdSize = {0}", oldEntry.pdSize,
                                               (i - 2) / 12);

                    AaruConsole.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;
                    }

                    var 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 (ddmSector.Length > 512)
            {
                byte[] tmp = new byte[512];
                Array.Copy(ddmSector, 512, tmp, 0, 512);
                entry = Marshal.ByteArrayToStructureBigEndian <AppleMapPartitionEntry>(tmp);

                // Check for a partition entry that's 512-byte aligned
                if (entry.signature == APM_MAGIC)
                {
                    AaruConsole.DebugWriteLine("AppleMap Plugin", "Found misaligned entry.");
                    entrySize     = 512;
                    entryCount    = entry.entries;
                    skipDdm       = 512;
                    sectorsToRead = (((entryCount + 1) * 512) / sectorSize) + 1;
                }
                else
                {
                    entry = Marshal.ByteArrayToStructureBigEndian <AppleMapPartitionEntry>(partSector);

                    if (entry.signature == APM_MAGIC)
                    {
                        AaruConsole.DebugWriteLine("AppleMap Plugin", "Found aligned entry.");
                        entrySize     = sectorSize;
                        entryCount    = entry.entries;
                        skipDdm       = sectorSize;
                        sectorsToRead = entryCount + 2;
                    }
                    else
                    {
                        return(partitions.Count > 0);
                    }
                }
            }
            else
            {
                entry = Marshal.ByteArrayToStructureBigEndian <AppleMapPartitionEntry>(partSector);

                if (entry.signature == APM_MAGIC)
                {
                    AaruConsole.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);
            AaruConsole.DebugWriteLine("AppleMap Plugin", "entry_size = {0}", entrySize);
            AaruConsole.DebugWriteLine("AppleMap Plugin", "entry_count = {0}", entryCount);
            AaruConsole.DebugWriteLine("AppleMap Plugin", "skip_ddm = {0}", skipDdm);
            AaruConsole.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 = Marshal.ByteArrayToStructureBigEndian <AppleMapPartitionEntry>(tmp);

                if (entry.signature != APM_MAGIC)
                {
                    continue;
                }

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].signature = 0x{1:X4}", i, entry.signature);
                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].reserved1 = 0x{1:X4}", i, entry.reserved1);
                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entries = {1}", i, entry.entries);
                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].start = {1}", i, entry.start);
                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].sectors = {1}", i, entry.sectors);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].name = \"{1}\"", i,
                                           StringHandlers.CToString(entry.name));

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].type = \"{1}\"", i,
                                           StringHandlers.CToString(entry.type));

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].first_data_block = {1}", i,
                                           entry.first_data_block);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].data_sectors = {1}", i, entry.data_sectors);
                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].flags = {1}", i, (AppleMapFlags)entry.flags);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].first_boot_block = {1}", i,
                                           entry.first_boot_block);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].boot_size = {1}", i, entry.boot_size);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].load_address = 0x{1:X8}", i,
                                           entry.load_address);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].load_address2 = 0x{1:X8}", i,
                                           entry.load_address2);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entry_point = 0x{1:X8}", i, entry.entry_point);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entry_point2 = 0x{1:X8}", i,
                                           entry.entry_point2);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].checksum = 0x{1:X8}", i, entry.checksum);

                AaruConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].processor = \"{1}\"", i,
                                           StringHandlers.CToString(entry.processor));

                var 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;
                }

                var sb = new StringBuilder();

                var 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)
                {
                    AaruConsole.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
                {
                    AaruConsole.DebugWriteLine("AppleMap Plugin",
                                               "Not adding partition becaus start ({0}) is outside media size ({1})",
                                               partition.Start, imagePlugin.Info.Sectors - 1);
                }
            }

            return(partitions.Count > 0);
        }
Пример #11
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;
            }

            var rbfSb     = new RBF_IdSector();
            var rbf9000Sb = new RBF_NewIdSector();

            foreach (int i in new[]
            {
                0, 4, 15
            })
            {
                ulong location = (ulong)i;
                uint  sbSize   = (uint)(Marshal.SizeOf <RBF_IdSector>() / imagePlugin.Info.SectorSize);

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

                byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize);

                if (sector.Length < Marshal.SizeOf <RBF_IdSector>())
                {
                    return;
                }

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

                AaruConsole.DebugWriteLine("RBF plugin",
                                           "magic at {0} = 0x{1:X8} or 0x{2:X8} (expected 0x{3:X8} or 0x{4:X8})",
                                           location, rbfSb.dd_sync, rbf9000Sb.rid_sync, RBF_SYNC, RBF_CNYS);

                if (rbfSb.dd_sync == RBF_SYNC ||
                    rbf9000Sb.rid_sync == RBF_SYNC ||
                    rbf9000Sb.rid_sync == RBF_CNYS)
                {
                    break;
                }
            }

            if (rbfSb.dd_sync != RBF_SYNC &&
                rbf9000Sb.rid_sync != RBF_SYNC &&
                rbf9000Sb.rid_sync != RBF_CNYS)
            {
                return;
            }

            if (rbf9000Sb.rid_sync == RBF_CNYS)
            {
                rbf9000Sb = (RBF_NewIdSector)Marshal.SwapStructureMembersEndian(rbf9000Sb);
            }

            var sb = new StringBuilder();

            sb.AppendLine("OS-9 Random Block File");

            if (rbf9000Sb.rid_sync == RBF_SYNC)
            {
                sb.AppendFormat("Volume ID: {0:X8}", rbf9000Sb.rid_diskid).AppendLine();
                sb.AppendFormat("{0} blocks in volume", rbf9000Sb.rid_totblocks).AppendLine();
                sb.AppendFormat("{0} cylinders", rbf9000Sb.rid_cylinders).AppendLine();
                sb.AppendFormat("{0} blocks in cylinder 0", rbf9000Sb.rid_cyl0size).AppendLine();
                sb.AppendFormat("{0} blocks per cylinder", rbf9000Sb.rid_cylsize).AppendLine();
                sb.AppendFormat("{0} heads", rbf9000Sb.rid_heads).AppendLine();
                sb.AppendFormat("{0} bytes per block", rbf9000Sb.rid_blocksize).AppendLine();

                // TODO: Convert to flags?
                sb.AppendLine((rbf9000Sb.rid_format & 0x01) == 0x01 ? "Disk is double sided" : "Disk is single sided");

                sb.AppendLine((rbf9000Sb.rid_format & 0x02) == 0x02 ? "Disk is double density"
                                  : "Disk is single density");

                if ((rbf9000Sb.rid_format & 0x10) == 0x10)
                {
                    sb.AppendLine("Disk is 384 TPI");
                }
                else if ((rbf9000Sb.rid_format & 0x08) == 0x08)
                {
                    sb.AppendLine("Disk is 192 TPI");
                }
                else if ((rbf9000Sb.rid_format & 0x04) == 0x04)
                {
                    sb.AppendLine("Disk is 96 TPI or 135 TPI");
                }
                else
                {
                    sb.AppendLine("Disk is 48 TPI");
                }

                sb.AppendFormat("Allocation bitmap descriptor starts at block {0}",
                                rbf9000Sb.rid_bitmap == 0 ? 1 : rbf9000Sb.rid_bitmap).AppendLine();

                if (rbf9000Sb.rid_firstboot > 0)
                {
                    sb.AppendFormat("Debugger descriptor starts at block {0}", rbf9000Sb.rid_firstboot).AppendLine();
                }

                if (rbf9000Sb.rid_bootfile > 0)
                {
                    sb.AppendFormat("Boot file descriptor starts at block {0}", rbf9000Sb.rid_bootfile).AppendLine();
                }

                sb.AppendFormat("Root directory descriptor starts at block {0}", rbf9000Sb.rid_rootdir).AppendLine();

                sb.AppendFormat("Disk is owned by group {0} user {1}", rbf9000Sb.rid_group, rbf9000Sb.rid_owner).
                AppendLine();

                sb.AppendFormat("Volume was created on {0}", DateHandlers.UnixToDateTime(rbf9000Sb.rid_ctime)).
                AppendLine();

                sb.AppendFormat("Volume's identification block was last written on {0}",
                                DateHandlers.UnixToDateTime(rbf9000Sb.rid_mtime)).AppendLine();

                sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(rbf9000Sb.rid_name, Encoding)).
                AppendLine();

                XmlFsType = new FileSystemType
                {
                    Type                      = "OS-9 Random Block File",
                    Bootable                  = rbf9000Sb.rid_bootfile > 0,
                    ClusterSize               = rbf9000Sb.rid_blocksize,
                    Clusters                  = rbf9000Sb.rid_totblocks,
                    CreationDate              = DateHandlers.UnixToDateTime(rbf9000Sb.rid_ctime),
                    CreationDateSpecified     = true,
                    ModificationDate          = DateHandlers.UnixToDateTime(rbf9000Sb.rid_mtime),
                    ModificationDateSpecified = true,
                    VolumeName                = StringHandlers.CToString(rbf9000Sb.rid_name, Encoding),
                    VolumeSerial              = $"{rbf9000Sb.rid_diskid:X8}"
                };
            }
            else
            {
                sb.AppendFormat("Volume ID: {0:X4}", rbfSb.dd_dsk).AppendLine();
                sb.AppendFormat("{0} blocks in volume", LSNToUInt32(rbfSb.dd_tot)).AppendLine();
                sb.AppendFormat("{0} tracks", rbfSb.dd_tks).AppendLine();
                sb.AppendFormat("{0} sectors per track", rbfSb.dd_spt).AppendLine();
                sb.AppendFormat("{0} bytes per sector", 256 << rbfSb.dd_lsnsize).AppendLine();

                sb.AppendFormat("{0} sectors per cluster ({1} bytes)", rbfSb.dd_bit,
                                rbfSb.dd_bit * (256 << rbfSb.dd_lsnsize)).AppendLine();

                // TODO: Convert to flags?
                sb.AppendLine((rbfSb.dd_fmt & 0x01) == 0x01 ? "Disk is double sided" : "Disk is single sided");
                sb.AppendLine((rbfSb.dd_fmt & 0x02) == 0x02 ? "Disk is double density" : "Disk is single density");

                if ((rbfSb.dd_fmt & 0x10) == 0x10)
                {
                    sb.AppendLine("Disk is 384 TPI");
                }
                else if ((rbfSb.dd_fmt & 0x08) == 0x08)
                {
                    sb.AppendLine("Disk is 192 TPI");
                }
                else if ((rbfSb.dd_fmt & 0x04) == 0x04)
                {
                    sb.AppendLine("Disk is 96 TPI or 135 TPI");
                }
                else
                {
                    sb.AppendLine("Disk is 48 TPI");
                }

                sb.AppendFormat("Allocation bitmap descriptor starts at block {0}",
                                rbfSb.dd_maplsn == 0 ? 1 : rbfSb.dd_maplsn).AppendLine();

                sb.AppendFormat("{0} bytes in allocation bitmap", rbfSb.dd_map).AppendLine();

                if (LSNToUInt32(rbfSb.dd_bt) > 0 &&
                    rbfSb.dd_bsz > 0)
                {
                    sb.AppendFormat("Boot file starts at block {0} and has {1} bytes", LSNToUInt32(rbfSb.dd_bt),
                                    rbfSb.dd_bsz).AppendLine();
                }

                sb.AppendFormat("Root directory descriptor starts at block {0}", LSNToUInt32(rbfSb.dd_dir)).
                AppendLine();

                sb.AppendFormat("Disk is owned by user {0}", rbfSb.dd_own).AppendLine();
                sb.AppendFormat("Volume was created on {0}", DateHandlers.Os9ToDateTime(rbfSb.dd_dat)).AppendLine();
                sb.AppendFormat("Volume attributes: {0:X2}", rbfSb.dd_att).AppendLine();
                sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(rbfSb.dd_nam, Encoding)).AppendLine();

                sb.AppendFormat("Path descriptor options: {0}", StringHandlers.CToString(rbfSb.dd_opt, Encoding)).
                AppendLine();

                XmlFsType = new FileSystemType
                {
                    Type                  = "OS-9 Random Block File",
                    Bootable              = LSNToUInt32(rbfSb.dd_bt) > 0 && rbfSb.dd_bsz > 0,
                    ClusterSize           = (uint)(rbfSb.dd_bit * (256 << rbfSb.dd_lsnsize)),
                    Clusters              = LSNToUInt32(rbfSb.dd_tot),
                    CreationDate          = DateHandlers.Os9ToDateTime(rbfSb.dd_dat),
                    CreationDateSpecified = true,
                    VolumeName            = StringHandlers.CToString(rbfSb.dd_nam, Encoding),
                    VolumeSerial          = $"{rbfSb.dd_dsk:X4}"
                };
            }

            information = sb.ToString();
        }
Пример #12
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = Encoding.BigEndianUnicode;
            information = "";

            var vh = new VolumeHeader();

            ulong hfspOffset;
            bool  wrapped;

            uint sectorsToRead = 0x800 / imagePlugin.Info.SectorSize;

            if (0x800 % imagePlugin.Info.SectorSize > 0)
            {
                sectorsToRead++;
            }

            byte[] vhSector = imagePlugin.ReadSectors(partition.Start, sectorsToRead);

            ushort drSigWord = BigEndianBitConverter.ToUInt16(vhSector, 0x400);

            if (drSigWord == AppleCommon.HFS_MAGIC)                          // "BD"
            {
                drSigWord = BigEndianBitConverter.ToUInt16(vhSector, 0x47C); // Read embedded HFS+ signature

                if (drSigWord == AppleCommon.HFSP_MAGIC)                     // "H+"
                {
                    ushort xdrStABNt = BigEndianBitConverter.ToUInt16(vhSector, 0x47E);

                    uint drAlBlkSiz = BigEndianBitConverter.ToUInt32(vhSector, 0x414);

                    ushort drAlBlSt = BigEndianBitConverter.ToUInt16(vhSector, 0x41C);

                    hfspOffset = (ulong)(((drAlBlSt * 512) + (xdrStABNt * drAlBlkSiz)) / imagePlugin.Info.SectorSize);
                    wrapped    = true;
                }
                else
                {
                    hfspOffset = 0;
                    wrapped    = false;
                }
            }
            else
            {
                hfspOffset = 0;
                wrapped    = false;
            }

            vhSector = imagePlugin.ReadSectors(partition.Start + hfspOffset, sectorsToRead); // Read volume header

            vh.signature = BigEndianBitConverter.ToUInt16(vhSector, 0x400);

            if (vh.signature != AppleCommon.HFSP_MAGIC &&
                vh.signature != AppleCommon.HFSX_MAGIC)
            {
                return;
            }

            var sb = new StringBuilder();

            if (vh.signature == 0x482B)
            {
                sb.AppendLine("HFS+ filesystem.");
            }

            if (vh.signature == 0x4858)
            {
                sb.AppendLine("HFSX filesystem.");
            }

            if (wrapped)
            {
                sb.AppendLine("Volume is wrapped inside an HFS volume.");
            }

            byte[] tmp = new byte[0x400];
            Array.Copy(vhSector, 0x400, tmp, 0, 0x400);
            vhSector = tmp;

            vh = Marshal.ByteArrayToStructureBigEndian <VolumeHeader>(vhSector);

            if (vh.version == 4 ||
                vh.version == 5)
            {
                sb.AppendFormat("Filesystem version is {0}.", vh.version).AppendLine();

                if ((vh.attributes & 0x80) == 0x80)
                {
                    sb.AppendLine("Volume is locked on hardware.");
                }

                if ((vh.attributes & 0x100) == 0x100)
                {
                    sb.AppendLine("Volume is unmounted.");
                }

                if ((vh.attributes & 0x200) == 0x200)
                {
                    sb.AppendLine("There are bad blocks in the extents file.");
                }

                if ((vh.attributes & 0x400) == 0x400)
                {
                    sb.AppendLine("Volume does not require cache.");
                }

                if ((vh.attributes & 0x800) == 0x800)
                {
                    sb.AppendLine("Volume state is inconsistent.");
                }

                if ((vh.attributes & 0x1000) == 0x1000)
                {
                    sb.AppendLine("CNIDs are reused.");
                }

                if ((vh.attributes & 0x2000) == 0x2000)
                {
                    sb.AppendLine("Volume is journaled.");
                }

                if ((vh.attributes & 0x8000) == 0x8000)
                {
                    sb.AppendLine("Volume is locked on software.");
                }

                sb.AppendFormat("Implementation that last mounted the volume: \"{0}\".",
                                Encoding.ASCII.GetString(vh.lastMountedVersion)).AppendLine();

                if ((vh.attributes & 0x2000) == 0x2000)
                {
                    sb.AppendFormat("Journal starts at allocation block {0}.", vh.journalInfoBlock).AppendLine();
                }

                sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(vh.createDate)).AppendLine();
                sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(vh.modifyDate)).AppendLine();

                if (vh.backupDate > 0)
                {
                    sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(vh.backupDate)).AppendLine();
                }
                else
                {
                    sb.AppendLine("Volume has never been backed up");
                }

                if (vh.backupDate > 0)
                {
                    sb.AppendFormat("Last check date: {0}", DateHandlers.MacToDateTime(vh.checkedDate)).AppendLine();
                }
                else
                {
                    sb.AppendLine("Volume has never been checked up");
                }

                sb.AppendFormat("{0} files on volume.", vh.fileCount).AppendLine();
                sb.AppendFormat("{0} folders on volume.", vh.folderCount).AppendLine();
                sb.AppendFormat("{0} bytes per allocation block.", vh.blockSize).AppendLine();
                sb.AppendFormat("{0} allocation blocks.", vh.totalBlocks).AppendLine();
                sb.AppendFormat("{0} free blocks.", vh.freeBlocks).AppendLine();
                sb.AppendFormat("Next allocation block: {0}.", vh.nextAllocation).AppendLine();
                sb.AppendFormat("Resource fork clump size: {0} bytes.", vh.rsrcClumpSize).AppendLine();
                sb.AppendFormat("Data fork clump size: {0} bytes.", vh.dataClumpSize).AppendLine();
                sb.AppendFormat("Next unused CNID: {0}.", vh.nextCatalogID).AppendLine();
                sb.AppendFormat("Volume has been mounted writable {0} times.", vh.writeCount).AppendLine();
                sb.AppendFormat("Allocation File is {0} bytes.", vh.allocationFile_logicalSize).AppendLine();
                sb.AppendFormat("Extents File is {0} bytes.", vh.extentsFile_logicalSize).AppendLine();
                sb.AppendFormat("Catalog File is {0} bytes.", vh.catalogFile_logicalSize).AppendLine();
                sb.AppendFormat("Attributes File is {0} bytes.", vh.attributesFile_logicalSize).AppendLine();
                sb.AppendFormat("Startup File is {0} bytes.", vh.startupFile_logicalSize).AppendLine();
                sb.AppendLine("Finder info:");
                sb.AppendFormat("CNID of bootable system's directory: {0}", vh.drFndrInfo0).AppendLine();
                sb.AppendFormat("CNID of first-run application's directory: {0}", vh.drFndrInfo1).AppendLine();
                sb.AppendFormat("CNID of previously opened directory: {0}", vh.drFndrInfo2).AppendLine();
                sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", vh.drFndrInfo3).AppendLine();
                sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", vh.drFndrInfo5).AppendLine();

                if (vh.drFndrInfo6 != 0 &&
                    vh.drFndrInfo7 != 0)
                {
                    sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", vh.drFndrInfo6, vh.drFndrInfo7).AppendLine();
                }

                XmlFsType = new FileSystemType();

                if (vh.backupDate > 0)
                {
                    XmlFsType.BackupDate          = DateHandlers.MacToDateTime(vh.backupDate);
                    XmlFsType.BackupDateSpecified = true;
                }

                XmlFsType.Bootable   |= vh.drFndrInfo0 != 0 || vh.drFndrInfo3 != 0 || vh.drFndrInfo5 != 0;
                XmlFsType.Clusters    = vh.totalBlocks;
                XmlFsType.ClusterSize = vh.blockSize;

                if (vh.createDate > 0)
                {
                    XmlFsType.CreationDate          = DateHandlers.MacToDateTime(vh.createDate);
                    XmlFsType.CreationDateSpecified = true;
                }

                XmlFsType.Dirty                 = (vh.attributes & 0x100) != 0x100;
                XmlFsType.Files                 = vh.fileCount;
                XmlFsType.FilesSpecified        = true;
                XmlFsType.FreeClusters          = vh.freeBlocks;
                XmlFsType.FreeClustersSpecified = true;

                if (vh.modifyDate > 0)
                {
                    XmlFsType.ModificationDate          = DateHandlers.MacToDateTime(vh.modifyDate);
                    XmlFsType.ModificationDateSpecified = true;
                }

                if (vh.signature == 0x482B)
                {
                    XmlFsType.Type = "HFS+";
                }

                if (vh.signature == 0x4858)
                {
                    XmlFsType.Type = "HFSX";
                }

                if (vh.drFndrInfo6 != 0 &&
                    vh.drFndrInfo7 != 0)
                {
                    XmlFsType.VolumeSerial = $"{vh.drFndrInfo6:X8}{vh.drFndrInfo7:X8}";
                }

                XmlFsType.SystemIdentifier = Encoding.ASCII.GetString(vh.lastMountedVersion);
            }
            else
            {
                sb.AppendFormat("Filesystem version is {0}.", vh.version).AppendLine();
                sb.AppendLine("This version is not supported yet.");
            }

            information = sb.ToString();
        }
Пример #13
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 =
                Marshal.ByteArrayToStructureBigEndian <Xbox360DevKitPartitionTable>(sector);

            if (table.magic == XBOX360_DEVKIT_MAGIC &&
                table.contentOff + table.contentLen <= imagePlugin.Info.Sectors &&
                table.dashboardOff + table.dashboardLen <= imagePlugin.Info.Sectors)
            {
                var 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
                };

                var 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)
                {
                    var sysCachePart = new Partition
                    {
                        Description = "System cache",
                        Size        = MemoryUnitDataOff,
                        Length      = (ulong)(MemoryUnitDataOff / imagePlugin.Info.SectorSize),
                        Sequence    = 1,
                        Offset      = 0,
                        Start       = 0,
                        Scheme      = Name
                    };

                    var 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);
                }

                var 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
                };

                var 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
                };

                var 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
                };

                var 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
                };

                var 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
                };

                var 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
                };

                var 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);
            }
        }
Пример #14
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

            uint  magic = 0;
            ulong pdloc = 0;

            byte[] pdsector   = null;
            bool   magicFound = false;
            bool   absolute   = false;

            foreach (ulong i in new ulong[]
            {
                0, 1, 8, 29
            }.TakeWhile(i => i + sectorOffset < imagePlugin.Info.Sectors))
            {
                pdsector = imagePlugin.ReadSector(i + sectorOffset);
                magic    = BitConverter.ToUInt32(pdsector, 4);

                AaruConsole.DebugWriteLine("VTOC plugin", "sanity at {0} is 0x{1:X8} (should be 0x{2:X8} or 0x{3:X8})",
                                           i + sectorOffset, magic, PD_MAGIC, PD_CIGAM);

                if (magic != PD_MAGIC &&
                    magic != PD_CIGAM)
                {
                    continue;
                }

                magicFound = true;
                pdloc      = i;

                break;
            }

            if (!magicFound)
            {
                return(false);
            }

            PDInfo    pd;
            PDInfoOld pdold;

            if (magic == PD_MAGIC)
            {
                pd    = Marshal.ByteArrayToStructureLittleEndian <PDInfo>(pdsector);
                pdold = Marshal.ByteArrayToStructureLittleEndian <PDInfoOld>(pdsector);
            }
            else
            {
                pd    = Marshal.ByteArrayToStructureBigEndian <PDInfo>(pdsector);
                pdold = Marshal.ByteArrayToStructureBigEndian <PDInfoOld>(pdsector);
            }

            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.driveid = {0}", pd.driveid);

            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.sanity = 0x{0:X8} (should be 0x{1:X8})", pd.sanity,
                                       PD_MAGIC);

            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.version = {0}", pd.version);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.serial = \"{0}\"", StringHandlers.CToString(pd.serial));
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.cyls = {0}", pd.cyls);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.tracks = {0}", pd.tracks);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.sectors = {0}", pd.sectors);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.bytes = {0}", pd.bytes);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.logicalst = {0}", pd.logicalst);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.errlogst = {0}", pd.errlogst);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.errlogsz = {0}", pd.errlogsz);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.mfgst = {0}", pd.mfgst);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.mfgsz = {0}", pd.mfgsz);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.defectst = {0}", pd.defectst);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.defectsz = {0}", pd.defectsz);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.relno = {0}", pd.relno);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.relst = {0}", pd.relst);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.relsz = {0}", pd.relsz);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.relnext = {0}", pd.relnext);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.allcstrt = {0}", pdold.allcstrt);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.allcend = {0}", pdold.allcend);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.vtoc_ptr = {0}", pd.vtoc_ptr);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.vtoc_len = {0}", pd.vtoc_len);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.vtoc_pad = {0}", pd.vtoc_pad);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.alt_ptr = {0}", pd.alt_ptr);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.alt_len = {0}", pd.alt_len);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pcyls = {0}", pd.pcyls);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.ptracks = {0}", pd.ptracks);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.psectors = {0}", pd.psectors);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pbytes = {0}", pd.pbytes);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.secovhd = {0}", pd.secovhd);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.interleave = {0}", pd.interleave);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.skew = {0}", pd.skew);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[0] = {0}", pd.pad[0]);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[1] = {0}", pd.pad[1]);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[2] = {0}", pd.pad[2]);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[3] = {0}", pd.pad[3]);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[4] = {0}", pd.pad[4]);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[5] = {0}", pd.pad[5]);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[6] = {0}", pd.pad[6]);
            AaruConsole.DebugWriteLine("VTOC plugin", "pdinfo.pad[7] = {0}", pd.pad[7]);

            magicFound = false;
            bool useOld = false;

            byte[] vtocsector = imagePlugin.ReadSector(pdloc + sectorOffset + 1);
            var    vtoc       = new vtoc();
            var    vtocOld    = new vtocold();

            magic = BitConverter.ToUInt32(vtocsector, 0);

            if (magic == VTOC_SANE ||
                magic == VTOC_ENAS)
            {
                magicFound = true;
                AaruConsole.DebugWriteLine("VTOC plugin", "New VTOC found at {0}", pdloc + sectorOffset + 1);

                if (magic == VTOC_SANE)
                {
                    vtoc = Marshal.ByteArrayToStructureLittleEndian <vtoc>(vtocsector);
                }
                else
                {
                    vtoc = Marshal.ByteArrayToStructureBigEndian <vtoc>(vtocsector);

                    for (int i = 0; i < vtoc.v_part.Length; i++)
                    {
                        vtoc.v_part[i].p_tag   = (pTag)Swapping.Swap((ushort)vtoc.v_part[i].p_tag);
                        vtoc.v_part[i].p_flag  = (pFlag)Swapping.Swap((ushort)vtoc.v_part[i].p_flag);
                        vtoc.v_part[i].p_start = Swapping.Swap(vtoc.v_part[i].p_start);
                        vtoc.v_part[i].p_size  = Swapping.Swap(vtoc.v_part[i].p_size);
                        vtoc.timestamp[i]      = Swapping.Swap(vtoc.timestamp[i]);
                    }
                }
            }

            if (!magicFound &&
                pd.version < XPDVERS)
            {
                magic = BitConverter.ToUInt32(vtocsector, 12);

                if (magic == VTOC_SANE ||
                    magic == VTOC_ENAS)
                {
                    magicFound = true;
                    useOld     = true;
                    AaruConsole.DebugWriteLine("VTOC plugin", "Old VTOC found at {0}", pdloc + sectorOffset + 1);

                    if (magic == VTOC_SANE)
                    {
                        vtocOld = Marshal.ByteArrayToStructureLittleEndian <vtocold>(vtocsector);
                    }
                    else
                    {
                        vtocOld = Marshal.ByteArrayToStructureBigEndian <vtocold>(vtocsector);

                        for (int i = 0; i < vtocOld.v_part.Length; i++)
                        {
                            vtocOld.v_part[i].p_tag   = (pTag)Swapping.Swap((ushort)vtocOld.v_part[i].p_tag);
                            vtocOld.v_part[i].p_flag  = (pFlag)Swapping.Swap((ushort)vtocOld.v_part[i].p_flag);
                            vtocOld.v_part[i].p_start = Swapping.Swap(vtocOld.v_part[i].p_start);
                            vtocOld.v_part[i].p_size  = Swapping.Swap(vtocOld.v_part[i].p_size);
                            vtocOld.timestamp[i]      = Swapping.Swap(vtocOld.timestamp[i]);
                        }
                    }
                }
            }

            if (!magicFound)
            {
                AaruConsole.DebugWriteLine("VTOC plugin", "Searching for VTOC on relative byte {0}", pd.vtoc_ptr);
                ulong relSecPtr = pd.vtoc_ptr / imagePlugin.Info.SectorSize;
                uint  relSecOff = pd.vtoc_ptr % imagePlugin.Info.SectorSize;
                uint  secCount  = (relSecOff + pd.vtoc_len) / imagePlugin.Info.SectorSize;

                if ((relSecOff + pd.vtoc_len) % imagePlugin.Info.SectorSize > 0)
                {
                    secCount++;
                }

                AaruConsole.DebugWriteLine("VTOC plugin",
                                           "Going to read {0} sectors from sector {1}, getting VTOC from byte {2}",
                                           secCount, relSecPtr + sectorOffset, relSecOff);

                if (relSecPtr + sectorOffset + secCount >= imagePlugin.Info.Sectors)
                {
                    AaruConsole.DebugWriteLine("VTOC plugin", "Going to read past device size, aborting...");

                    return(false);
                }

                byte[] tmp = imagePlugin.ReadSectors(relSecPtr + sectorOffset, secCount);
                vtocsector = new byte[pd.vtoc_len];
                Array.Copy(tmp, relSecOff, vtocsector, 0, pd.vtoc_len);
                magic = BitConverter.ToUInt32(vtocsector, 0);

                if (magic == VTOC_SANE ||
                    magic == VTOC_ENAS)
                {
                    magicFound = true;
                    AaruConsole.DebugWriteLine("VTOC plugin", "New VTOC found.");

                    if (magic == VTOC_SANE)
                    {
                        vtoc = Marshal.ByteArrayToStructureLittleEndian <vtoc>(vtocsector);
                    }
                    else
                    {
                        vtoc = Marshal.ByteArrayToStructureBigEndian <vtoc>(vtocsector);

                        for (int i = 0; i < vtoc.v_part.Length; i++)
                        {
                            vtoc.v_part[i].p_tag   = (pTag)Swapping.Swap((ushort)vtoc.v_part[i].p_tag);
                            vtoc.v_part[i].p_flag  = (pFlag)Swapping.Swap((ushort)vtoc.v_part[i].p_flag);
                            vtoc.v_part[i].p_start = Swapping.Swap(vtoc.v_part[i].p_start);
                            vtoc.v_part[i].p_size  = Swapping.Swap(vtoc.v_part[i].p_size);
                            vtoc.timestamp[i]      = Swapping.Swap(vtoc.timestamp[i]);
                        }
                    }
                }
            }

            if (!magicFound)
            {
                AaruConsole.DebugWriteLine("VTOC plugin", "Cannot find VTOC.");

                return(false);
            }

            if (useOld)
            {
                AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_sanity = 0x{0:X8} (should be 0x{1:X8})",
                                           vtocOld.v_sanity, VTOC_SANE);

                AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_version = {0}", vtocOld.v_version);

                AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_volume = \"{0}\"",
                                           StringHandlers.CToString(vtocOld.v_volume));

                AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_sectorsz = {0}", vtocOld.v_sectorsz);
                AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_nparts = {0}", vtocOld.v_nparts);

                for (int i = 0; i < V_NUMPAR; i++)
                {
                    AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_part[{0}].p_tag = {1} ({2})", i,
                                               vtocOld.v_part[i].p_tag, (ushort)vtocOld.v_part[i].p_tag);

                    AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_part[{0}].p_flag = {1} ({2})", i,
                                               vtocOld.v_part[i].p_flag, (ushort)vtocOld.v_part[i].p_flag);

                    AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_part[{0}].p_start = {1}", i,
                                               vtocOld.v_part[i].p_start);

                    AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.v_part[{0}].p_size = {1}", i,
                                               vtocOld.v_part[i].p_size);

                    AaruConsole.DebugWriteLine("VTOC plugin", "vtocOld.timestamp[{0}] = {1}", i,
                                               DateHandlers.UnixToDateTime(vtocOld.timestamp[i]));
                }
            }
            else
            {
                AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_sanity = 0x{0:X8} (should be 0x{1:X8})",
                                           vtoc.v_sanity, VTOC_SANE);

                AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_version = {0}", vtoc.v_version);

                AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_volume = \"{0}\"",
                                           StringHandlers.CToString(vtoc.v_volume));

                AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_pad = {0}", vtoc.v_pad);
                AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_nparts = {0}", vtoc.v_nparts);

                for (int i = 0; i < V_NUMPAR; i++)
                {
                    AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_part[{0}].p_tag = {1} ({2})", i,
                                               vtoc.v_part[i].p_tag, (ushort)vtoc.v_part[i].p_tag);

                    AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_part[{0}].p_flag = {1} ({2})", i,
                                               vtoc.v_part[i].p_flag, (ushort)vtoc.v_part[i].p_flag);

                    AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_part[{0}].p_start = {1}", i,
                                               vtoc.v_part[i].p_start);

                    AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.v_part[{0}].p_size = {1}", i,
                                               vtoc.v_part[i].p_size);

                    AaruConsole.DebugWriteLine("VTOC plugin", "vtoc.timestamp[{0}] = {1}", i,
                                               DateHandlers.UnixToDateTime(vtoc.timestamp[i]));
                }
            }

            uint bps;

            partition[] parts;
            int[]       timestamps;

            if (useOld)
            {
                bps        = vtocOld.v_sectorsz;
                parts      = vtocOld.v_part;
                timestamps = vtocOld.timestamp;
            }
            else
            {
                bps        = pd.bytes;
                parts      = vtoc.v_part;
                timestamps = vtoc.timestamp;
            }

            // Check for a partition describing the VTOC whose start is the same as the start we know.
            // This means partition starts are absolute, not relative, to the VTOC position
            for (int i = 0; i < V_NUMPAR; i++)
            {
                if (parts[i].p_tag == pTag.V_BACKUP &&
                    (ulong)parts[i].p_start == sectorOffset)
                {
                    absolute = true;

                    break;
                }
            }

            for (int i = 0; i < V_NUMPAR; i++)
            {
                if (parts[i].p_tag != pTag.V_UNUSED)
                {
                    var part = new Partition
                    {
                        Start    = (ulong)(parts[i].p_start * bps) / imagePlugin.Info.SectorSize,
                        Length   = (ulong)(parts[i].p_size * bps) / imagePlugin.Info.SectorSize,
                        Offset   = (ulong)(parts[i].p_start * bps), Size = (ulong)(parts[i].p_size * bps),
                        Sequence = (ulong)i,
                        Type     = $"UNIX: {decodeUNIXTAG(parts[i].p_tag, !useOld)}", Scheme = Name
                    };

                    string info = "";

                    // Apparently old ones are absolute :?
                    if (!useOld &&
                        !absolute)
                    {
                        part.Start  += sectorOffset;
                        part.Offset += sectorOffset * imagePlugin.Info.SectorSize;
                    }

                    if (parts[i].p_flag.HasFlag(pFlag.V_VALID))
                    {
                        info += " (valid)";
                    }

                    if (parts[i].p_flag.HasFlag(pFlag.V_UNMNT))
                    {
                        info += " (unmountable)";
                    }

                    if (parts[i].p_flag.HasFlag(pFlag.V_OPEN))
                    {
                        info += " (open)";
                    }

                    if (parts[i].p_flag.HasFlag(pFlag.V_REMAP))
                    {
                        info += " (alternate sector mapping)";
                    }

                    if (parts[i].p_flag.HasFlag(pFlag.V_RONLY))
                    {
                        info += " (read-only)";
                    }

                    if (timestamps[i] != 0)
                    {
                        info += $" created on {DateHandlers.UnixToDateTime(timestamps[i])}";
                    }

                    part.Description = "UNIX slice" + info + ".";

                    if (part.End < imagePlugin.Info.Sectors)
                    {
                        partitions.Add(part);
                    }
                }
            }

            return(partitions.Count > 0);
        }
Пример #15
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            if (imagePlugin.Info.SectorSize < 512)
            {
                return;
            }

            var locusSb = new Locus_Superblock();

            byte[] sector = null;

            for (ulong location = 0; location <= 8; location++)
            {
                uint sbSize = (uint)(Marshal.SizeOf <Locus_Superblock>() / imagePlugin.Info.SectorSize);

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

                sector = imagePlugin.ReadSectors(partition.Start + location, sbSize);

                if (sector.Length < Marshal.SizeOf <Locus_Superblock>())
                {
                    return;
                }

                locusSb = Marshal.ByteArrayToStructureLittleEndian <Locus_Superblock>(sector);

                if (locusSb.s_magic == LOCUS_MAGIC ||
                    locusSb.s_magic == LOCUS_CIGAM ||
                    locusSb.s_magic == LOCUS_MAGIC_OLD ||
                    locusSb.s_magic == LOCUS_CIGAM_OLD)
                {
                    break;
                }
            }

            // We don't care about old version for information
            if (locusSb.s_magic != LOCUS_MAGIC &&
                locusSb.s_magic != LOCUS_CIGAM &&
                locusSb.s_magic != LOCUS_MAGIC_OLD &&
                locusSb.s_magic != LOCUS_CIGAM_OLD)
            {
                return;
            }

            // Numerical arrays are not important for information so no need to swap them
            if (locusSb.s_magic == LOCUS_CIGAM ||
                locusSb.s_magic == LOCUS_CIGAM_OLD)
            {
                locusSb         = Marshal.ByteArrayToStructureBigEndian <Locus_Superblock>(sector);
                locusSb.s_flags = (LocusFlags)Swapping.Swap((ushort)locusSb.s_flags);
            }

            var sb = new StringBuilder();

            sb.AppendLine(locusSb.s_magic == LOCUS_MAGIC_OLD ? "Locus filesystem (old)" : "Locus filesystem");

            int blockSize = locusSb.s_version == LocusVersion.SB_SB4096 ? 4096 : 1024;

            string s_fsmnt = StringHandlers.CToString(locusSb.s_fsmnt, Encoding);
            string s_fpack = StringHandlers.CToString(locusSb.s_fpack, Encoding);

            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_magic = 0x{0:X8}", locusSb.s_magic);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_gfs = {0}", locusSb.s_gfs);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fsize = {0}", locusSb.s_fsize);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_lwm = {0}", locusSb.s_lwm);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_hwm = {0}", locusSb.s_hwm);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_llst = {0}", locusSb.s_llst);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fstore = {0}", locusSb.s_fstore);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_time = {0}", locusSb.s_time);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_tfree = {0}", locusSb.s_tfree);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_isize = {0}", locusSb.s_isize);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_nfree = {0}", locusSb.s_nfree);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_flags = {0}", locusSb.s_flags);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_tinode = {0}", locusSb.s_tinode);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_lasti = {0}", locusSb.s_lasti);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_nbehind = {0}", locusSb.s_nbehind);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_gfspack = {0}", locusSb.s_gfspack);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_ninode = {0}", locusSb.s_ninode);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_flock = {0}", locusSb.s_flock);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_ilock = {0}", locusSb.s_ilock);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fmod = {0}", locusSb.s_fmod);
            AaruConsole.DebugWriteLine("Locus plugin", "LocusSb.s_version = {0}", locusSb.s_version);

            sb.AppendFormat("Superblock last modified on {0}", DateHandlers.UnixToDateTime(locusSb.s_time)).
            AppendLine();

            sb.AppendFormat("Volume has {0} blocks of {1} bytes each (total {2} bytes)", locusSb.s_fsize, blockSize,
                            locusSb.s_fsize * blockSize).AppendLine();

            sb.AppendFormat("{0} blocks free ({1} bytes)", locusSb.s_tfree, locusSb.s_tfree * blockSize).AppendLine();
            sb.AppendFormat("I-node list uses {0} blocks", locusSb.s_isize).AppendLine();
            sb.AppendFormat("{0} free inodes", locusSb.s_tinode).AppendLine();
            sb.AppendFormat("Next free inode search will start at inode {0}", locusSb.s_lasti).AppendLine();

            sb.AppendFormat("There are an estimate of {0} free inodes before next search start", locusSb.s_nbehind).
            AppendLine();

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_RDONLY))
            {
                sb.AppendLine("Read-only volume");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_CLEAN))
            {
                sb.AppendLine("Clean volume");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_DIRTY))
            {
                sb.AppendLine("Dirty volume");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_RMV))
            {
                sb.AppendLine("Removable volume");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_PRIMPACK))
            {
                sb.AppendLine("This is the primary pack");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_REPLTYPE))
            {
                sb.AppendLine("Replicated volume");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_USER))
            {
                sb.AppendLine("User replicated volume");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_BACKBONE))
            {
                sb.AppendLine("Backbone volume");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_NFS))
            {
                sb.AppendLine("NFS volume");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_BYHAND))
            {
                sb.AppendLine("Volume inhibits automatic fsck");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_NOSUID))
            {
                sb.AppendLine("Set-uid/set-gid is disabled");
            }

            if (locusSb.s_flags.HasFlag(LocusFlags.SB_SYNCW))
            {
                sb.AppendLine("Volume uses synchronous writes");
            }

            sb.AppendFormat("Volume label: {0}", s_fsmnt).AppendLine();
            sb.AppendFormat("Physical volume name: {0}", s_fpack).AppendLine();
            sb.AppendFormat("Global File System number: {0}", locusSb.s_gfs).AppendLine();
            sb.AppendFormat("Global File System pack number {0}", locusSb.s_gfspack).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type = "Locus filesystem", ClusterSize = (uint)blockSize, Clusters = (ulong)locusSb.s_fsize,

                // Sometimes it uses one, or the other. Use the bigger
                VolumeName       = string.IsNullOrEmpty(s_fsmnt) ? s_fpack : s_fsmnt,
                ModificationDate = DateHandlers.UnixToDateTime(locusSb.s_time), ModificationDateSpecified = true,
                Dirty            = !locusSb.s_flags.HasFlag(LocusFlags.SB_CLEAN) ||
                                   locusSb.s_flags.HasFlag(LocusFlags.SB_DIRTY),
                FreeClusters = (ulong)locusSb.s_tfree, FreeClustersSpecified = true
            };
        }
Пример #16
0
        public void Open(string path)
        {
            string filename      = Path.GetFileName(path);
            string filenameNoExt = Path.GetFileNameWithoutExtension(path);
            string parentFolder  = Path.GetDirectoryName(path);

            parentFolder = parentFolder ?? "";

            if (filename is null ||
                filenameNoExt is null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            // Prepend data fork name with "R."
            string ProDosAppleDouble = Path.Combine(parentFolder, "R." + filename);

            // Prepend data fork name with '%'
            string UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename);

            // Change file extension to ADF
            string DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF");

            // Change file extension to adf
            string DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf");

            // Store AppleDouble header file in ".AppleDouble" folder with same name
            string NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", filename);

            // Store AppleDouble header file in "resource.frk" folder with same name
            string DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename);

            // Prepend data fork name with "._"
            string OSXAppleDouble = Path.Combine(parentFolder, "._" + filename);

            // Adds ".rsrc" extension
            string UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc");

            // Check AppleDouble created by A/UX in ProDOS filesystem
            if (File.Exists(ProDosAppleDouble))
            {
                var prodosStream = new FileStream(ProDosAppleDouble, FileMode.Open, FileAccess.Read);

                if (prodosStream.Length > 26)
                {
                    byte[] prodos_b = new byte[26];
                    prodosStream.Read(prodos_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(prodos_b);
                    prodosStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        headerPath = ProDosAppleDouble;
                    }
                }
            }

            // Check AppleDouble created by A/UX in UFS filesystem
            if (File.Exists(UNIXAppleDouble))
            {
                var unixStream = new FileStream(UNIXAppleDouble, FileMode.Open, FileAccess.Read);

                if (unixStream.Length > 26)
                {
                    byte[] unix_b = new byte[26];
                    unixStream.Read(unix_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(unix_b);
                    unixStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        headerPath = UNIXAppleDouble;
                    }
                }
            }

            // Check AppleDouble created by A/UX in FAT filesystem
            if (File.Exists(DOSAppleDouble))
            {
                var dosStream = new FileStream(DOSAppleDouble, FileMode.Open, FileAccess.Read);

                if (dosStream.Length > 26)
                {
                    byte[] dos_b = new byte[26];
                    dosStream.Read(dos_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dos_b);
                    dosStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        headerPath = DOSAppleDouble;
                    }
                }
            }

            // Check AppleDouble created by A/UX in case preserving FAT filesystem
            if (File.Exists(DOSAppleDoubleLower))
            {
                var doslStream = new FileStream(DOSAppleDoubleLower, FileMode.Open, FileAccess.Read);

                if (doslStream.Length > 26)
                {
                    byte[] dosl_b = new byte[26];
                    doslStream.Read(dosl_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dosl_b);
                    doslStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        headerPath = DOSAppleDoubleLower;
                    }
                }
            }

            // Check AppleDouble created by Netatalk
            if (File.Exists(NetatalkAppleDouble))
            {
                var netatalkStream = new FileStream(NetatalkAppleDouble, FileMode.Open, FileAccess.Read);

                if (netatalkStream.Length > 26)
                {
                    byte[] netatalk_b = new byte[26];
                    netatalkStream.Read(netatalk_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(netatalk_b);
                    netatalkStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        headerPath = NetatalkAppleDouble;
                    }
                }
            }

            // Check AppleDouble created by DAVE
            if (File.Exists(DAVEAppleDouble))
            {
                var daveStream = new FileStream(DAVEAppleDouble, FileMode.Open, FileAccess.Read);

                if (daveStream.Length > 26)
                {
                    byte[] dave_b = new byte[26];
                    daveStream.Read(dave_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dave_b);
                    daveStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        headerPath = DAVEAppleDouble;
                    }
                }
            }

            // Check AppleDouble created by Mac OS X
            if (File.Exists(OSXAppleDouble))
            {
                var osxStream = new FileStream(OSXAppleDouble, FileMode.Open, FileAccess.Read);

                if (osxStream.Length > 26)
                {
                    byte[] osx_b = new byte[26];
                    osxStream.Read(osx_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(osx_b);
                    osxStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        headerPath = OSXAppleDouble;
                    }
                }
            }

            // Check AppleDouble created by UnAr (from The Unarchiver)
            if (File.Exists(UnArAppleDouble))
            {
                var unarStream = new FileStream(UnArAppleDouble, FileMode.Open, FileAccess.Read);

                if (unarStream.Length > 26)
                {
                    byte[] unar_b = new byte[26];
                    unarStream.Read(unar_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(unar_b);
                    unarStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        headerPath = UnArAppleDouble;
                    }
                }
            }

            var fs = new FileStream(headerPath, FileMode.Open, FileAccess.Read);

            fs.Seek(0, SeekOrigin.Begin);

            byte[] hdr_b = new byte[26];
            fs.Read(hdr_b, 0, 26);
            header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(hdr_b);

            AppleDoubleEntry[] entries = new AppleDoubleEntry[header.entries];

            for (int i = 0; i < header.entries; i++)
            {
                byte[] entry = new byte[12];
                fs.Read(entry, 0, 12);
                entries[i] = Marshal.ByteArrayToStructureBigEndian <AppleDoubleEntry>(entry);
            }

            creationTime  = DateTime.UtcNow;
            lastWriteTime = creationTime;

            foreach (AppleDoubleEntry entry in entries)
            {
                switch ((AppleDoubleEntryID)entry.id)
                {
                case AppleDoubleEntryID.DataFork:
                    // AppleDouble have datafork in separated file
                    break;

                case AppleDoubleEntryID.FileDates:
                    fs.Seek(entry.offset, SeekOrigin.Begin);
                    byte[] dates_b = new byte[16];
                    fs.Read(dates_b, 0, 16);

                    AppleDoubleFileDates dates =
                        Marshal.ByteArrayToStructureBigEndian <AppleDoubleFileDates>(dates_b);

                    creationTime  = DateHandlers.UnixUnsignedToDateTime(dates.creationDate);
                    lastWriteTime = DateHandlers.UnixUnsignedToDateTime(dates.modificationDate);

                    break;

                case AppleDoubleEntryID.FileInfo:
                    fs.Seek(entry.offset, SeekOrigin.Begin);
                    byte[] finfo = new byte[entry.length];
                    fs.Read(finfo, 0, finfo.Length);

                    if (MacintoshHome.SequenceEqual(header.homeFilesystem))
                    {
                        AppleDoubleMacFileInfo macinfo =
                            Marshal.ByteArrayToStructureBigEndian <AppleDoubleMacFileInfo>(finfo);

                        creationTime  = DateHandlers.MacToDateTime(macinfo.creationDate);
                        lastWriteTime = DateHandlers.MacToDateTime(macinfo.modificationDate);
                    }
                    else if (ProDOSHome.SequenceEqual(header.homeFilesystem))
                    {
                        AppleDoubleProDOSFileInfo prodosinfo =
                            Marshal.ByteArrayToStructureBigEndian <AppleDoubleProDOSFileInfo>(finfo);

                        creationTime  = DateHandlers.MacToDateTime(prodosinfo.creationDate);
                        lastWriteTime = DateHandlers.MacToDateTime(prodosinfo.modificationDate);
                    }
                    else if (UNIXHome.SequenceEqual(header.homeFilesystem))
                    {
                        AppleDoubleUNIXFileInfo unixinfo =
                            Marshal.ByteArrayToStructureBigEndian <AppleDoubleUNIXFileInfo>(finfo);

                        creationTime  = DateHandlers.UnixUnsignedToDateTime(unixinfo.creationDate);
                        lastWriteTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.modificationDate);
                    }
                    else if (DOSHome.SequenceEqual(header.homeFilesystem))
                    {
                        AppleDoubleDOSFileInfo dosinfo =
                            Marshal.ByteArrayToStructureBigEndian <AppleDoubleDOSFileInfo>(finfo);

                        lastWriteTime =
                            DateHandlers.DosToDateTime(dosinfo.modificationDate, dosinfo.modificationTime);
                    }

                    break;

                case AppleDoubleEntryID.ResourceFork:
                    rsrcFork = entry;

                    break;
                }
            }

            dataFork = new AppleDoubleEntry
            {
                id = (uint)AppleDoubleEntryID.DataFork
            };

            if (File.Exists(path))
            {
                var dataFs = new FileStream(path, FileMode.Open, FileAccess.Read);
                dataFork.length = (uint)dataFs.Length;
                dataFs.Close();
            }

            fs.Close();
            opened   = true;
            basePath = path;
        }
Пример #17
0
        public bool Identify(string path)
        {
            string filename      = Path.GetFileName(path);
            string filenameNoExt = Path.GetFileNameWithoutExtension(path);
            string parentFolder  = Path.GetDirectoryName(path);

            parentFolder = parentFolder ?? "";

            if (filename is null ||
                filenameNoExt is null)
            {
                return(false);
            }

            // Prepend data fork name with "R."
            string ProDosAppleDouble = Path.Combine(parentFolder, "R." + filename);

            // Prepend data fork name with '%'
            string UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename);

            // Change file extension to ADF
            string DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF");

            // Change file extension to adf
            string DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf");

            // Store AppleDouble header file in ".AppleDouble" folder with same name
            string NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", filename);

            // Store AppleDouble header file in "resource.frk" folder with same name
            string DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename);

            // Prepend data fork name with "._"
            string OSXAppleDouble = Path.Combine(parentFolder, "._" + filename);

            // Adds ".rsrc" extension
            string UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc");

            // Check AppleDouble created by A/UX in ProDOS filesystem
            if (File.Exists(ProDosAppleDouble))
            {
                var prodosStream = new FileStream(ProDosAppleDouble, FileMode.Open, FileAccess.Read);

                if (prodosStream.Length > 26)
                {
                    byte[] prodos_b = new byte[26];
                    prodosStream.Read(prodos_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(prodos_b);
                    prodosStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        return(true);
                    }
                }
            }

            // Check AppleDouble created by A/UX in UFS filesystem
            if (File.Exists(UNIXAppleDouble))
            {
                var unixStream = new FileStream(UNIXAppleDouble, FileMode.Open, FileAccess.Read);

                if (unixStream.Length > 26)
                {
                    byte[] unix_b = new byte[26];
                    unixStream.Read(unix_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(unix_b);
                    unixStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        return(true);
                    }
                }
            }

            // Check AppleDouble created by A/UX in FAT filesystem
            if (File.Exists(DOSAppleDouble))
            {
                var dosStream = new FileStream(DOSAppleDouble, FileMode.Open, FileAccess.Read);

                if (dosStream.Length > 26)
                {
                    byte[] dos_b = new byte[26];
                    dosStream.Read(dos_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dos_b);
                    dosStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        return(true);
                    }
                }
            }

            // Check AppleDouble created by A/UX in case preserving FAT filesystem
            if (File.Exists(DOSAppleDoubleLower))
            {
                var doslStream = new FileStream(DOSAppleDoubleLower, FileMode.Open, FileAccess.Read);

                if (doslStream.Length > 26)
                {
                    byte[] dosl_b = new byte[26];
                    doslStream.Read(dosl_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dosl_b);
                    doslStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        return(true);
                    }
                }
            }

            // Check AppleDouble created by Netatalk
            if (File.Exists(NetatalkAppleDouble))
            {
                var netatalkStream = new FileStream(NetatalkAppleDouble, FileMode.Open, FileAccess.Read);

                if (netatalkStream.Length > 26)
                {
                    byte[] netatalk_b = new byte[26];
                    netatalkStream.Read(netatalk_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(netatalk_b);
                    netatalkStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        return(true);
                    }
                }
            }

            // Check AppleDouble created by DAVE
            if (File.Exists(DAVEAppleDouble))
            {
                var daveStream = new FileStream(DAVEAppleDouble, FileMode.Open, FileAccess.Read);

                if (daveStream.Length > 26)
                {
                    byte[] dave_b = new byte[26];
                    daveStream.Read(dave_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dave_b);
                    daveStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        return(true);
                    }
                }
            }

            // Check AppleDouble created by Mac OS X
            if (File.Exists(OSXAppleDouble))
            {
                var osxStream = new FileStream(OSXAppleDouble, FileMode.Open, FileAccess.Read);

                if (osxStream.Length > 26)
                {
                    byte[] osx_b = new byte[26];
                    osxStream.Read(osx_b, 0, 26);
                    header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(osx_b);
                    osxStream.Close();

                    if (header.magic == AppleDoubleMagic &&
                        (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2))
                    {
                        return(true);
                    }
                }
            }

            // Check AppleDouble created by UnAr (from The Unarchiver)
            if (!File.Exists(UnArAppleDouble))
            {
                return(false);
            }

            var unarStream = new FileStream(UnArAppleDouble, FileMode.Open, FileAccess.Read);

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

            byte[] unar_b = new byte[26];
            unarStream.Read(unar_b, 0, 26);
            header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(unar_b);
            unarStream.Close();

            return(header.magic == AppleDoubleMagic &&
                   (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2));
        }
Пример #18
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

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

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

            SGILabel dvh = Marshal.ByteArrayToStructureBigEndian <SGILabel>(sector);

            for (int i = 0; i < dvh.volume.Length; i++)
            {
                dvh.volume[i] = (SGIVolume)Marshal.SwapStructureMembersEndian(dvh.volume[i]);
            }

            for (int i = 0; i < dvh.partitions.Length; i++)
            {
                dvh.partitions[i] = (SGIPartition)Marshal.SwapStructureMembersEndian(dvh.partitions[i]);
            }

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.magic = 0x{0:X8} (should be 0x{1:X8})", dvh.magic,
                                       SGI_MAGIC);

            if (dvh.magic != SGI_MAGIC)
            {
                return(false);
            }

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.root_part_num = {0}", dvh.root_part_num);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.swap_part_num = {0}", dvh.swap_part_num);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.boot_file = \"{0}\"",
                                       StringHandlers.CToString(dvh.boot_file));

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_skew = {0}", dvh.device_params.dp_skew);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_gap1 = {0}", dvh.device_params.dp_gap1);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_gap2 = {0}", dvh.device_params.dp_gap2);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_spares_cyl = {0}",
                                       dvh.device_params.dp_spares_cyl);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_cyls = {0}", dvh.device_params.dp_cyls);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_shd0 = {0}", dvh.device_params.dp_shd0);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_trks0 = {0}", dvh.device_params.dp_trks0);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_ctq_depth = {0}",
                                       dvh.device_params.dp_ctq_depth);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_cylshi = {0}",
                                       dvh.device_params.dp_cylshi);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_secs = {0}", dvh.device_params.dp_secs);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_secbytes = {0}",
                                       dvh.device_params.dp_secbytes);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_interleave = {0}",
                                       dvh.device_params.dp_interleave);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_flags = {0}", dvh.device_params.dp_flags);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_datarate = {0}",
                                       dvh.device_params.dp_datarate);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_nretries = {0}",
                                       dvh.device_params.dp_nretries);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_mspw = {0}", dvh.device_params.dp_mspw);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xgap1 = {0}", dvh.device_params.dp_xgap1);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xsync = {0}", dvh.device_params.dp_xsync);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xrdly = {0}", dvh.device_params.dp_xrdly);
            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xgap2 = {0}", dvh.device_params.dp_xgap2);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xrgate = {0}",
                                       dvh.device_params.dp_xrgate);

            AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.device_params.dp_xwcont = {0}",
                                       dvh.device_params.dp_xwcont);

            ulong counter = 0;

            for (int i = 0; i < dvh.partitions.Length; i++)
            {
                AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.partitions[{0}].num_blocks = {1}", i,
                                           dvh.partitions[i].num_blocks);

                AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.partitions[{0}].first_block = {1}", i,
                                           dvh.partitions[i].first_block);

                // TODO: Solve big endian marshal with enumerations
                dvh.partitions[i].type = (SGIType)Swapping.Swap((uint)dvh.partitions[i].type);
                AaruConsole.DebugWriteLine("SGIVH plugin", "dvh.partitions[{0}].type = {1}", i, dvh.partitions[i].type);

                var part = new Partition
                {
                    Start = (dvh.partitions[i].first_block * dvh.device_params.dp_secbytes) /
                            imagePlugin.Info.SectorSize,
                    Offset = dvh.partitions[i].first_block * dvh.device_params.dp_secbytes,
                    Length = (dvh.partitions[i].num_blocks * dvh.device_params.dp_secbytes) /
                             imagePlugin.Info.SectorSize,
                    Size = dvh.partitions[i].num_blocks * dvh.device_params.dp_secbytes,
                    Type = TypeToString(dvh.partitions[i].type), Sequence = counter, Scheme = Name
                };

                if (part.Size <= 0 ||
                    dvh.partitions[i].type == SGIType.Header ||
                    dvh.partitions[i].type == SGIType.Volume)
                {
                    continue;
                }

                partitions.Add(part);
                counter++;
            }

            return(true);
        }
Пример #19
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;
            }

            uint sbSize = (uint)(Marshal.SizeOf <s_spcl>() / imagePlugin.Info.SectorSize);

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

            byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);

            if (sector.Length < Marshal.SizeOf <s_spcl>())
            {
                return;
            }

            spcl16   oldHdr = Marshal.ByteArrayToStructureLittleEndian <spcl16>(sector);
            spcl_aix aixHdr = Marshal.ByteArrayToStructureLittleEndian <spcl_aix>(sector);
            s_spcl   newHdr = Marshal.ByteArrayToStructureLittleEndian <s_spcl>(sector);

            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 = Marshal.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 = Marshal.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;
            }

            var sb = new StringBuilder();

            XmlFsType = new FileSystemType
            {
                ClusterSize = 1024, Clusters = 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();
        }
Пример #20
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            if (imagePlugin.Info.SectorSize < 512)
            {
                return;
            }

            var xfsSb = new XFS_Superblock();

            // Misaligned
            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
            {
                uint sbSize = (uint)((Marshal.SizeOf <XFS_Superblock>() + 0x400) / imagePlugin.Info.SectorSize);

                if ((Marshal.SizeOf <XFS_Superblock>() + 0x400) % imagePlugin.Info.SectorSize != 0)
                {
                    sbSize++;
                }

                byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);

                if (sector.Length < Marshal.SizeOf <XFS_Superblock>())
                {
                    return;
                }

                byte[] sbpiece = new byte[Marshal.SizeOf <XFS_Superblock>()];

                foreach (int location in new[]
                {
                    0, 0x200, 0x400
                })
                {
                    Array.Copy(sector, location, sbpiece, 0, Marshal.SizeOf <XFS_Superblock>());

                    xfsSb = Marshal.ByteArrayToStructureBigEndian <XFS_Superblock>(sbpiece);

                    AaruConsole.DebugWriteLine("XFS plugin", "magic at 0x{0:X3} = 0x{1:X8} (expected 0x{2:X8})",
                                               location, xfsSb.magicnum, XFS_MAGIC);

                    if (xfsSb.magicnum == XFS_MAGIC)
                    {
                        break;
                    }
                }
            }
            else
            {
                foreach (int i in new[]
                {
                    0, 1, 2
                })
                {
                    ulong location = (ulong)i;
                    uint  sbSize   = (uint)(Marshal.SizeOf <XFS_Superblock>() / imagePlugin.Info.SectorSize);

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

                    byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize);

                    if (sector.Length < Marshal.SizeOf <XFS_Superblock>())
                    {
                        return;
                    }

                    xfsSb = Marshal.ByteArrayToStructureBigEndian <XFS_Superblock>(sector);

                    AaruConsole.DebugWriteLine("XFS plugin", "magic at {0} = 0x{1:X8} (expected 0x{2:X8})", location,
                                               xfsSb.magicnum, XFS_MAGIC);

                    if (xfsSb.magicnum == XFS_MAGIC)
                    {
                        break;
                    }
                }
            }

            if (xfsSb.magicnum != XFS_MAGIC)
            {
                return;
            }

            var sb = new StringBuilder();

            sb.AppendLine("XFS filesystem");
            sb.AppendFormat("Filesystem version {0}", xfsSb.version & 0xF).AppendLine();
            sb.AppendFormat("{0} bytes per sector", xfsSb.sectsize).AppendLine();
            sb.AppendFormat("{0} bytes per block", xfsSb.blocksize).AppendLine();
            sb.AppendFormat("{0} bytes per inode", xfsSb.inodesize).AppendLine();
            sb.AppendFormat("{0} data blocks in volume, {1} free", xfsSb.dblocks, xfsSb.fdblocks).AppendLine();
            sb.AppendFormat("{0} blocks per allocation group", xfsSb.agblocks).AppendLine();
            sb.AppendFormat("{0} allocation groups in volume", xfsSb.agcount).AppendLine();
            sb.AppendFormat("{0} inodes in volume, {1} free", xfsSb.icount, xfsSb.ifree).AppendLine();

            if (xfsSb.inprogress > 0)
            {
                sb.AppendLine("fsck in progress");
            }

            sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(xfsSb.fname, Encoding)).AppendLine();
            sb.AppendFormat("Volume UUID: {0}", xfsSb.uuid).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type           = "XFS filesystem", ClusterSize = xfsSb.blocksize,
                Clusters       = xfsSb.dblocks,
                FreeClusters   = xfsSb.fdblocks, FreeClustersSpecified = true,
                Files          = xfsSb.icount - xfsSb.ifree,
                FilesSpecified = true, Dirty = xfsSb.inprogress > 0,
                VolumeName     = StringHandlers.CToString(xfsSb.fname, Encoding), VolumeSerial = xfsSb.uuid.ToString()
            };
        }
Пример #21
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";
            var 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);

            UFSSuperBlock ufs_sb = Marshal.ByteArrayToStructureLittleEndian <UFSSuperBlock>(ufs_sb_sectors);

            UFSSuperBlock bs_sfu = Marshal.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]);
            }

            AaruConsole.DebugWriteLine("FFS plugin", "ufs_sb offset: 0x{0:X8}", sb_offset);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_rlink: 0x{0:X8}", ufs_sb.fs_rlink);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_sblkno: 0x{0:X8}", ufs_sb.fs_sblkno);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_cblkno: 0x{0:X8}", ufs_sb.fs_cblkno);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_iblkno: 0x{0:X8}", ufs_sb.fs_iblkno);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_dblkno: 0x{0:X8}", ufs_sb.fs_dblkno);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_size: 0x{0:X8}", ufs_sb.fs_size);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_dsize: 0x{0:X8}", ufs_sb.fs_dsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_ncg: 0x{0:X8}", ufs_sb.fs_ncg);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_bsize: 0x{0:X8}", ufs_sb.fs_bsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fsize: 0x{0:X8}", ufs_sb.fs_fsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_frag: 0x{0:X8}", ufs_sb.fs_frag);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_minfree: 0x{0:X8}", ufs_sb.fs_minfree);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_maxcontig: 0x{0:X8}", ufs_sb.fs_maxcontig);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_maxbpg: 0x{0:X8}", ufs_sb.fs_maxbpg);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fragshift: 0x{0:X8}", ufs_sb.fs_fragshift);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fsbtodb: 0x{0:X8}", ufs_sb.fs_fsbtodb);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_sbsize: 0x{0:X8}", ufs_sb.fs_sbsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_csmask: 0x{0:X8}", ufs_sb.fs_csmask);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_csshift: 0x{0:X8}", ufs_sb.fs_csshift);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_nindir: 0x{0:X8}", ufs_sb.fs_nindir);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_inopb: 0x{0:X8}", ufs_sb.fs_inopb);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_optim: 0x{0:X8}", ufs_sb.fs_optim);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_id_1: 0x{0:X8}", ufs_sb.fs_id_1);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_id_2: 0x{0:X8}", ufs_sb.fs_id_2);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_csaddr: 0x{0:X8}", ufs_sb.fs_csaddr);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_cssize: 0x{0:X8}", ufs_sb.fs_cssize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_cgsize: 0x{0:X8}", ufs_sb.fs_cgsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_ipg: 0x{0:X8}", ufs_sb.fs_ipg);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fpg: 0x{0:X8}", ufs_sb.fs_fpg);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fmod: 0x{0:X2}", ufs_sb.fs_fmod);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_clean: 0x{0:X2}", ufs_sb.fs_clean);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_ronly: 0x{0:X2}", ufs_sb.fs_ronly);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_flags: 0x{0:X2}", ufs_sb.fs_flags);
            AaruConsole.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    = (ulong)ufs_sb.fs_old_size;
            XmlFsType.ClusterSize = (uint)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          = (ulong)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          = (ulong)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 = (ulong)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();
        }
Пример #22
0
        public void Open(string path)
        {
            var fs = new FileStream(path, FileMode.Open, FileAccess.Read);

            fs.Seek(0, SeekOrigin.Begin);

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

            AppleSingleEntry[] entries = new AppleSingleEntry[header.entries];

            for (int i = 0; i < header.entries; i++)
            {
                byte[] entry = new byte[12];
                fs.Read(entry, 0, 12);
                entries[i] = Marshal.ByteArrayToStructureBigEndian <AppleSingleEntry>(entry);
            }

            creationTime  = DateTime.UtcNow;
            lastWriteTime = creationTime;

            foreach (AppleSingleEntry entry in entries)
            {
                switch ((AppleSingleEntryID)entry.id)
                {
                case AppleSingleEntryID.DataFork:
                    dataFork = entry;

                    break;

                case AppleSingleEntryID.FileDates:
                    fs.Seek(entry.offset, SeekOrigin.Begin);
                    byte[] dates_b = new byte[16];
                    fs.Read(dates_b, 0, 16);

                    AppleSingleFileDates dates =
                        Marshal.ByteArrayToStructureBigEndian <AppleSingleFileDates>(dates_b);

                    creationTime  = DateHandlers.MacToDateTime(dates.creationDate);
                    lastWriteTime = DateHandlers.MacToDateTime(dates.modificationDate);

                    break;

                case AppleSingleEntryID.FileInfo:
                    fs.Seek(entry.offset, SeekOrigin.Begin);
                    byte[] finfo = new byte[entry.length];
                    fs.Read(finfo, 0, finfo.Length);

                    if (MacintoshHome.SequenceEqual(header.homeFilesystem))
                    {
                        AppleSingleMacFileInfo macinfo =
                            Marshal.ByteArrayToStructureBigEndian <AppleSingleMacFileInfo>(finfo);

                        creationTime  = DateHandlers.MacToDateTime(macinfo.creationDate);
                        lastWriteTime = DateHandlers.MacToDateTime(macinfo.modificationDate);
                    }
                    else if (ProDOSHome.SequenceEqual(header.homeFilesystem))
                    {
                        AppleSingleProDOSFileInfo prodosinfo =
                            Marshal.ByteArrayToStructureBigEndian <AppleSingleProDOSFileInfo>(finfo);

                        creationTime  = DateHandlers.MacToDateTime(prodosinfo.creationDate);
                        lastWriteTime = DateHandlers.MacToDateTime(prodosinfo.modificationDate);
                    }
                    else if (UNIXHome.SequenceEqual(header.homeFilesystem))
                    {
                        AppleSingleUNIXFileInfo unixinfo =
                            Marshal.ByteArrayToStructureBigEndian <AppleSingleUNIXFileInfo>(finfo);

                        creationTime  = DateHandlers.UnixUnsignedToDateTime(unixinfo.creationDate);
                        lastWriteTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.modificationDate);
                    }
                    else if (DOSHome.SequenceEqual(header.homeFilesystem))
                    {
                        AppleSingleDOSFileInfo dosinfo =
                            Marshal.ByteArrayToStructureBigEndian <AppleSingleDOSFileInfo>(finfo);

                        lastWriteTime =
                            DateHandlers.DosToDateTime(dosinfo.modificationDate, dosinfo.modificationTime);
                    }

                    break;

                case AppleSingleEntryID.ResourceFork:
                    rsrcFork = entry;

                    break;
                }
            }

            fs.Close();
            opened   = true;
            isPath   = true;
            basePath = path;
        }
Пример #23
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            var sb = new StringBuilder();

            var besb = new BeSuperBlock();

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

            bool littleEndian;

            besb.magic1 = BigEndianBitConverter.ToUInt32(sbSector, 0x20);

            if (besb.magic1 == BEFS_MAGIC1 ||
                besb.magic1 == BEFS_CIGAM1) // Magic is at offset
            {
                littleEndian = besb.magic1 == BEFS_CIGAM1;
            }
            else
            {
                sbSector    = imagePlugin.ReadSector(1 + partition.Start);
                besb.magic1 = BigEndianBitConverter.ToUInt32(sbSector, 0x20);

                if (besb.magic1 == BEFS_MAGIC1 ||
                    besb.magic1 == BEFS_CIGAM1) // There is a boot sector
                {
                    littleEndian = besb.magic1 == BEFS_CIGAM1;
                }
                else if (sbSector.Length >= 0x400)
                {
                    byte[] temp = imagePlugin.ReadSector(0 + partition.Start);
                    besb.magic1 = BigEndianBitConverter.ToUInt32(temp, 0x220);

                    if (besb.magic1 == BEFS_MAGIC1 ||
                        besb.magic1 == BEFS_CIGAM1) // There is a boot sector
                    {
                        littleEndian = besb.magic1 == BEFS_CIGAM1;
                        sbSector     = new byte[0x200];
                        Array.Copy(temp, 0x200, sbSector, 0, 0x200);
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    return;
                }
            }

            if (littleEndian)
            {
                besb = Marshal.ByteArrayToStructureLittleEndian <BeSuperBlock>(sbSector);
            }
            else
            {
                besb = Marshal.ByteArrayToStructureBigEndian <BeSuperBlock>(sbSector);
            }

            sb.AppendLine(littleEndian ? "Little-endian BeFS" : "Big-endian BeFS");

            if (besb.magic1 != BEFS_MAGIC1 ||
                besb.fs_byte_order != BEFS_ENDIAN ||
                besb.magic2 != BEFS_MAGIC2 ||
                besb.magic3 != BEFS_MAGIC3 ||
                besb.root_dir_len != 1 ||
                besb.indices_len != 1 ||
                1 << (int)besb.block_shift != besb.block_size)
            {
                sb.AppendLine("Superblock seems corrupt, following information may be incorrect");
                sb.AppendFormat("Magic 1: 0x{0:X8} (Should be 0x42465331)", besb.magic1).AppendLine();
                sb.AppendFormat("Magic 2: 0x{0:X8} (Should be 0xDD121031)", besb.magic2).AppendLine();
                sb.AppendFormat("Magic 3: 0x{0:X8} (Should be 0x15B6830E)", besb.magic3).AppendLine();

                sb.AppendFormat("Filesystem endianness: 0x{0:X8} (Should be 0x42494745)", besb.fs_byte_order).
                AppendLine();

                sb.AppendFormat("Root folder's i-node size: {0} blocks (Should be 1)", besb.root_dir_len).AppendLine();
                sb.AppendFormat("Indices' i-node size: {0} blocks (Should be 1)", besb.indices_len).AppendLine();

                sb.AppendFormat("1 << block_shift == block_size => 1 << {0} == {1} (Should be {2})", besb.block_shift,
                                1 << (int)besb.block_shift, besb.block_size).AppendLine();
            }

            switch (besb.flags)
            {
            case BEFS_CLEAN:
                sb.AppendLine(besb.log_start == besb.log_end ? "Filesystem is clean" : "Filesystem is dirty");

                break;

            case BEFS_DIRTY:
                sb.AppendLine("Filesystem is dirty");

                break;

            default:
                sb.AppendFormat("Unknown flags: {0:X8}", besb.flags).AppendLine();

                break;
            }

            sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(besb.name, Encoding)).AppendLine();
            sb.AppendFormat("{0} bytes per block", besb.block_size).AppendLine();

            sb.AppendFormat("{0} blocks in volume ({1} bytes)", besb.num_blocks, besb.num_blocks * besb.block_size).
            AppendLine();

            sb.AppendFormat("{0} used blocks ({1} bytes)", besb.used_blocks, besb.used_blocks * besb.block_size).
            AppendLine();

            sb.AppendFormat("{0} bytes per i-node", besb.inode_size).AppendLine();

            sb.AppendFormat("{0} blocks per allocation group ({1} bytes)", besb.blocks_per_ag,
                            besb.blocks_per_ag * besb.block_size).AppendLine();

            sb.AppendFormat("{0} allocation groups in volume", besb.num_ags).AppendLine();

            sb.AppendFormat("Journal resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
                            besb.log_blocks_start, besb.log_blocks_ag, besb.log_blocks_len,
                            besb.log_blocks_len * besb.block_size).AppendLine();

            sb.AppendFormat("Journal starts in byte {0} and ends in byte {1}", besb.log_start, besb.log_end).
            AppendLine();

            sb.
            AppendFormat("Root folder's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
                         besb.root_dir_start, besb.root_dir_ag, besb.root_dir_len,
                         besb.root_dir_len * besb.block_size).AppendLine();

            sb.
            AppendFormat("Indices' i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
                         besb.indices_start, besb.indices_ag, besb.indices_len, besb.indices_len * besb.block_size).
            AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Clusters     = (ulong)besb.num_blocks, ClusterSize = besb.block_size,
                Dirty        = besb.flags == BEFS_DIRTY,
                FreeClusters = (ulong)(besb.num_blocks - besb.used_blocks), FreeClustersSpecified = true,
                Type         = "BeFS",
                VolumeName   = StringHandlers.CToString(besb.name, Encoding)
            };
        }
Пример #24
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
            byte[]    rootBlockSector = imagePlugin.ReadSector(2 + partition.Start);
            RootBlock rootBlock       = Marshal.ByteArrayToStructureBigEndian <RootBlock>(rootBlockSector);

            var sbInformation = new StringBuilder();

            XmlFsType = new FileSystemType();

            switch (rootBlock.diskType)
            {
            case AFS_DISK:
            case MUAF_DISK:
                sbInformation.Append("Professional File System v1");
                XmlFsType.Type = "PFS v1";

                break;

            case PFS2_DISK:
                sbInformation.Append("Professional File System v2");
                XmlFsType.Type = "PFS v2";

                break;

            case PFS_DISK:
            case MUPFS_DISK:
                sbInformation.Append("Professional File System v3");
                XmlFsType.Type = "PFS v3";

                break;
            }

            if (rootBlock.diskType == MUAF_DISK ||
                rootBlock.diskType == MUPFS_DISK)
            {
                sbInformation.Append(", with multi-user support");
            }

            sbInformation.AppendLine();

            sbInformation.AppendFormat("Volume name: {0}", StringHandlers.PascalToString(rootBlock.diskname, Encoding)).
            AppendLine();

            sbInformation.AppendFormat("Volume has {0} free sectors of {1}", rootBlock.blocksfree, rootBlock.diskSize).
            AppendLine();

            sbInformation.AppendFormat("Volume created on {0}",
                                       DateHandlers.AmigaToDateTime(rootBlock.creationday, rootBlock.creationminute,
                                                                    rootBlock.creationtick)).AppendLine();

            if (rootBlock.extension > 0)
            {
                sbInformation.AppendFormat("Root block extension resides at block {0}", rootBlock.extension).
                AppendLine();
            }

            information = sbInformation.ToString();

            XmlFsType.CreationDate =
                DateHandlers.AmigaToDateTime(rootBlock.creationday, rootBlock.creationminute, rootBlock.creationtick);

            XmlFsType.CreationDateSpecified = true;
            XmlFsType.FreeClusters          = rootBlock.blocksfree;
            XmlFsType.FreeClustersSpecified = true;
            XmlFsType.Clusters    = rootBlock.diskSize;
            XmlFsType.ClusterSize = imagePlugin.Info.SectorSize;
            XmlFsType.VolumeName  = StringHandlers.PascalToString(rootBlock.diskname, Encoding);
        }
Пример #25
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.UTF8;
            byte[] sector = imagePlugin.ReadSector(partition.Start);
            uint   magic  = BitConverter.ToUInt32(sector, 0x00);

            var  sqSb         = new SquashSuperBlock();
            bool littleEndian = true;

            switch (magic)
            {
            case SQUASH_MAGIC:
                sqSb = Marshal.ByteArrayToStructureLittleEndian <SquashSuperBlock>(sector);

                break;

            case SQUASH_CIGAM:
                sqSb         = Marshal.ByteArrayToStructureBigEndian <SquashSuperBlock>(sector);
                littleEndian = false;

                break;
            }

            var sbInformation = new StringBuilder();

            sbInformation.AppendLine("Squash file system");
            sbInformation.AppendLine(littleEndian ? "Little-endian" : "Big-endian");
            sbInformation.AppendFormat("Volume version {0}.{1}", sqSb.s_major, sqSb.s_minor).AppendLine();
            sbInformation.AppendFormat("Volume has {0} bytes", sqSb.bytes_used).AppendLine();
            sbInformation.AppendFormat("Volume has {0} bytes per block", sqSb.block_size).AppendLine();

            sbInformation.AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time)).
            AppendLine();

            sbInformation.AppendFormat("Volume has {0} inodes", sqSb.inodes).AppendLine();

            switch (sqSb.compression)
            {
            case (ushort)SquashCompression.Lz4:
                sbInformation.AppendLine("Volume is compressed using LZ4");

                break;

            case (ushort)SquashCompression.Lzo:
                sbInformation.AppendLine("Volume is compressed using LZO");

                break;

            case (ushort)SquashCompression.Lzma:
                sbInformation.AppendLine("Volume is compressed using LZMA");

                break;

            case (ushort)SquashCompression.Xz:
                sbInformation.AppendLine("Volume is compressed using XZ");

                break;

            case (ushort)SquashCompression.Zlib:
                sbInformation.AppendLine("Volume is compressed using GZIP");

                break;

            case (ushort)SquashCompression.Zstd:
                sbInformation.AppendLine("Volume is compressed using Zstandard");

                break;

            default:
                sbInformation.AppendFormat("Volume is compressed using unknown algorithm {0}", sqSb.compression).
                AppendLine();

                break;
            }

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                Type                  = "Squash file system",
                CreationDate          = DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time),
                CreationDateSpecified = true,
                Clusters              = (((partition.End - partition.Start) + 1) * imagePlugin.Info.SectorSize) /
                                        sqSb.block_size,
                ClusterSize           = sqSb.block_size, Files = sqSb.inodes, FilesSpecified = true, FreeClusters = 0,
                FreeClustersSpecified = true
            };
        }
Пример #26
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;
            }

            uint sbSize = (uint)(Marshal.SizeOf <UNICOS_Superblock>() / imagePlugin.Info.SectorSize);

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

            byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);

            if (sector.Length < Marshal.SizeOf <UNICOS_Superblock>())
            {
                return;
            }

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

            if (unicosSb.s_magic != UNICOS_MAGIC)
            {
                return;
            }

            var sb = new StringBuilder();

            sb.AppendLine("UNICOS filesystem");

            if (unicosSb.s_secure == UNICOS_SECURE)
            {
                sb.AppendLine("Volume is secure");
            }

            sb.AppendFormat("Volume contains {0} partitions", unicosSb.s_npart).AppendLine();
            sb.AppendFormat("{0} bytes per sector", unicosSb.s_iounit).AppendLine();
            sb.AppendLine("4096 bytes per block");
            sb.AppendFormat("{0} data blocks in volume", unicosSb.s_fsize).AppendLine();
            sb.AppendFormat("Root resides on inode {0}", unicosSb.s_root).AppendLine();
            sb.AppendFormat("{0} inodes in volume", unicosSb.s_isize).AppendLine();
            sb.AppendFormat("Volume last updated on {0}", DateHandlers.UnixToDateTime(unicosSb.s_time)).AppendLine();

            if (unicosSb.s_error > 0)
            {
                sb.AppendFormat("Volume is dirty, error code = 0x{0:X16}", unicosSb.s_error).AppendLine();
            }

            sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(unicosSb.s_fname, Encoding)).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type             = "UNICOS filesystem", ClusterSize = 4096, Clusters = (ulong)unicosSb.s_fsize,
                VolumeName       = StringHandlers.CToString(unicosSb.s_fname, Encoding),
                ModificationDate = DateHandlers.UnixToDateTime(unicosSb.s_time), ModificationDateSpecified = true
            };

            XmlFsType.Dirty |= unicosSb.s_error > 0;
        }
Пример #27
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 512)
            {
                return(false);
            }

            // Misaligned
            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
            {
                uint sbSize = (uint)((Marshal.SizeOf <XFS_Superblock>() + 0x400) / imagePlugin.Info.SectorSize);

                if ((Marshal.SizeOf <XFS_Superblock>() + 0x400) % imagePlugin.Info.SectorSize != 0)
                {
                    sbSize++;
                }

                byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);

                if (sector.Length < Marshal.SizeOf <XFS_Superblock>())
                {
                    return(false);
                }

                byte[] sbpiece = new byte[Marshal.SizeOf <XFS_Superblock>()];

                foreach (int location in new[]
                {
                    0, 0x200, 0x400
                })
                {
                    Array.Copy(sector, location, sbpiece, 0, Marshal.SizeOf <XFS_Superblock>());

                    XFS_Superblock xfsSb = Marshal.ByteArrayToStructureBigEndian <XFS_Superblock>(sbpiece);

                    AaruConsole.DebugWriteLine("XFS plugin", "magic at 0x{0:X3} = 0x{1:X8} (expected 0x{2:X8})",
                                               location, xfsSb.magicnum, XFS_MAGIC);

                    if (xfsSb.magicnum == XFS_MAGIC)
                    {
                        return(true);
                    }
                }
            }
            else
            {
                foreach (int i in new[]
                {
                    0, 1, 2
                })
                {
                    ulong location = (ulong)i;

                    uint sbSize = (uint)(Marshal.SizeOf <XFS_Superblock>() / imagePlugin.Info.SectorSize);

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

                    byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize);

                    if (sector.Length < Marshal.SizeOf <XFS_Superblock>())
                    {
                        return(false);
                    }

                    XFS_Superblock xfsSb = Marshal.ByteArrayToStructureBigEndian <XFS_Superblock>(sector);

                    AaruConsole.DebugWriteLine("XFS plugin", "magic at {0} = 0x{1:X8} (expected 0x{2:X8})", location,
                                               xfsSb.magicnum, XFS_MAGIC);

                    if (xfsSb.magicnum == XFS_MAGIC)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #28
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
            var sbInformation = new StringBuilder();

            XmlFsType   = new FileSystemType();
            information = null;
            byte[] bootBlockSectors = imagePlugin.ReadSectors(0 + partition.Start, 2);

            BootBlock bootBlk = Marshal.ByteArrayToStructureBigEndian <BootBlock>(bootBlockSectors);

            bootBlk.bootCode = new byte[bootBlockSectors.Length - 12];
            Array.Copy(bootBlockSectors, 12, bootBlk.bootCode, 0, bootBlk.bootCode.Length);
            bootBlockSectors[4] = bootBlockSectors[5] = bootBlockSectors[6] = bootBlockSectors[7] = 0;
            uint bsum = AmigaBootChecksum(bootBlockSectors);

            ulong bRootPtr = 0;

            // If bootblock is correct, let's take its rootblock pointer
            if (bsum == bootBlk.checksum)
            {
                bRootPtr = bootBlk.root_ptr + partition.Start;
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "Bootblock points to {0} as Rootblock", bRootPtr);
            }

            ulong[] rootPtrs =
            {
                bRootPtr + partition.Start,                                            ((((partition.End - partition.Start) + 1) / 2) + partition.Start) - 2,
                ((((partition.End - partition.Start) + 1) / 2) + partition.Start) - 1,
                (((partition.End - partition.Start) + 1) / 2) +
                partition.Start,
                (((partition.End - partition.Start) + 1) / 2) + partition.Start + 4
            };

            var rootBlk = new RootBlock();

            byte[] rootBlockSector = null;

            bool rootFound = false;
            uint blockSize = 0;

            // So to handle even number of sectors
            foreach (ulong rootPtr in rootPtrs.Where(rootPtr => rootPtr < partition.End && rootPtr >= partition.Start))
            {
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "Searching for Rootblock in sector {0}", rootPtr);

                rootBlockSector = imagePlugin.ReadSector(rootPtr);

                rootBlk.type = BigEndianBitConverter.ToUInt32(rootBlockSector, 0x00);
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.type = {0}", rootBlk.type);

                if (rootBlk.type != TYPE_HEADER)
                {
                    continue;
                }

                rootBlk.hashTableSize = BigEndianBitConverter.ToUInt32(rootBlockSector, 0x0C);

                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.hashTableSize = {0}", rootBlk.hashTableSize);

                blockSize = (rootBlk.hashTableSize + 56) * 4;
                uint sectorsPerBlock = (uint)(blockSize / rootBlockSector.Length);

                AaruConsole.DebugWriteLine("AmigaDOS plugin", "blockSize = {0}", blockSize);
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "sectorsPerBlock = {0}", sectorsPerBlock);

                if (blockSize % rootBlockSector.Length > 0)
                {
                    sectorsPerBlock++;
                }

                if (rootPtr + sectorsPerBlock >= partition.End)
                {
                    continue;
                }

                rootBlockSector = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock);

                // Clear checksum on sector
                rootBlk.checksum    = BigEndianBitConverter.ToUInt32(rootBlockSector, 20);
                rootBlockSector[20] = rootBlockSector[21] = rootBlockSector[22] = rootBlockSector[23] = 0;
                uint rsum = AmigaChecksum(rootBlockSector);

                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.checksum = 0x{0:X8}", rootBlk.checksum);
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rsum = 0x{0:X8}", rsum);

                rootBlk.sec_type = BigEndianBitConverter.ToUInt32(rootBlockSector, rootBlockSector.Length - 4);
                AaruConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.sec_type = {0}", rootBlk.sec_type);

                if (rootBlk.sec_type != SUBTYPE_ROOT ||
                    rootBlk.checksum != rsum)
                {
                    continue;
                }

                rootBlockSector = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock);
                rootFound       = true;

                break;
            }

            if (!rootFound)
            {
                return;
            }

            rootBlk = MarshalRootBlock(rootBlockSector);

            string diskName = StringHandlers.PascalToString(rootBlk.diskName, Encoding);

            switch (bootBlk.diskType & 0xFF)
            {
            case 0:
                sbInformation.Append("Amiga Original File System");
                XmlFsType.Type = "Amiga OFS";

                break;

            case 1:
                sbInformation.Append("Amiga Fast File System");
                XmlFsType.Type = "Amiga FFS";

                break;

            case 2:
                sbInformation.Append("Amiga Original File System with international characters");
                XmlFsType.Type = "Amiga OFS";

                break;

            case 3:
                sbInformation.Append("Amiga Fast File System with international characters");
                XmlFsType.Type = "Amiga FFS";

                break;

            case 4:
                sbInformation.Append("Amiga Original File System with directory cache");
                XmlFsType.Type = "Amiga OFS";

                break;

            case 5:
                sbInformation.Append("Amiga Fast File System with directory cache");
                XmlFsType.Type = "Amiga FFS";

                break;

            case 6:
                sbInformation.Append("Amiga Original File System with long filenames");
                XmlFsType.Type = "Amiga OFS2";

                break;

            case 7:
                sbInformation.Append("Amiga Fast File System with long filenames");
                XmlFsType.Type = "Amiga FFS2";

                break;
            }

            if ((bootBlk.diskType & 0x6D754600) == 0x6D754600)
            {
                sbInformation.Append(", with multi-user patches");
            }

            sbInformation.AppendLine();

            sbInformation.AppendFormat("Volume name: {0}", diskName).AppendLine();

            if (bootBlk.checksum == bsum)
            {
                var sha1Ctx = new Sha1Context();
                sha1Ctx.Update(bootBlk.bootCode);
                sbInformation.AppendLine("Volume is bootable");
                sbInformation.AppendFormat("Boot code SHA1 is {0}", sha1Ctx.End()).AppendLine();
            }

            if (rootBlk.bitmapFlag == 0xFFFFFFFF)
            {
                sbInformation.AppendLine("Volume bitmap is valid");
            }

            if (rootBlk.bitmapExtensionBlock != 0x00000000 &&
                rootBlk.bitmapExtensionBlock != 0xFFFFFFFF)
            {
                sbInformation.AppendFormat("Bitmap extension at block {0}", rootBlk.bitmapExtensionBlock).AppendLine();
            }

            if ((bootBlk.diskType & 0xFF) == 4 ||
                (bootBlk.diskType & 0xFF) == 5)
            {
                sbInformation.AppendFormat("Directory cache starts at block {0}", rootBlk.extension).AppendLine();
            }

            ulong blocks = (((partition.End - partition.Start) + 1) * imagePlugin.Info.SectorSize) / blockSize;

            sbInformation.AppendFormat("Volume block size is {0} bytes", blockSize).AppendLine();
            sbInformation.AppendFormat("Volume has {0} blocks", blocks).AppendLine();

            sbInformation.AppendFormat("Volume created on {0}",
                                       DateHandlers.AmigaToDateTime(rootBlk.cDays, rootBlk.cMins, rootBlk.cTicks)).
            AppendLine();

            sbInformation.AppendFormat("Volume last modified on {0}",
                                       DateHandlers.AmigaToDateTime(rootBlk.vDays, rootBlk.vMins, rootBlk.vTicks)).
            AppendLine();

            sbInformation.AppendFormat("Volume root directory last modified on on {0}",
                                       DateHandlers.AmigaToDateTime(rootBlk.rDays, rootBlk.rMins, rootBlk.rTicks)).
            AppendLine();

            sbInformation.AppendFormat("Root block checksum is 0x{0:X8}", rootBlk.checksum).AppendLine();
            information = sbInformation.ToString();

            XmlFsType.CreationDate = DateHandlers.AmigaToDateTime(rootBlk.cDays, rootBlk.cMins, rootBlk.cTicks);

            XmlFsType.CreationDateSpecified = true;

            XmlFsType.ModificationDate = DateHandlers.AmigaToDateTime(rootBlk.vDays, rootBlk.vMins, rootBlk.vTicks);

            XmlFsType.ModificationDateSpecified = true;
            XmlFsType.Dirty       = rootBlk.bitmapFlag != 0xFFFFFFFF;
            XmlFsType.Clusters    = blocks;
            XmlFsType.ClusterSize = blockSize;
            XmlFsType.VolumeName  = diskName;
            XmlFsType.Bootable    = bsum == bootBlk.checksum;

            // Useful as a serial
            XmlFsType.VolumeSerial = $"{rootBlk.checksum:X8}";
        }
Пример #29
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            var sb = new StringBuilder();

            HammerSuperBlock hammerSb;

            uint run = HAMMER_VOLHDR_SIZE / imagePlugin.Info.SectorSize;

            if (HAMMER_VOLHDR_SIZE % imagePlugin.Info.SectorSize > 0)
            {
                run++;
            }

            byte[] sbSector = imagePlugin.ReadSectors(partition.Start, run);

            ulong magic = BitConverter.ToUInt64(sbSector, 0);

            if (magic == HAMMER_FSBUF_VOLUME)
            {
                hammerSb = Marshal.ByteArrayToStructureLittleEndian <HammerSuperBlock>(sbSector);
            }
            else
            {
                hammerSb = Marshal.ByteArrayToStructureBigEndian <HammerSuperBlock>(sbSector);
            }

            sb.AppendLine("HAMMER filesystem");

            sb.AppendFormat("Volume version: {0}", hammerSb.vol_version).AppendLine();

            sb.AppendFormat("Volume {0} of {1} on this filesystem", hammerSb.vol_no + 1, hammerSb.vol_count).
            AppendLine();

            sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(hammerSb.vol_label, Encoding)).AppendLine();
            sb.AppendFormat("Volume serial: {0}", hammerSb.vol_fsid).AppendLine();
            sb.AppendFormat("Filesystem type: {0}", hammerSb.vol_fstype).AppendLine();
            sb.AppendFormat("Boot area starts at {0}", hammerSb.vol_bot_beg).AppendLine();
            sb.AppendFormat("Memory log starts at {0}", hammerSb.vol_mem_beg).AppendLine();
            sb.AppendFormat("First volume buffer starts at {0}", hammerSb.vol_buf_beg).AppendLine();
            sb.AppendFormat("Volume ends at {0}", hammerSb.vol_buf_end).AppendLine();

            XmlFsType = new FileSystemType
            {
                Clusters     = partition.Size / HAMMER_BIGBLOCK_SIZE, ClusterSize = HAMMER_BIGBLOCK_SIZE, Dirty = false,
                Type         = "HAMMER",
                VolumeName   = StringHandlers.CToString(hammerSb.vol_label, Encoding),
                VolumeSerial = hammerSb.vol_fsid.ToString()
            };

            if (hammerSb.vol_no == hammerSb.vol_rootvol)
            {
                sb.AppendFormat("Filesystem contains {0} \"big-blocks\" ({1} bytes)", hammerSb.vol0_stat_bigblocks,
                                hammerSb.vol0_stat_bigblocks * HAMMER_BIGBLOCK_SIZE).AppendLine();

                sb.AppendFormat("Filesystem has {0} \"big-blocks\" free ({1} bytes)", hammerSb.vol0_stat_freebigblocks,
                                hammerSb.vol0_stat_freebigblocks * HAMMER_BIGBLOCK_SIZE).AppendLine();

                sb.AppendFormat("Filesystem has {0} inode used", hammerSb.vol0_stat_inodes).AppendLine();

                XmlFsType.Clusters              = (ulong)hammerSb.vol0_stat_bigblocks;
                XmlFsType.FreeClusters          = (ulong)hammerSb.vol0_stat_freebigblocks;
                XmlFsType.FreeClustersSpecified = true;
                XmlFsType.Files          = (ulong)hammerSb.vol0_stat_inodes;
                XmlFsType.FilesSpecified = true;
            }

            // 0 ?
            //sb.AppendFormat("Volume header CRC: 0x{0:X8}", afs_sb.vol_crc).AppendLine();

            information = sb.ToString();
        }
Пример #30
0
        public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
                           Dictionary <string, string> options, string @namespace)
        {
            Encoding     = Encoding.GetEncoding("iso-8859-15");
            littleEndian = true;

            if (options == null)
            {
                options = GetDefaultOptions();
            }

            if (options.TryGetValue("debug", out string debugString))
            {
                bool.TryParse(debugString, out debug);
            }

            if (imagePlugin.Info.SectorSize < 512)
            {
                return(Errno.InvalidArgument);
            }

            AaruConsole.DebugWriteLine("Xbox FAT plugin", "Reading superblock");

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

            superblock = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector);

            if (superblock.magic == FATX_CIGAM)
            {
                superblock   = Marshal.ByteArrayToStructureBigEndian <Superblock>(sector);
                littleEndian = false;
            }

            if (superblock.magic != FATX_MAGIC)
            {
                return(Errno.InvalidArgument);
            }

            AaruConsole.DebugWriteLine("Xbox FAT plugin",
                                       littleEndian ? "Filesystem is little endian" : "Filesystem is big endian");

            int logicalSectorsPerPhysicalSectors = partition.Offset == 0 && littleEndian ? 8 : 1;

            AaruConsole.DebugWriteLine("Xbox FAT plugin", "logicalSectorsPerPhysicalSectors = {0}",
                                       logicalSectorsPerPhysicalSectors);

            string volumeLabel = StringHandlers.CToString(superblock.volumeLabel,
                                                          !littleEndian ? Encoding.BigEndianUnicode : Encoding.Unicode,
                                                          true);

            XmlFsType = new FileSystemType
            {
                Type        = "FATX filesystem",
                ClusterSize = (uint)(superblock.sectorsPerCluster * logicalSectorsPerPhysicalSectors *
                                     imagePlugin.Info.SectorSize),
                VolumeName = volumeLabel, VolumeSerial = $"{superblock.id:X8}"
            };

            XmlFsType.Clusters = (((partition.End - partition.Start) + 1) * imagePlugin.Info.SectorSize) /
                                 XmlFsType.ClusterSize;

            statfs = new FileSystemInfo
            {
                Blocks    = XmlFsType.Clusters, FilenameLength = MAX_FILENAME,
                Files     = 0, // Requires traversing all directories
                FreeFiles = 0, Id =
                {
                    IsInt = true, Serial32 = superblock.magic
                },
                PluginId   = Id, Type = littleEndian ? "Xbox FAT" : "Xbox 360 FAT",
                FreeBlocks = 0 // Requires traversing the FAT
            };

            AaruConsole.DebugWriteLine("Xbox FAT plugin", "XmlFsType.ClusterSize: {0}", XmlFsType.ClusterSize);
            AaruConsole.DebugWriteLine("Xbox FAT plugin", "XmlFsType.VolumeName: {0}", XmlFsType.VolumeName);
            AaruConsole.DebugWriteLine("Xbox FAT plugin", "XmlFsType.VolumeSerial: {0}", XmlFsType.VolumeSerial);
            AaruConsole.DebugWriteLine("Xbox FAT plugin", "stat.Blocks: {0}", statfs.Blocks);
            AaruConsole.DebugWriteLine("Xbox FAT plugin", "stat.FilenameLength: {0}", statfs.FilenameLength);
            AaruConsole.DebugWriteLine("Xbox FAT plugin", "stat.Id: {0}", statfs.Id.Serial32);
            AaruConsole.DebugWriteLine("Xbox FAT plugin", "stat.Type: {0}", statfs.Type);

            byte[] buffer;
            fatStartSector = (FAT_START / imagePlugin.Info.SectorSize) + partition.Start;
            uint fatSize;

            AaruConsole.DebugWriteLine("Xbox FAT plugin", "fatStartSector: {0}", fatStartSector);

            if (statfs.Blocks > MAX_XFAT16_CLUSTERS)
            {
                AaruConsole.DebugWriteLine("Xbox FAT plugin", "Reading FAT32");

                fatSize = (uint)(((statfs.Blocks + 1) * sizeof(uint)) / imagePlugin.Info.SectorSize);

                if ((uint)(((statfs.Blocks + 1) * sizeof(uint)) % imagePlugin.Info.SectorSize) > 0)
                {
                    fatSize++;
                }

                long fatClusters = (fatSize * imagePlugin.Info.SectorSize) / 4096;

                if ((fatSize * imagePlugin.Info.SectorSize) % 4096 > 0)
                {
                    fatClusters++;
                }

                fatSize = (uint)((fatClusters * 4096) / imagePlugin.Info.SectorSize);

                AaruConsole.DebugWriteLine("Xbox FAT plugin", "FAT is {0} sectors", fatSize);

                buffer = imagePlugin.ReadSectors(fatStartSector, fatSize);

                AaruConsole.DebugWriteLine("Xbox FAT plugin", "Casting FAT");
                fat32 = MemoryMarshal.Cast <byte, uint>(buffer).ToArray();

                if (!littleEndian)
                {
                    for (int i = 0; i < fat32.Length; i++)
                    {
                        fat32[i] = Swapping.Swap(fat32[i]);
                    }
                }

                AaruConsole.DebugWriteLine("Xbox FAT plugin", "fat32[0] == FATX32_ID = {0}", fat32[0] == FATX32_ID);

                if (fat32[0] != FATX32_ID)
                {
                    return(Errno.InvalidArgument);
                }
            }
            else
            {
                AaruConsole.DebugWriteLine("Xbox FAT plugin", "Reading FAT16");

                fatSize = (uint)(((statfs.Blocks + 1) * sizeof(ushort)) / imagePlugin.Info.SectorSize);

                if ((uint)(((statfs.Blocks + 1) * sizeof(ushort)) % imagePlugin.Info.SectorSize) > 0)
                {
                    fatSize++;
                }

                long fatClusters = (fatSize * imagePlugin.Info.SectorSize) / 4096;

                if ((fatSize * imagePlugin.Info.SectorSize) % 4096 > 0)
                {
                    fatClusters++;
                }

                fatSize = (uint)((fatClusters * 4096) / imagePlugin.Info.SectorSize);

                AaruConsole.DebugWriteLine("Xbox FAT plugin", "FAT is {0} sectors", fatSize);

                buffer = imagePlugin.ReadSectors(fatStartSector, fatSize);

                AaruConsole.DebugWriteLine("Xbox FAT plugin", "Casting FAT");
                fat16 = MemoryMarshal.Cast <byte, ushort>(buffer).ToArray();

                if (!littleEndian)
                {
                    for (int i = 0; i < fat16.Length; i++)
                    {
                        fat16[i] = Swapping.Swap(fat16[i]);
                    }
                }

                AaruConsole.DebugWriteLine("Xbox FAT plugin", "fat16[0] == FATX16_ID = {0}", fat16[0] == FATX16_ID);

                if (fat16[0] != FATX16_ID)
                {
                    return(Errno.InvalidArgument);
                }
            }

            sectorsPerCluster  = (uint)(superblock.sectorsPerCluster * logicalSectorsPerPhysicalSectors);
            this.imagePlugin   = imagePlugin;
            firstClusterSector = fatStartSector + fatSize;
            bytesPerCluster    = sectorsPerCluster * imagePlugin.Info.SectorSize;

            AaruConsole.DebugWriteLine("Xbox FAT plugin", "sectorsPerCluster = {0}", sectorsPerCluster);
            AaruConsole.DebugWriteLine("Xbox FAT plugin", "bytesPerCluster = {0}", bytesPerCluster);
            AaruConsole.DebugWriteLine("Xbox FAT plugin", "firstClusterSector = {0}", firstClusterSector);

            uint[] rootDirectoryClusters = GetClusters(superblock.rootDirectoryCluster);

            if (rootDirectoryClusters is null)
            {
                return(Errno.InvalidArgument);
            }

            byte[] rootDirectoryBuffer = new byte[bytesPerCluster * rootDirectoryClusters.Length];

            AaruConsole.DebugWriteLine("Xbox FAT plugin", "Reading root directory");

            for (int i = 0; i < rootDirectoryClusters.Length; i++)
            {
                buffer =
                    imagePlugin.ReadSectors(firstClusterSector + ((rootDirectoryClusters[i] - 1) * sectorsPerCluster),
                                            sectorsPerCluster);

                Array.Copy(buffer, 0, rootDirectoryBuffer, i * bytesPerCluster, bytesPerCluster);
            }

            rootDirectory = new Dictionary <string, DirectoryEntry>();

            int pos = 0;

            while (pos < rootDirectoryBuffer.Length)
            {
                DirectoryEntry entry = littleEndian
                                           ? Marshal.
                                       ByteArrayToStructureLittleEndian <DirectoryEntry
                                                                         >(rootDirectoryBuffer, pos, Marshal.SizeOf <DirectoryEntry>())
                                           : Marshal.ByteArrayToStructureBigEndian <DirectoryEntry>(rootDirectoryBuffer,
                                                                                                    pos,
                                                                                                    Marshal.
                                                                                                    SizeOf <
                                                                                                        DirectoryEntry
                                                                                                        >());

                pos += Marshal.SizeOf <DirectoryEntry>();

                if (entry.filenameSize == UNUSED_DIRENTRY ||
                    entry.filenameSize == FINISHED_DIRENTRY)
                {
                    break;
                }

                if (entry.filenameSize == DELETED_DIRENTRY ||
                    entry.filenameSize > MAX_FILENAME)
                {
                    continue;
                }

                string filename = Encoding.GetString(entry.filename, 0, entry.filenameSize);

                rootDirectory.Add(filename, entry);
            }

            cultureInfo    = new CultureInfo("en-US", false);
            directoryCache = new Dictionary <string, Dictionary <string, DirectoryEntry> >();
            mounted        = true;

            return(Errno.NoError);
        }