Example #1
0
File: ReFS.cs Project: paulyc/Aaru
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            uint sbSize = (uint)(Marshal.SizeOf <VolumeHeader>() / imagePlugin.Info.SectorSize);

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

            if (partition.Start + sbSize >= partition.End)
            {
                return(false);
            }

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

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

            VolumeHeader vhdr = Marshal.ByteArrayToStructureLittleEndian <VolumeHeader>(sector);

            return(vhdr.identifier == FSRS && ArrayHelpers.ArrayIsNullOrEmpty(vhdr.mustBeZero) &&
                   vhdr.signature.SequenceEqual(_signature));
        }
Example #2
0
File: AODOS.cs Project: paulyc/Aaru
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = Encoding.GetEncoding("koi8-r");
            byte[]    sector = imagePlugin.ReadSector(0);
            BootBlock bb     = Marshal.ByteArrayToStructureLittleEndian <BootBlock>(sector);

            var sbInformation = new StringBuilder();

            sbInformation.AppendLine("Alexander Osipov DOS file system");

            XmlFsType = new FileSystemType
            {
                Type                  = "Alexander Osipov DOS file system",
                Clusters              = imagePlugin.Info.Sectors,
                ClusterSize           = imagePlugin.Info.SectorSize,
                Files                 = bb.files,
                FilesSpecified        = true,
                FreeClusters          = imagePlugin.Info.Sectors - bb.usedSectors,
                FreeClustersSpecified = true,
                VolumeName            = StringHandlers.SpacePaddedToString(bb.volumeLabel, Encoding),
                Bootable              = true
            };

            sbInformation.AppendFormat("{0} files on volume", bb.files).AppendLine();
            sbInformation.AppendFormat("{0} used sectors on volume", bb.usedSectors).AppendLine();

            sbInformation.AppendFormat("Disk name: {0}", StringHandlers.CToString(bb.volumeLabel, Encoding)).
            AppendLine();

            information = sbInformation.ToString();
        }
Example #3
0
File: AODOS.cs Project: paulyc/Aaru
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            // Does AO-DOS support hard disks?
            if (partition.Start > 0)
            {
                return(false);
            }

            // How is it really?
            if (imagePlugin.Info.SectorSize != 512)
            {
                return(false);
            }

            // Does AO-DOS support any other kind of disk?
            if (imagePlugin.Info.Sectors != 800 &&
                imagePlugin.Info.Sectors != 1600)
            {
                return(false);
            }

            byte[]    sector = imagePlugin.ReadSector(0);
            BootBlock bb     = Marshal.ByteArrayToStructureLittleEndian <BootBlock>(sector);

            return(bb.identifier.SequenceEqual(_identifier));
        }
Example #4
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 sbAddr = REISER4_SUPER_OFFSET / imagePlugin.Info.SectorSize;

            if (sbAddr == 0)
            {
                sbAddr = 1;
            }

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

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

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

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

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

            if (!_magic.SequenceEqual(reiserSb.magic))
            {
                return;
            }

            var sb = new StringBuilder();

            sb.AppendLine("Reiser 4 filesystem");
            sb.AppendFormat("{0} bytes per block", reiserSb.blocksize).AppendLine();
            sb.AppendFormat("Volume disk format: {0}", reiserSb.diskformat).AppendLine();
            sb.AppendFormat("Volume UUID: {0}", reiserSb.uuid).AppendLine();
            sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(reiserSb.label, Encoding)).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type         = "Reiser 4 filesystem",
                ClusterSize  = reiserSb.blocksize,
                Clusters     = ((partition.End - partition.Start) * imagePlugin.Info.SectorSize) / reiserSb.blocksize,
                VolumeName   = StringHandlers.CToString(reiserSb.label, Encoding),
                VolumeSerial = reiserSb.uuid.ToString()
            };
        }
Example #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();

            int  sbSizeInBytes   = Marshal.SizeOf <SuperBlock>();
            uint sbSizeInSectors = (uint)(sbSizeInBytes / imagePlugin.Info.SectorSize);

            if (sbSizeInBytes % imagePlugin.Info.SectorSize > 0)
            {
                sbSizeInSectors++;
            }

            byte[]     sbSector = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors);
            SuperBlock supblk   = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector);

            sb.AppendFormat("{0} bytes per zone", supblk.s_zone_size).AppendLine();

            sb.AppendFormat("{0} zones in volume ({1} bytes)", supblk.s_nzones, supblk.s_nzones * supblk.s_zone_size).
            AppendLine();

            sb.AppendFormat("{0} inodes", supblk.s_ninodes).AppendLine();

            sb.AppendFormat("{0} data zones ({1} bytes)", supblk.s_ndatazones,
                            supblk.s_ndatazones * supblk.s_zone_size).AppendLine();

            sb.AppendFormat("{0} imap zones ({1} bytes)", supblk.s_imap_zones,
                            supblk.s_imap_zones * supblk.s_zone_size).AppendLine();

            sb.AppendFormat("{0} zmap zones ({1} bytes)", supblk.s_zmap_zones,
                            supblk.s_zmap_zones * supblk.s_zone_size).AppendLine();

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

            sb.AppendFormat("Maximum filesize is {0} bytes ({1} MiB)", supblk.s_max_size, supblk.s_max_size / 1048576).
            AppendLine();

            sb.AppendFormat("{0} zones reserved for kernel images ({1} bytes)", supblk.s_kernzones,
                            supblk.s_kernzones * supblk.s_zone_size).AppendLine();

            sb.AppendFormat("First kernel zone: {0}", supblk.s_firstkernzone).AppendLine();

            XmlFsType = new FileSystemType
            {
                Bootable    = !ArrayHelpers.ArrayIsNullOrEmpty(supblk.s_boot_segment),
                Clusters    = supblk.s_nzones,
                ClusterSize = supblk.s_zone_size,
                Type        = "Xia filesystem"
            };

            information = sb.ToString();
        }
Example #6
0
File: VxFS.cs Project: paulyc/Aaru
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.UTF8;
            ulong vmfsSuperOff = VXFS_BASE / imagePlugin.Info.SectorSize;

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

            SuperBlock vxSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector);

            var sbInformation = new StringBuilder();

            sbInformation.AppendLine("Veritas file system");

            sbInformation.AppendFormat("Volume version {0}", vxSb.vs_version).AppendLine();

            sbInformation.AppendFormat("Volume name {0}", StringHandlers.CToString(vxSb.vs_fname, Encoding)).
            AppendLine();

            sbInformation.AppendFormat("Volume has {0} blocks of {1} bytes each", vxSb.vs_bsize, vxSb.vs_size).
            AppendLine();

            sbInformation.AppendFormat("Volume has {0} inodes per block", vxSb.vs_inopb).AppendLine();
            sbInformation.AppendFormat("Volume has {0} free inodes", vxSb.vs_ifree).AppendLine();
            sbInformation.AppendFormat("Volume has {0} free blocks", vxSb.vs_free).AppendLine();

            sbInformation.AppendFormat("Volume created on {0}",
                                       DateHandlers.UnixUnsignedToDateTime(vxSb.vs_ctime, vxSb.vs_cutime)).AppendLine();

            sbInformation.AppendFormat("Volume last modified on {0}",
                                       DateHandlers.UnixUnsignedToDateTime(vxSb.vs_wtime, vxSb.vs_wutime)).AppendLine();

            if (vxSb.vs_clean != 0)
            {
                sbInformation.AppendLine("Volume is dirty");
            }

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                Type                      = "Veritas file system",
                CreationDate              = DateHandlers.UnixUnsignedToDateTime(vxSb.vs_ctime, vxSb.vs_cutime),
                CreationDateSpecified     = true,
                ModificationDate          = DateHandlers.UnixUnsignedToDateTime(vxSb.vs_wtime, vxSb.vs_wutime),
                ModificationDateSpecified = true,
                Clusters                  = (ulong)vxSb.vs_size,
                ClusterSize               = (uint)vxSb.vs_bsize,
                Dirty                     = vxSb.vs_clean != 0,
                FreeClusters              = (ulong)vxSb.vs_free,
                FreeClustersSpecified     = true
            };
        }
Example #7
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = new Radix50();
            information = "";

            var sb = new StringBuilder();

            byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start);

            HomeBlock homeblock = Marshal.ByteArrayToStructureLittleEndian <HomeBlock>(hbSector);

            /* TODO: Is this correct?
             * Assembler:
             *      MOV address, R0
             *      CLR R1
             *      MOV #255., R2
             * 10$: ADD (R0)+, R1
             *      SOB R2, 10$
             *      MOV 1,@R0
             */
            ushort check = 0;

            for (int i = 0; i < 512; i += 2)
            {
                check += BitConverter.ToUInt16(hbSector, i);
            }

            sb.AppendFormat("Volume format is {0}",
                            StringHandlers.SpacePaddedToString(homeblock.format, Encoding.ASCII)).AppendLine();

            sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512).
            AppendLine();

            sb.AppendFormat("First directory segment starts at block {0}", homeblock.rootBlock).AppendLine();
            sb.AppendFormat("Volume owner is \"{0}\"", Encoding.GetString(homeblock.ownername).TrimEnd()).AppendLine();
            sb.AppendFormat("Volume label: \"{0}\"", Encoding.GetString(homeblock.volname).TrimEnd()).AppendLine();
            sb.AppendFormat("Checksum: 0x{0:X4} (calculated 0x{1:X4})", homeblock.checksum, check).AppendLine();

            byte[] bootBlock = imagePlugin.ReadSector(0);

            XmlFsType = new FileSystemType
            {
                Type        = "RT-11",
                ClusterSize = (uint)(homeblock.cluster * 512),
                Clusters    = homeblock.cluster,
                VolumeName  = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
                Bootable    = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlock)
            };

            information = sb.ToString();
        }
Example #8
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (partition.Start + 1 >= imagePlugin.Info.Sectors)
            {
                return(false);
            }

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

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

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

            // Check root directory name
            if (!_rootDirFname.SequenceEqual(qnxSb.rootDir.di_fname))
            {
                return(false);
            }

            // Check sizes are multiple of blocks
            if (qnxSb.rootDir.di_size % 512 != 0 ||
                qnxSb.inode.di_size % 512 != 0 ||
                qnxSb.boot.di_size % 512 != 0 ||
                qnxSb.altBoot.di_size % 512 != 0)
            {
                return(false);
            }

            // Check extents are not past device
            if (qnxSb.rootDir.di_first_xtnt.block + partition.Start >= partition.End ||
                qnxSb.inode.di_first_xtnt.block + partition.Start >= partition.End ||
                qnxSb.boot.di_first_xtnt.block + partition.Start >= partition.End ||
                qnxSb.altBoot.di_first_xtnt.block + partition.Start >= partition.End)
            {
                return(false);
            }

            // Check inodes are in use
            if ((qnxSb.rootDir.di_status & 0x01) != 0x01 ||
                (qnxSb.inode.di_status & 0x01) != 0x01 ||
                (qnxSb.boot.di_status & 0x01) != 0x01)
            {
                return(false);
            }

            // All hail filesystems without identification marks
            return(true);
        }
Example #9
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (partition.Start > 0)
            {
                return(false);
            }

            if (imagePlugin.Info.SectorSize != 256)
            {
                return(false);
            }

            if (imagePlugin.Info.Sectors != 683 &&
                imagePlugin.Info.Sectors != 768 &&
                imagePlugin.Info.Sectors != 1366 &&
                imagePlugin.Info.Sectors != 3200)
            {
                return(false);
            }

            byte[] sector;

            if (imagePlugin.Info.Sectors == 3200)
            {
                sector = imagePlugin.ReadSector(1560);
                Header cbmHdr = Marshal.ByteArrayToStructureLittleEndian <Header>(sector);

                if (cbmHdr.diskDosVersion == 0x44 &&
                    cbmHdr.dosVersion == 0x33 &&
                    cbmHdr.diskVersion == 0x44)
                {
                    return(true);
                }
            }
            else
            {
                sector = imagePlugin.ReadSector(357);
                BAM cbmBam = Marshal.ByteArrayToStructureLittleEndian <BAM>(sector);

                if (cbmBam.dosVersion == 0x41 &&
                    (cbmBam.doubleSided == 0x00 || cbmBam.doubleSided == 0x80) &&
                    cbmBam.unused1 == 0x00 &&
                    cbmBam.directoryTrack == 0x12)
                {
                    return(true);
                }
            }

            return(false);
        }
Example #10
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.UTF8;
            ulong vmfsSuperOff = VMFS_BASE / imagePlugin.Info.SectorSize;

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

            VolumeInfo volInfo = Marshal.ByteArrayToStructureLittleEndian <VolumeInfo>(sector);

            var sbInformation = new StringBuilder();

            sbInformation.AppendLine("VMware file system");

            uint ctimeSecs     = (uint)(volInfo.ctime / 1000000);
            uint ctimeNanoSecs = (uint)(volInfo.ctime % 1000000);
            uint mtimeSecs     = (uint)(volInfo.mtime / 1000000);
            uint mtimeNanoSecs = (uint)(volInfo.mtime % 1000000);

            sbInformation.AppendFormat("Volume version {0}", volInfo.version).AppendLine();

            sbInformation.AppendFormat("Volume name {0}", StringHandlers.CToString(volInfo.name, Encoding)).
            AppendLine();

            sbInformation.AppendFormat("Volume size {0} bytes", volInfo.size * 256).AppendLine();
            sbInformation.AppendFormat("Volume UUID {0}", volInfo.uuid).AppendLine();

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

            sbInformation.AppendFormat("Volume last modified on {0}",
                                       DateHandlers.UnixUnsignedToDateTime(mtimeSecs, mtimeNanoSecs)).AppendLine();

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                Type                      = "VMware file system",
                CreationDate              = DateHandlers.UnixUnsignedToDateTime(ctimeSecs, ctimeNanoSecs),
                CreationDateSpecified     = true,
                ModificationDate          = DateHandlers.UnixUnsignedToDateTime(mtimeSecs, mtimeNanoSecs),
                ModificationDateSpecified = true,
                Clusters                  = (volInfo.size * 256) / imagePlugin.Info.SectorSize,
                ClusterSize               = imagePlugin.Info.SectorSize,
                VolumeSerial              = volInfo.uuid.ToString()
            };
        }
Example #11
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 SuperBlock();
            bool littleEndian = true;

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

                break;

            case CRAM_CIGAM:
                crSb         = Marshal.ByteArrayToStructureBigEndian <SuperBlock>(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
            };
        }
Example #12
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 512)
            {
                return(false);
            }

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

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

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

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

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

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

                AaruConsole.DebugWriteLine("Locus plugin", "magic at {1} = 0x{0:X8}", locusSb.s_magic, location);

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

            return(false);
        }
Example #13
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;

            if (partition.Start + bootSectors >= partition.End)
            {
                return(false);
            }

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

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

            SuperBlock jfsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector);

            return(jfsSb.s_magic == JFS_MAGIC);
        }
Example #14
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            int  sbSizeInBytes   = Marshal.SizeOf <SuperBlock>();
            uint sbSizeInSectors = (uint)(sbSizeInBytes / imagePlugin.Info.SectorSize);

            if (sbSizeInBytes % imagePlugin.Info.SectorSize > 0)
            {
                sbSizeInSectors++;
            }

            if (sbSizeInSectors + partition.Start >= partition.End)
            {
                return(false);
            }

            byte[]     sbSector = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors);
            SuperBlock supblk   = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector);

            return(supblk.s_magic == XIAFS_SUPER_MAGIC);
        }
Example #15
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 512)
            {
                return(false);
            }

            // It should be start of a tape or floppy or file
            if (partition.Start != 0)
            {
                return(false);
            }

            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(false);
            }

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

            AaruConsole.DebugWriteLine("dump(8) plugin", "old magic = 0x{0:X8}", oldHdr.c_magic);
            AaruConsole.DebugWriteLine("dump(8) plugin", "aix magic = 0x{0:X8}", aixHdr.c_magic);
            AaruConsole.DebugWriteLine("dump(8) plugin", "new magic = 0x{0:X8}", newHdr.c_magic);

            return(oldHdr.c_magic == OFS_MAGIC || aixHdr.c_magic == XIX_MAGIC || aixHdr.c_magic == XIX_CIGAM ||
                   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);
        }
Example #16
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < F2FS_MIN_SECTOR ||
                imagePlugin.Info.SectorSize > F2FS_MAX_SECTOR)
            {
                return(false);
            }

            uint sbAddr = F2FS_SUPER_OFFSET / imagePlugin.Info.SectorSize;

            if (sbAddr == 0)
            {
                sbAddr = 1;
            }

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

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

            if (partition.Start + sbAddr >= partition.End)
            {
                return(false);
            }

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

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

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

            return(sb.magic == F2FS_MAGIC);
        }
Example #17
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (imagePlugin.Info.SectorSize < 512)
            {
                return(false);
            }

            uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize;

            if (sbAddr == 0)
            {
                sbAddr = 1;
            }

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

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

            if (partition.Start + sbAddr + sbSize >= partition.End)
            {
                return(false);
            }

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

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

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

            return(_magic35.SequenceEqual(reiserSb.magic) || _magic36.SequenceEqual(reiserSb.magic) ||
                   _magicJr.SequenceEqual(reiserSb.magic));
        }
Example #18
0
File: QNX6.cs Project: paulyc/Aaru
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            uint sectors     = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize;
            uint bootSectors = QNX6_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;

            if (partition.Start + bootSectors + sectors >= partition.End)
            {
                return(false);
            }

            byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors);
            byte[] sector     = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors);

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

            AudiSuperBlock audiSb = Marshal.ByteArrayToStructureLittleEndian <AudiSuperBlock>(audiSector);

            SuperBlock qnxSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector);

            return(qnxSb.magic == QNX6_MAGIC || audiSb.magic == QNX6_MAGIC);
        }
Example #19
0
File: ODS.cs Project: paulyc/Aaru
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-1");
            information = "";

            var sb = new StringBuilder();

            byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start);

            HomeBlock homeblock = Marshal.ByteArrayToStructureLittleEndian <HomeBlock>(hbSector);

            // Optical disc
            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc &&
                StringHandlers.CToString(homeblock.format) != "DECFILE11A  " &&
                StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
            {
                if (hbSector.Length < 0x400)
                {
                    return;
                }

                byte[] tmp = imagePlugin.ReadSector(partition.Start);
                hbSector = new byte[0x200];
                Array.Copy(tmp, 0x200, hbSector, 0, 0x200);

                homeblock = Marshal.ByteArrayToStructureLittleEndian <HomeBlock>(hbSector);

                if (StringHandlers.CToString(homeblock.format) != "DECFILE11A  " &&
                    StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
                {
                    return;
                }
            }

            if ((homeblock.struclev & 0xFF00) != 0x0200 ||
                (homeblock.struclev & 0xFF) != 1 ||
                StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
            {
                sb.AppendLine("The following information may be incorrect for this volume.");
            }

            if (homeblock.resfiles < 5 ||
                homeblock.devtype != 0)
            {
                sb.AppendLine("This volume may be corrupted.");
            }

            sb.AppendFormat("Volume format is {0}", StringHandlers.SpacePaddedToString(homeblock.format, Encoding)).
            AppendLine();

            sb.AppendFormat("Volume is Level {0} revision {1}", (homeblock.struclev & 0xFF00) >> 8,
                            homeblock.struclev & 0xFF).AppendLine();

            sb.AppendFormat("Lowest structure in the volume is Level {0}, revision {1}",
                            (homeblock.lowstruclev & 0xFF00) >> 8, homeblock.lowstruclev & 0xFF).AppendLine();

            sb.AppendFormat("Highest structure in the volume is Level {0}, revision {1}",
                            (homeblock.highstruclev & 0xFF00) >> 8, homeblock.highstruclev & 0xFF).AppendLine();

            sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512).
            AppendLine();

            sb.AppendFormat("This home block is on sector {0} (VBN {1})", homeblock.homelbn, homeblock.homevbn).
            AppendLine();

            sb.AppendFormat("Secondary home block is on sector {0} (VBN {1})", homeblock.alhomelbn,
                            homeblock.alhomevbn).AppendLine();

            sb.AppendFormat("Volume bitmap starts in sector {0} (VBN {1})", homeblock.ibmaplbn, homeblock.ibmapvbn).
            AppendLine();

            sb.AppendFormat("Volume bitmap runs for {0} sectors ({1} bytes)", homeblock.ibmapsize,
                            homeblock.ibmapsize * 512).AppendLine();

            sb.AppendFormat("Backup INDEXF.SYS;1 is in sector {0} (VBN {1})", homeblock.altidxlbn, homeblock.altidxvbn).
            AppendLine();

            sb.AppendFormat("{0} maximum files on the volume", homeblock.maxfiles).AppendLine();
            sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();

            if (homeblock.rvn > 0 &&
                homeblock.setcount > 0 &&
                StringHandlers.CToString(homeblock.strucname) != "            ")
            {
                sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount,
                                StringHandlers.SpacePaddedToString(homeblock.strucname, Encoding)).AppendLine();
            }

            sb.AppendFormat("Volume owner is \"{0}\" (ID 0x{1:X8})",
                            StringHandlers.SpacePaddedToString(homeblock.ownername, Encoding), homeblock.volowner).
            AppendLine();

            sb.AppendFormat("Volume label: \"{0}\"", StringHandlers.SpacePaddedToString(homeblock.volname, Encoding)).
            AppendLine();

            sb.AppendFormat("Drive serial number: 0x{0:X8}", homeblock.serialnum).AppendLine();
            sb.AppendFormat("Volume was created on {0}", DateHandlers.VmsToDateTime(homeblock.credate)).AppendLine();

            if (homeblock.revdate > 0)
            {
                sb.AppendFormat("Volume was last modified on {0}", DateHandlers.VmsToDateTime(homeblock.revdate)).
                AppendLine();
            }

            if (homeblock.copydate > 0)
            {
                sb.AppendFormat("Volume copied on {0}", DateHandlers.VmsToDateTime(homeblock.copydate)).AppendLine();
            }

            sb.AppendFormat("Checksums: 0x{0:X4} and 0x{1:X4}", homeblock.checksum1, homeblock.checksum2).AppendLine();
            sb.AppendLine("Flags:");
            sb.AppendFormat("Window: {0}", homeblock.window).AppendLine();
            sb.AppendFormat("Cached directores: {0}", homeblock.lru_lim).AppendLine();
            sb.AppendFormat("Default allocation: {0} blocks", homeblock.extend).AppendLine();

            if ((homeblock.volchar & 0x01) == 0x01)
            {
                sb.AppendLine("Readings should be verified");
            }

            if ((homeblock.volchar & 0x02) == 0x02)
            {
                sb.AppendLine("Writings should be verified");
            }

            if ((homeblock.volchar & 0x04) == 0x04)
            {
                sb.AppendLine("Files should be erased or overwritten when deleted");
            }

            if ((homeblock.volchar & 0x08) == 0x08)
            {
                sb.AppendLine("Highwater mark is to be disabled");
            }

            if ((homeblock.volchar & 0x10) == 0x10)
            {
                sb.AppendLine("Classification checks are enabled");
            }

            sb.AppendLine("Volume permissions (r = read, w = write, c = create, d = delete)");
            sb.AppendLine("System, owner, group, world");

            // System
            sb.Append((homeblock.protect & 0x1000) == 0x1000 ? "-" : "r");
            sb.Append((homeblock.protect & 0x2000) == 0x2000 ? "-" : "w");
            sb.Append((homeblock.protect & 0x4000) == 0x4000 ? "-" : "c");
            sb.Append((homeblock.protect & 0x8000) == 0x8000 ? "-" : "d");

            // Owner
            sb.Append((homeblock.protect & 0x100) == 0x100 ? "-" : "r");
            sb.Append((homeblock.protect & 0x200) == 0x200 ? "-" : "w");
            sb.Append((homeblock.protect & 0x400) == 0x400 ? "-" : "c");
            sb.Append((homeblock.protect & 0x800) == 0x800 ? "-" : "d");

            // Group
            sb.Append((homeblock.protect & 0x10) == 0x10 ? "-" : "r");
            sb.Append((homeblock.protect & 0x20) == 0x20 ? "-" : "w");
            sb.Append((homeblock.protect & 0x40) == 0x40 ? "-" : "c");
            sb.Append((homeblock.protect & 0x80) == 0x80 ? "-" : "d");

            // World (other)
            sb.Append((homeblock.protect & 0x1) == 0x1 ? "-" : "r");
            sb.Append((homeblock.protect & 0x2) == 0x2 ? "-" : "w");
            sb.Append((homeblock.protect & 0x4) == 0x4 ? "-" : "c");
            sb.Append((homeblock.protect & 0x8) == 0x8 ? "-" : "d");

            sb.AppendLine();

            sb.AppendLine("Unknown structures:");
            sb.AppendFormat("Security mask: 0x{0:X8}", homeblock.sec_mask).AppendLine();
            sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine();
            sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine();

            XmlFsType = new FileSystemType
            {
                Type         = "FILES-11",
                ClusterSize  = (uint)(homeblock.cluster * 512),
                Clusters     = partition.Size / (ulong)(homeblock.cluster * 512),
                VolumeName   = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
                VolumeSerial = $"{homeblock.serialnum:X8}"
            };

            if (homeblock.credate > 0)
            {
                XmlFsType.CreationDate          = DateHandlers.VmsToDateTime(homeblock.credate);
                XmlFsType.CreationDateSpecified = true;
            }

            if (homeblock.revdate > 0)
            {
                XmlFsType.ModificationDate          = DateHandlers.VmsToDateTime(homeblock.revdate);
                XmlFsType.ModificationDateSpecified = true;
            }

            information = sb.ToString();
        }
Example #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;
            }

            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();
        }
Example #21
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";
            byte[] sector = imagePlugin.ReadSector(partition.Start + 1);

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

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

            // Too much useless information

            /*
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_fname = {0}", CurrentEncoding.GetString(qnxSb.rootDir.di_fname));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_size = {0}", qnxSb.rootDir.di_size);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_first_xtnt.block = {0}", qnxSb.rootDir.di_first_xtnt.block);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_first_xtnt.length = {0}", qnxSb.rootDir.di_first_xtnt.length);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_xblk = {0}", qnxSb.rootDir.di_xblk);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_ftime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_mtime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_atime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_ctime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_num_xtnts = {0}", qnxSb.rootDir.di_num_xtnts);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_mode = {0}", Convert.ToString(qnxSb.rootDir.di_mode, 8));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_uid = {0}", qnxSb.rootDir.di_uid);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_gid = {0}", qnxSb.rootDir.di_gid);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_nlink = {0}", qnxSb.rootDir.di_nlink);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_zero = {0}", qnxSb.rootDir.di_zero);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_type = {0}", qnxSb.rootDir.di_type);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_status = {0}", qnxSb.rootDir.di_status);
             *
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_fname = {0}", CurrentEncoding.GetString(qnxSb.inode.di_fname));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_size = {0}", qnxSb.inode.di_size);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_first_xtnt.block = {0}", qnxSb.inode.di_first_xtnt.block);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_first_xtnt.length = {0}", qnxSb.inode.di_first_xtnt.length);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_xblk = {0}", qnxSb.inode.di_xblk);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_ftime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_mtime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_atime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_ctime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_num_xtnts = {0}", qnxSb.inode.di_num_xtnts);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_mode = {0}", Convert.ToString(qnxSb.inode.di_mode, 8));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_uid = {0}", qnxSb.inode.di_uid);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_gid = {0}", qnxSb.inode.di_gid);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_nlink = {0}", qnxSb.inode.di_nlink);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_zero = {0}", qnxSb.inode.di_zero);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_type = {0}", qnxSb.inode.di_type);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_status = {0}", qnxSb.inode.di_status);
             *
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_fname = {0}", CurrentEncoding.GetString(qnxSb.boot.di_fname));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_size = {0}", qnxSb.boot.di_size);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_first_xtnt.block = {0}", qnxSb.boot.di_first_xtnt.block);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_first_xtnt.length = {0}", qnxSb.boot.di_first_xtnt.length);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_xblk = {0}", qnxSb.boot.di_xblk);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_ftime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_mtime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_atime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_ctime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_num_xtnts = {0}", qnxSb.boot.di_num_xtnts);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_mode = {0}", Convert.ToString(qnxSb.boot.di_mode, 8));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_uid = {0}", qnxSb.boot.di_uid);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_gid = {0}", qnxSb.boot.di_gid);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_nlink = {0}", qnxSb.boot.di_nlink);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_zero = {0}", qnxSb.boot.di_zero);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_type = {0}", qnxSb.boot.di_type);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_status = {0}", qnxSb.boot.di_status);
             *
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_fname = {0}", CurrentEncoding.GetString(qnxSb.altBoot.di_fname));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_size = {0}", qnxSb.altBoot.di_size);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_first_xtnt.block = {0}", qnxSb.altBoot.di_first_xtnt.block);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_first_xtnt.length = {0}", qnxSb.altBoot.di_first_xtnt.length);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_xblk = {0}", qnxSb.altBoot.di_xblk);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_ftime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_mtime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_atime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_ctime));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_num_xtnts = {0}", qnxSb.altBoot.di_num_xtnts);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_mode = {0}", Convert.ToString(qnxSb.altBoot.di_mode, 8));
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_uid = {0}", qnxSb.altBoot.di_uid);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_gid = {0}", qnxSb.altBoot.di_gid);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_nlink = {0}", qnxSb.altBoot.di_nlink);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_zero = {0}", qnxSb.altBoot.di_zero);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_type = {0}", qnxSb.altBoot.di_type);
             * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_status = {0}", qnxSb.altBoot.di_status);
             */

            information =
                $"QNX4 filesystem\nCreated on {DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_ftime)}\n";

            XmlFsType = new FileSystemType
            {
                Type                      = "QNX4 filesystem",
                Clusters                  = partition.Length,
                ClusterSize               = 512,
                CreationDate              = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_ftime),
                CreationDateSpecified     = true,
                ModificationDate          = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_mtime),
                ModificationDateSpecified = true
            };

            XmlFsType.Bootable |= qnxSb.boot.di_size != 0 || qnxSb.altBoot.di_size != 0;
        }
Example #22
0
File: Sun.cs Project: paulyc/Aaru
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

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

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

            bool useDkl = false, useDkl8 = false, useDkl16 = false;

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

            dk_label   dkl   = Marshal.ByteArrayToStructureLittleEndian <dk_label>(sunSector);
            dk_label8  dkl8  = Marshal.ByteArrayToStructureLittleEndian <dk_label8>(sunSector);
            dk_label16 dkl16 = Marshal.ByteArrayToStructureLittleEndian <dk_label16>(sunSector);

            AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_magic = 0x{0:X4}", dkl.dkl_magic);
            AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_sanity = 0x{0:X8}", dkl8.dkl_vtoc.v_sanity);
            AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sanity = 0x{0:X8}", dkl16.dkl_vtoc.v_sanity);

            if (dkl.dkl_magic == DKL_MAGIC ||
                dkl.dkl_magic == DKL_CIGAM)
            {
                if (dkl16.dkl_vtoc.v_sanity == VTOC_SANE ||
                    dkl16.dkl_vtoc.v_sanity == VTOC_ENAS)
                {
                    useDkl16 = true;
                }
                else if (dkl8.dkl_vtoc.v_sanity == VTOC_SANE ||
                         dkl8.dkl_vtoc.v_sanity == VTOC_ENAS)
                {
                    useDkl8 = true;
                }
                else
                {
                    useDkl = true;
                }
            }

            if (!useDkl &&
                !useDkl8 &&
                !useDkl16)
            {
                sunSector = imagePlugin.ReadSector(sectorOffset + 1);

                dkl   = Marshal.ByteArrayToStructureLittleEndian <dk_label>(sunSector);
                dkl8  = Marshal.ByteArrayToStructureLittleEndian <dk_label8>(sunSector);
                dkl16 = Marshal.ByteArrayToStructureLittleEndian <dk_label16>(sunSector);

                if (dkl.dkl_magic == DKL_MAGIC ||
                    dkl.dkl_magic == DKL_CIGAM)
                {
                    if (dkl16.dkl_vtoc.v_sanity == VTOC_SANE ||
                        dkl16.dkl_vtoc.v_sanity == VTOC_ENAS)
                    {
                        useDkl16 = true;
                    }
                    else if (dkl8.dkl_vtoc.v_sanity == VTOC_SANE ||
                             dkl8.dkl_vtoc.v_sanity == VTOC_ENAS)
                    {
                        useDkl8 = true;
                    }
                    else
                    {
                        useDkl = true;
                    }
                }
            }

            if (!useDkl &&
                !useDkl8 &&
                !useDkl16)
            {
                return(false);
            }

            if (useDkl16 && dkl16.dkl_magic == DKL_CIGAM)
            {
                dkl16 = SwapDiskLabel(dkl16);
            }
            else if (useDkl8 && dkl8.dkl_magic == DKL_CIGAM)
            {
                dkl8 = SwapDiskLabel(dkl8);
            }
            else if (useDkl && dkl.dkl_magic == DKL_CIGAM)
            {
                dkl = SwapDiskLabel(dkl);
            }

            if (useDkl)
            {
                ulong sectorsPerCylinder = (ulong)(dkl.dkl_nsect * dkl.dkl_nhead);

                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_asciilabel = \"{0}\"",
                                           StringHandlers.CToString(dkl.dkl_asciilabel));

                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_rpm = {0}", dkl.dkl_rpm);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_pcyl = {0}", dkl.dkl_pcyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_apc = {0}", dkl.dkl_apc);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_gap1 = {0}", dkl.dkl_gap1);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_gap2 = {0}", dkl.dkl_gap2);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_intrlv = {0}", dkl.dkl_intrlv);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_ncyl = {0}", dkl.dkl_ncyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_acyl = {0}", dkl.dkl_acyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_nhead = {0}", dkl.dkl_nhead);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_nsect = {0}", dkl.dkl_nsect);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_bhead = {0}", dkl.dkl_bhead);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_ppart = {0}", dkl.dkl_ppart);

                for (int i = 0; i < NDKMAP; i++)
                {
                    AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_map[{0}].dkl_cylno = {1}", i,
                                               dkl.dkl_map[i].dkl_cylno);

                    AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_map[{0}].dkl_nblk = {1}", i,
                                               dkl.dkl_map[i].dkl_nblk);
                }

                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_magic = 0x{0:X4}", dkl.dkl_magic);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_cksum = 0x{0:X4}", dkl.dkl_cksum);
                AaruConsole.DebugWriteLine("Sun plugin", "sectorsPerCylinder = {0}", sectorsPerCylinder);

                for (int i = 0; i < NDKMAP; i++)
                {
                    if (dkl.dkl_map[i].dkl_cylno > 0 &&
                        dkl.dkl_map[i].dkl_nblk > 0)
                    {
                        var part = new Partition
                        {
                            Size     = (ulong)dkl.dkl_map[i].dkl_nblk * DK_LABEL_SIZE,
                            Length   = (ulong)((dkl.dkl_map[i].dkl_nblk * DK_LABEL_SIZE) / imagePlugin.Info.SectorSize),
                            Sequence = (ulong)i,
                            Offset   = (((ulong)dkl.dkl_map[i].dkl_cylno * sectorsPerCylinder) + sectorOffset) *
                                       DK_LABEL_SIZE,
                            Start = ((((ulong)dkl.dkl_map[i].dkl_cylno * sectorsPerCylinder) + sectorOffset) *
                                     DK_LABEL_SIZE) / imagePlugin.Info.SectorSize,
                            Type   = "SunOS partition",
                            Scheme = Name
                        };

                        if (part.Start < imagePlugin.Info.Sectors &&
                            part.End <= imagePlugin.Info.Sectors)
                        {
                            partitions.Add(part);
                        }
                    }
                }
            }
            else if (useDkl8)
            {
                ulong sectorsPerCylinder = (ulong)(dkl8.dkl_nsect * dkl8.dkl_nhead);

                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_asciilabel = \"{0}\"",
                                           StringHandlers.CToString(dkl8.dkl_asciilabel));

                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_version = {0}", dkl8.dkl_vtoc.v_version);

                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_volume = \"{0}\"",
                                           StringHandlers.CToString(dkl8.dkl_vtoc.v_volume));

                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_nparts = {0}", dkl8.dkl_vtoc.v_nparts);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_sanity = 0x{0:X8}", dkl8.dkl_vtoc.v_sanity);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_write_reinstruct = {0}", dkl8.dkl_write_reinstruct);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_read_reinstruct = {0}", dkl8.dkl_read_reinstruct);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_rpm = {0}", dkl8.dkl_rpm);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_pcyl = {0}", dkl8.dkl_pcyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_apc = {0}", dkl8.dkl_apc);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs1 = {0}", dkl8.dkl_obs1);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs2 = {0}", dkl8.dkl_obs2);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_intrlv = {0}", dkl8.dkl_intrlv);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_ncyl = {0}", dkl8.dkl_ncyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_acyl = {0}", dkl8.dkl_acyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_nhead = {0}", dkl8.dkl_nhead);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_nsect = {0}", dkl8.dkl_nsect);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs3 = {0}", dkl8.dkl_obs3);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs4 = {0}", dkl8.dkl_obs4);

                for (int i = 0; i < NDKMAP; i++)
                {
                    AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_map[{0}].dkl_cylno = {1}", i,
                                               dkl8.dkl_map[i].dkl_cylno);

                    AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_map[{0}].dkl_nblk = {1}", i,
                                               dkl8.dkl_map[i].dkl_nblk);

                    AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_part[{0}].p_tag = {1} ({2})", i,
                                               dkl8.dkl_vtoc.v_part[i].p_tag, (ushort)dkl8.dkl_vtoc.v_part[i].p_tag);

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

                    AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_timestamp[{0}] = {1}", i,
                                               DateHandlers.UnixToDateTime(dkl8.dkl_vtoc.v_timestamp[i]));
                }

                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_magic = 0x{0:X4}", dkl8.dkl_magic);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_cksum = 0x{0:X4}", dkl8.dkl_cksum);
                AaruConsole.DebugWriteLine("Sun plugin", "sectorsPerCylinder = {0}", sectorsPerCylinder);

                if (dkl8.dkl_vtoc.v_nparts > NDKMAP)
                {
                    return(false);
                }

                for (int i = 0; i < dkl8.dkl_vtoc.v_nparts; i++)
                {
                    if (dkl8.dkl_map[i].dkl_nblk > 0 &&
                        dkl8.dkl_vtoc.v_part[i].p_tag != SunTag.SunEmpty &&
                        dkl8.dkl_vtoc.v_part[i].p_tag != SunTag.SunWholeDisk)
                    {
                        var part = new Partition
                        {
                            Description = SunFlagsToString(dkl8.dkl_vtoc.v_part[i].p_flag),
                            Size        = (ulong)dkl8.dkl_map[i].dkl_nblk * DK_LABEL_SIZE,
                            Length      = (ulong)((dkl8.dkl_map[i].dkl_nblk * DK_LABEL_SIZE) / imagePlugin.Info.SectorSize),
                            Sequence    = (ulong)i,
                            Offset      = (((ulong)dkl8.dkl_map[i].dkl_cylno * sectorsPerCylinder) + sectorOffset) *
                                          DK_LABEL_SIZE,
                            Start = ((((ulong)dkl8.dkl_map[i].dkl_cylno * sectorsPerCylinder) + sectorOffset) *
                                     DK_LABEL_SIZE) / imagePlugin.Info.SectorSize,
                            Type   = SunIdToString(dkl8.dkl_vtoc.v_part[i].p_tag),
                            Scheme = Name
                        };

                        if (dkl8.dkl_vtoc.v_timestamp[i] != 0)
                        {
                            part.Description +=
                                $"\nPartition timestamped on {DateHandlers.UnixToDateTime(dkl8.dkl_vtoc.v_timestamp[i])}";
                        }

                        if (part.Start < imagePlugin.Info.Sectors &&
                            part.End <= imagePlugin.Info.Sectors)
                        {
                            partitions.Add(part);
                        }
                    }
                }
            }
            else
            {
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sanity = 0x{0:X8}", dkl16.dkl_vtoc.v_sanity);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_version = {0}", dkl16.dkl_vtoc.v_version);

                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_volume = \"{0}\"",
                                           StringHandlers.CToString(dkl16.dkl_vtoc.v_volume));

                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sectorsz = {0}", dkl16.dkl_vtoc.v_sectorsz);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_nparts = {0}", dkl16.dkl_vtoc.v_nparts);

                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_asciilabel = \"{0}\"",
                                           StringHandlers.CToString(dkl16.dkl_vtoc.v_asciilabel));

                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_pcyl = {0}", dkl16.dkl_pcyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_ncyl = {0}", dkl16.dkl_ncyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_acyl = {0}", dkl16.dkl_acyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_bcyl = {0}", dkl16.dkl_bcyl);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_nhead = {0}", dkl16.dkl_nhead);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_nsect = {0}", dkl16.dkl_nsect);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_intrlv = {0}", dkl16.dkl_intrlv);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_skew = {0}", dkl16.dkl_skew);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_apc = {0}", dkl16.dkl_apc);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_rpm = {0}", dkl16.dkl_rpm);

                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_write_reinstruct = {0}",
                                           dkl16.dkl_write_reinstruct);

                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_read_reinstruct = {0}", dkl16.dkl_read_reinstruct);

                for (int i = 0; i < NDKMAP16; i++)
                {
                    AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_start = {1}", i,
                                               dkl16.dkl_vtoc.v_part[i].p_start);

                    AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_size = {1}", i,
                                               dkl16.dkl_vtoc.v_part[i].p_size);

                    AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_tag = {1} ({2})", i,
                                               dkl16.dkl_vtoc.v_part[i].p_tag, (ushort)dkl16.dkl_vtoc.v_part[i].p_tag);

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

                    AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_timestamp[{0}] = {1}", i,
                                               DateHandlers.UnixToDateTime(dkl16.dkl_vtoc.v_timestamp[i]));
                }

                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_magic = 0x{0:X4}", dkl16.dkl_magic);
                AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_cksum = 0x{0:X4}", dkl16.dkl_cksum);

                if (dkl16.dkl_vtoc.v_nparts > NDKMAP16)
                {
                    return(false);
                }

                for (int i = 0; i < dkl16.dkl_vtoc.v_nparts; i++)
                {
                    if (dkl16.dkl_vtoc.v_part[i].p_size > 0 &&
                        dkl16.dkl_vtoc.v_part[i].p_tag != SunTag.SunEmpty &&
                        dkl16.dkl_vtoc.v_part[i].p_tag != SunTag.SunWholeDisk)
                    {
                        var part = new Partition
                        {
                            Description = SunFlagsToString(dkl16.dkl_vtoc.v_part[i].p_flag),
                            Size        = (ulong)dkl16.dkl_vtoc.v_part[i].p_size * dkl16.dkl_vtoc.v_sectorsz,
                            Length      = (ulong)((dkl16.dkl_vtoc.v_part[i].p_size * dkl16.dkl_vtoc.v_sectorsz) /
                                                  imagePlugin.Info.SectorSize),
                            Sequence = (ulong)i,
                            Offset   = ((ulong)dkl16.dkl_vtoc.v_part[i].p_start + sectorOffset) *
                                       dkl16.dkl_vtoc.v_sectorsz,
                            Start = (((ulong)dkl16.dkl_vtoc.v_part[i].p_start + sectorOffset) *
                                     dkl16.dkl_vtoc.v_sectorsz) / imagePlugin.Info.SectorSize,
                            Type   = SunIdToString(dkl16.dkl_vtoc.v_part[i].p_tag),
                            Scheme = Name
                        };

                        if (dkl16.dkl_vtoc.v_timestamp[i] != 0)
                        {
                            part.Description +=
                                $"\nPartition timestamped on {DateHandlers.UnixToDateTime(dkl16.dkl_vtoc.v_timestamp[i])}";
                        }

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

            return(partitions.Count > 0);
        }
Example #23
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 sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize;

            if (sbAddr == 0)
            {
                sbAddr = 1;
            }

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

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

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

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

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

            if (!_magic35.SequenceEqual(reiserSb.magic) &&
                !_magic36.SequenceEqual(reiserSb.magic) &&
                !_magicJr.SequenceEqual(reiserSb.magic))
            {
                return;
            }

            var sb = new StringBuilder();

            if (_magic35.SequenceEqual(reiserSb.magic))
            {
                sb.AppendLine("Reiser 3.5 filesystem");
            }
            else if (_magic36.SequenceEqual(reiserSb.magic))
            {
                sb.AppendLine("Reiser 3.6 filesystem");
            }
            else if (_magicJr.SequenceEqual(reiserSb.magic))
            {
                sb.AppendLine("Reiser Jr. filesystem");
            }

            sb.AppendFormat("Volume has {0} blocks with {1} blocks free", reiserSb.block_count, reiserSb.free_blocks).
            AppendLine();

            sb.AppendFormat("{0} bytes per block", reiserSb.blocksize).AppendLine();
            sb.AppendFormat("Root directory resides on block {0}", reiserSb.root_block).AppendLine();

            if (reiserSb.umount_state == 2)
            {
                sb.AppendLine("Volume has not been cleanly umounted");
            }

            sb.AppendFormat("Volume last checked on {0}", DateHandlers.UnixUnsignedToDateTime(reiserSb.last_check)).
            AppendLine();

            if (reiserSb.version >= 2)
            {
                sb.AppendFormat("Volume UUID: {0}", reiserSb.uuid).AppendLine();
                sb.AppendFormat("Volume name: {0}", Encoding.GetString(reiserSb.label)).AppendLine();
            }

            information = sb.ToString();

            XmlFsType = new FileSystemType();

            if (_magic35.SequenceEqual(reiserSb.magic))
            {
                XmlFsType.Type = "Reiser 3.5 filesystem";
            }
            else if (_magic36.SequenceEqual(reiserSb.magic))
            {
                XmlFsType.Type = "Reiser 3.6 filesystem";
            }
            else if (_magicJr.SequenceEqual(reiserSb.magic))
            {
                XmlFsType.Type = "Reiser Jr. filesystem";
            }

            XmlFsType.ClusterSize           = reiserSb.blocksize;
            XmlFsType.Clusters              = reiserSb.block_count;
            XmlFsType.FreeClusters          = reiserSb.free_blocks;
            XmlFsType.FreeClustersSpecified = true;
            XmlFsType.Dirty = reiserSb.umount_state == 2;

            if (reiserSb.version < 2)
            {
                return;
            }

            XmlFsType.VolumeName   = Encoding.GetString(reiserSb.label);
            XmlFsType.VolumeSerial = reiserSb.uuid.ToString();
        }
Example #24
0
File: MBR.cs Project: paulyc/Aaru
        static bool GetMinix(IMediaImage imagePlugin, ulong start, ulong divider, ulong sectorOffset, uint sectorSize,
                             out List <Partition> partitions)
        {
            partitions = new List <Partition>();

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

            ExtendedBootRecord mnx = Marshal.ByteArrayToStructureLittleEndian <ExtendedBootRecord>(sector);

            AaruConsole.DebugWriteLine("MBR plugin", "mnx.magic == MBR_Magic = {0}", mnx.magic == MBR_MAGIC);

            if (mnx.magic != MBR_MAGIC)
            {
                return(false);
            }

            bool anyMnx = false;

            foreach (PartitionEntry mnxEntry in mnx.entries)
            {
                bool   mnxValid      = true;
                byte   startSector   = (byte)(mnxEntry.start_sector & 0x3F);
                ushort startCylinder = (ushort)(((mnxEntry.start_sector & 0xC0) << 2) | mnxEntry.start_cylinder);
                byte   endSector     = (byte)(mnxEntry.end_sector & 0x3F);
                ushort endCylinder   = (ushort)(((mnxEntry.end_sector & 0xC0) << 2) | mnxEntry.end_cylinder);
                ulong  mnxStart      = mnxEntry.lba_start;
                ulong  mnxSectors    = mnxEntry.lba_sectors;

                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.status {0}", mnxEntry.status);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.type {0}", mnxEntry.type);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.lba_start {0}", mnxEntry.lba_start);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.lba_sectors {0}", mnxEntry.lba_sectors);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.start_cylinder {0}", startCylinder);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.start_head {0}", mnxEntry.start_head);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.start_sector {0}", startSector);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.end_cylinder {0}", endCylinder);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.end_head {0}", mnxEntry.end_head);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.end_sector {0}", endSector);

                mnxValid &= mnxEntry.status == 0x00 || mnxEntry.status == 0x80;
                mnxValid &= mnxEntry.type == 0x81 || mnxEntry.type == 0x80;

                mnxValid &= mnxEntry.lba_start != 0 || mnxEntry.lba_sectors != 0 || mnxEntry.start_cylinder != 0 ||
                            mnxEntry.start_head != 0 || mnxEntry.start_sector != 0 || mnxEntry.end_cylinder != 0 ||
                            mnxEntry.end_head != 0 || mnxEntry.end_sector != 0;

                if (mnxEntry.lba_start == 0 &&
                    mnxEntry.lba_sectors == 0 &&
                    mnxValid)
                {
                    mnxStart = CHS.ToLBA(startCylinder, mnxEntry.start_head, startSector, imagePlugin.Info.Heads,
                                         imagePlugin.Info.SectorsPerTrack);

                    mnxSectors = CHS.ToLBA(endCylinder, mnxEntry.end_head, mnxEntry.end_sector, imagePlugin.Info.Heads,
                                           imagePlugin.Info.SectorsPerTrack) - mnxStart;
                }

                // For optical media
                mnxStart   /= divider;
                mnxSectors /= divider;

                AaruConsole.DebugWriteLine("MBR plugin", "mnx_start {0}", mnxStart);
                AaruConsole.DebugWriteLine("MBR plugin", "mnx_sectors {0}", mnxSectors);

                if (!mnxValid)
                {
                    continue;
                }

                var part = new Partition();

                if (mnxStart > 0 &&
                    mnxSectors > 0)
                {
                    part.Start  = mnxStart + sectorOffset;
                    part.Length = mnxSectors;
                    part.Offset = part.Start * sectorSize;
                    part.Size   = part.Length * sectorSize;
                }
                else
                {
                    mnxValid = false;
                }

                if (!mnxValid)
                {
                    continue;
                }

                anyMnx           = true;
                part.Type        = "MINIX";
                part.Name        = "MINIX";
                part.Description = mnxEntry.status == 0x80 ? "Partition is bootable." : "";
                part.Scheme      = "MINIX";

                partitions.Add(part);
            }

            return(anyMnx);
        }
Example #25
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

            // I think Apricot can't chain partitions so.
            if (sectorOffset != 0)
            {
                return(false);
            }

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

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

            Label label = Marshal.ByteArrayToStructureLittleEndian <Label>(sector);

            // Not much to check but...
            ulong deviceSectors = imagePlugin.Info.Sectors;
            ulong deviceSizeAccordingToLabel = label.cylinders * label.heads * label.spt;

            if (label.operatingSystem > 4 ||
                label.bootType > 5 ||
                label.partitionCount > 8 ||
                deviceSizeAccordingToLabel > deviceSectors ||
                label.firstDataBlock > deviceSectors)
            {
                return(false);
            }

            AaruConsole.DebugWriteLine("Apricot partitions", "label.version = \"{0}\"",
                                       StringHandlers.CToString(label.version));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.operatingSystem = {0} ({1})", label.operatingSystem,
                                       label.operatingSystem < _operatingSystemCodes.Length
                                           ? _operatingSystemCodes[label.operatingSystem] : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.writeProtected = {0}", label.writeProtected);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.copyProtected = {0}", label.copyProtected);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootType = {0} ({1})", label.bootType,
                                       label.bootType < _bootTypeCodes.Length ? _bootTypeCodes[label.bootType]
                                           : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.partitionCount = {0}", label.partitionCount);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.winchester = {0}", label.winchester);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.sectorSize = {0}", label.sectorSize);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.spt = {0}", label.spt);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.cylinders = {0}", label.cylinders);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.heads = {0}", label.heads);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.interleave = {0}", label.interleave);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.skew = {0}", label.skew);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootLocation = {0}", label.bootLocation);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootSize = {0}", label.bootSize);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootAddress = 0x{0:X8}", label.bootAddress);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootOffset:label.bootSegment = {0:X4}:{1:X4}",
                                       label.bootOffset, label.bootSegment);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.firstDataBlock = {0}", label.firstDataBlock);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.generation = {0}", label.generation);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.copyCount = {0}", label.copyCount);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.maxCopies = {0}", label.maxCopies);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.serialNumber = \"{0}\"",
                                       StringHandlers.CToString(label.serialNumber));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.partNumber = \"{0}\"",
                                       StringHandlers.CToString(label.partNumber));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.copyright = \"{0}\"",
                                       StringHandlers.CToString(label.copyright));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.bps = {0}", label.mainBPB.bps);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.spc = {0}", label.mainBPB.spc);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.rsectors = {0}", label.mainBPB.rsectors);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.fats_no = {0}", label.mainBPB.fats_no);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.root_ent = {0}", label.mainBPB.root_ent);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.sectors = {0}", label.mainBPB.sectors);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.media = {0}", label.mainBPB.media);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.spfat = {0}", label.mainBPB.spfat);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.diskType = {0} ({1})",
                                       label.mainBPB.diskType,
                                       label.mainBPB.diskType < _diskTypeCodes.Length
                                           ? _diskTypeCodes[label.mainBPB.diskType] : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.startSector = {0}",
                                       label.mainBPB.startSector);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.fontName = \"{0}\"",
                                       StringHandlers.CToString(label.fontName));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardName = \"{0}\"",
                                       StringHandlers.CToString(label.keyboardName));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.biosMajorVersion = {0}", label.biosMajorVersion);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.biosMinorVersion = {0}", label.biosMinorVersion);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.diagnosticsFlag = {0}", label.diagnosticsFlag);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.prnDevice = {0} ({1})", label.prnDevice,
                                       label.prnDevice < _printDevices.Length ? _printDevices[label.prnDevice]
                                           : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.bellVolume = {0}", label.bellVolume);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.enableCache = {0}", label.enableCache);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.enableGraphics = {0}", label.enableGraphics);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.dosLength = {0}", label.dosLength);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.fontLength = {0}", label.fontLength);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardLength = {0}", label.keyboardLength);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.dosStart = {0}", label.dosStart);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.fontStart = {0}", label.fontStart);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardStart = {0}", label.keyboardStart);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardVolume = {0}", label.keyboardVolume);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeat = {0}", label.autorepeat);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeatLeadIn = {0}", label.autorepeatLeadIn);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeatInterval = {0}",
                                       label.autorepeatInterval);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.microscreenMode = {0}", label.microscreenMode);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareKeyboard is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareKeyboard));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.lineMode = {0} ({1} lines)", label.lineMode,
                                       label.lineMode < _lineModes.Length ? _lineModes[label.lineMode] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.lineWidth = {0} ({1} columns)", label.lineWidth,
                                       label.lineWidth < _lineWidths.Length ? _lineWidths[label.lineWidth] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.imageOff = {0}", label.imageOff);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareScreen is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareScreen));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.txBaudRate = {0} ({1} bps)", label.txBaudRate,
                                       label.txBaudRate < _baudRates.Length ? _baudRates[label.txBaudRate] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.rxBaudRate = {0} ({1} bps)", label.rxBaudRate,
                                       label.rxBaudRate < _baudRates.Length ? _baudRates[label.rxBaudRate] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.txBits = {0}", label.txBits);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.rxBits = {0}", label.rxBits);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.stopBits = {0} ({1} bits)", label.stopBits,
                                       label.stopBits < _stopBits.Length ? _stopBits[label.stopBits] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.parityCheck = {0}", label.parityCheck);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.parityType = {0} ({1})", label.parityType,
                                       label.parityType < _parityTypes.Length ? _parityTypes[label.parityType]
                                           : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.txXonXoff = {0}", label.txXonXoff);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.rxXonXoff = {0}", label.rxXonXoff);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.xonCharacter = {0}", label.xonCharacter);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.xoffCharacter = {0}", label.xoffCharacter);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.rxXonXoffBuffer = {0}", label.rxXonXoffBuffer);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.dtrDsr = {0}", label.dtrDsr);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.ctsRts = {0}", label.ctsRts);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.nullsAfterCr = {0}", label.nullsAfterCr);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.nullsAfterFF = {0}", label.nullsAfterFF);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.lfAfterCRSerial = {0}", label.lfAfterCRSerial);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.biosErrorReportSerial = {0}",
                                       label.biosErrorReportSerial);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareSerial is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareSerial));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.lfAfterCrParallel = {0}", label.lfAfterCrParallel);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.selectLine = {0}", label.selectLine);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.paperEmpty = {0}", label.paperEmpty);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.faultLine = {0}", label.faultLine);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.biosErrorReportParallel = {0}",
                                       label.biosErrorReportParallel);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareParallel is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareParallel));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareWinchester is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareWinchester));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.parkingEnabled = {0}", label.parkingEnabled);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.formatProtection = {0}", label.formatProtection);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareRamDisk is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareRamDisk));

            for (int i = 0; i < 32; i++)
            {
                AaruConsole.DebugWriteLine("Apricot partitions", "label.badBlocks[{1}] = {0}", label.badBlocks[i], i);
            }

            for (int i = 0; i < 8; i++)
            {
                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].bps = {0}",
                                           label.partitions[i].bps, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].spc = {0}",
                                           label.partitions[i].spc, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].rsectors = {0}",
                                           label.partitions[i].rsectors, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].fats_no = {0}",
                                           label.partitions[i].fats_no, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].root_ent = {0}",
                                           label.partitions[i].root_ent, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].sectors = {0}",
                                           label.partitions[i].sectors, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].media = {0}",
                                           label.partitions[i].media, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].spfat = {0}",
                                           label.partitions[i].spfat, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].diskType = {0} ({2})",
                                           label.partitions[i].diskType, i,
                                           label.partitions[i].diskType < _diskTypeCodes.Length
                                               ? _diskTypeCodes[label.partitions[i].diskType] : "Unknown");

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].startSector = {0}",
                                           label.partitions[i].startSector, i);
            }

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spare is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spare));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.cpmDoubleSided = {0}", label.cpmDoubleSided);

            // Only hard disks can contain partitions
            if (!label.winchester)
            {
                return(false);
            }

            for (byte i = 0; i < label.partitionCount; i++)
            {
                var part = new Partition
                {
                    Start    = label.partitions[i].startSector,
                    Size     = (ulong)(label.partitions[i].sectors * label.sectorSize),
                    Length   = label.partitions[i].sectors,
                    Type     = "ACT Apricot partition",
                    Sequence = i,
                    Scheme   = Name,
                    Offset   = (ulong)(label.partitions[i].startSector * label.sectorSize)
                };

                if (part.Start < deviceSectors &&
                    part.End < deviceSectors)
                {
                    partitions.Add(part);
                }
            }

            return(partitions.Count > 0);
        }
Example #26
0
File: MBR.cs Project: paulyc/Aaru
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            ulong counter = 0;

            partitions = new List <Partition>();

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

            uint sectorSize = imagePlugin.Info.SectorSize;

            // Divider of sector size in MBR between real sector size
            ulong divider = 1;

            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
            {
                sectorSize = 512;
                divider    = 4;
            }

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

            MasterBootRecord      mbr     = Marshal.ByteArrayToStructureLittleEndian <MasterBootRecord>(sector);
            TimedMasterBootRecord mbrTime = Marshal.ByteArrayToStructureLittleEndian <TimedMasterBootRecord>(sector);

            SerializedMasterBootRecord mbrSerial =
                Marshal.ByteArrayToStructureLittleEndian <SerializedMasterBootRecord>(sector);

            ModernMasterBootRecord mbrModern = Marshal.ByteArrayToStructureLittleEndian <ModernMasterBootRecord>(sector);
            NecMasterBootRecord    mbrNec    = Marshal.ByteArrayToStructureLittleEndian <NecMasterBootRecord>(sector);

            DiskManagerMasterBootRecord mbrOntrack =
                Marshal.ByteArrayToStructureLittleEndian <DiskManagerMasterBootRecord>(sector);

            AaruConsole.DebugWriteLine("MBR plugin", "xmlmedia = {0}", imagePlugin.Info.XmlMediaType);
            AaruConsole.DebugWriteLine("MBR plugin", "mbr.magic = {0:X4}", mbr.magic);

            if (mbr.magic != MBR_MAGIC)
            {
                return(false); // Not MBR
            }
            byte[] hdrBytes = imagePlugin.ReadSector(1 + sectorOffset);

            ulong signature = BitConverter.ToUInt64(hdrBytes, 0);

            AaruConsole.DebugWriteLine("MBR Plugin", "gpt.signature = 0x{0:X16}", signature);

            if (signature == GPT_MAGIC)
            {
                return(false);
            }

            if (signature != GPT_MAGIC &&
                imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
            {
                hdrBytes  = imagePlugin.ReadSector(sectorOffset);
                signature = BitConverter.ToUInt64(hdrBytes, 512);
                AaruConsole.DebugWriteLine("MBR Plugin", "gpt.signature @ 0x200 = 0x{0:X16}", signature);

                if (signature == GPT_MAGIC)
                {
                    return(false);
                }
            }

            PartitionEntry[] entries;

            if (mbrOntrack.dm_magic == DM_MAGIC)
            {
                entries = mbrOntrack.entries;
            }
            else if (mbrNec.nec_magic == NEC_MAGIC)
            {
                entries = mbrNec.entries;
            }
            else
            {
                entries = mbr.entries;
            }

            foreach (PartitionEntry entry in entries)
            {
                byte   startSector   = (byte)(entry.start_sector & 0x3F);
                ushort startCylinder = (ushort)(((entry.start_sector & 0xC0) << 2) | entry.start_cylinder);
                byte   endSector     = (byte)(entry.end_sector & 0x3F);
                ushort endCylinder   = (ushort)(((entry.end_sector & 0xC0) << 2) | entry.end_cylinder);
                ulong  lbaStart      = entry.lba_start;
                ulong  lbaSectors    = entry.lba_sectors;

                // Let's start the fun...

                bool valid    = true;
                bool extended = false;
                bool minix    = false;

                if (entry.status != 0x00 &&
                    entry.status != 0x80)
                {
                    return(false); // Maybe a FAT filesystem
                }
                valid &= entry.type != 0x00;

                if (entry.type == 0x05 ||
                    entry.type == 0x0F ||
                    entry.type == 0x15 ||
                    entry.type == 0x1F ||
                    entry.type == 0x85 ||
                    entry.type == 0x91 ||
                    entry.type == 0x9B ||
                    entry.type == 0xC5 ||
                    entry.type == 0xCF ||
                    entry.type == 0xD5)
                {
                    valid    = false;
                    extended = true; // Extended partition
                }

                minix |= entry.type == 0x81 || entry.type == 0x80; // MINIX partition

                valid &= entry.lba_start != 0 || entry.lba_sectors != 0 || entry.start_cylinder != 0 ||
                         entry.start_head != 0 || entry.start_sector != 0 || entry.end_cylinder != 0 ||
                         entry.end_head != 0 || entry.end_sector != 0;

                if (entry.lba_start == 0 &&
                    entry.lba_sectors == 0 &&
                    valid)
                {
                    lbaStart = CHS.ToLBA(startCylinder, entry.start_head, startSector, imagePlugin.Info.Heads,
                                         imagePlugin.Info.SectorsPerTrack);

                    lbaSectors = CHS.ToLBA(endCylinder, entry.end_head, entry.end_sector, imagePlugin.Info.Heads,
                                           imagePlugin.Info.SectorsPerTrack) - lbaStart;
                }

                // For optical media
                lbaStart   /= divider;
                lbaSectors /= divider;

                if (minix && lbaStart == sectorOffset)
                {
                    minix = false;
                }

                if (lbaStart > imagePlugin.Info.Sectors)
                {
                    valid    = false;
                    extended = false;
                }

                // Some buggy implementations do some rounding errors getting a few sectors beyond device size
                if (lbaStart + lbaSectors > imagePlugin.Info.Sectors)
                {
                    lbaSectors = imagePlugin.Info.Sectors - lbaStart;
                }

                AaruConsole.DebugWriteLine("MBR plugin", "entry.status {0}", entry.status);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.type {0}", entry.type);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.lba_start {0}", entry.lba_start);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.lba_sectors {0}", entry.lba_sectors);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.start_cylinder {0}", startCylinder);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.start_head {0}", entry.start_head);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.start_sector {0}", startSector);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.end_cylinder {0}", endCylinder);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.end_head {0}", entry.end_head);
                AaruConsole.DebugWriteLine("MBR plugin", "entry.end_sector {0}", endSector);

                AaruConsole.DebugWriteLine("MBR plugin", "entry.minix = {0}", minix);

                AaruConsole.DebugWriteLine("MBR plugin", "lba_start {0}", lbaStart);
                AaruConsole.DebugWriteLine("MBR plugin", "lba_sectors {0}", lbaSectors);

                if (valid && minix) // Let's mix the fun
                {
                    if (GetMinix(imagePlugin, lbaStart, divider, sectorOffset, sectorSize, out List <Partition> mnxParts))
                    {
                        partitions.AddRange(mnxParts);
                    }
                    else
                    {
                        minix = false;
                    }
                }

                if (valid && !minix)
                {
                    var part = new Partition();

                    if ((lbaStart > 0 || imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc) &&
                        lbaSectors > 0)
                    {
                        part.Start  = lbaStart + sectorOffset;
                        part.Length = lbaSectors;
                        part.Offset = part.Start * sectorSize;
                        part.Size   = part.Length * sectorSize;
                    }
                    else
                    {
                        valid = false;
                    }

                    if (valid)
                    {
                        part.Type        = $"0x{entry.type:X2}";
                        part.Name        = DecodeMbrType(entry.type);
                        part.Sequence    = counter;
                        part.Description = entry.status == 0x80 ? "Partition is bootable." : "";
                        part.Scheme      = Name;

                        counter++;

                        partitions.Add(part);
                    }
                }

                AaruConsole.DebugWriteLine("MBR plugin", "entry.extended = {0}", extended);

                if (!extended)
                {
                    continue;
                }

                bool  processingExtended = true;
                ulong chainStart         = lbaStart;

                while (processingExtended)
                {
                    sector = imagePlugin.ReadSector(lbaStart);

                    ExtendedBootRecord ebr = Marshal.ByteArrayToStructureLittleEndian <ExtendedBootRecord>(sector);

                    AaruConsole.DebugWriteLine("MBR plugin", "ebr.magic == MBR_Magic = {0}", ebr.magic == MBR_MAGIC);

                    if (ebr.magic != MBR_MAGIC)
                    {
                        break;
                    }

                    ulong nextStart = 0;

                    foreach (PartitionEntry ebrEntry in ebr.entries)
                    {
                        bool extValid = true;
                        startSector   = (byte)(ebrEntry.start_sector & 0x3F);
                        startCylinder = (ushort)(((ebrEntry.start_sector & 0xC0) << 2) | ebrEntry.start_cylinder);
                        endSector     = (byte)(ebrEntry.end_sector & 0x3F);
                        endCylinder   = (ushort)(((ebrEntry.end_sector & 0xC0) << 2) | ebrEntry.end_cylinder);
                        ulong extStart   = ebrEntry.lba_start;
                        ulong extSectors = ebrEntry.lba_sectors;
                        bool  extMinix   = false;

                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.status {0}", ebrEntry.status);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.type {0}", ebrEntry.type);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.lba_start {0}", ebrEntry.lba_start);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.lba_sectors {0}", ebrEntry.lba_sectors);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.start_cylinder {0}", startCylinder);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.start_head {0}", ebrEntry.start_head);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.start_sector {0}", startSector);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.end_cylinder {0}", endCylinder);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.end_head {0}", ebrEntry.end_head);
                        AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.end_sector {0}", endSector);

                        // Let's start the fun...
                        extValid &= ebrEntry.status == 0x00 || ebrEntry.status == 0x80;
                        extValid &= ebrEntry.type != 0x00;

                        extValid &= ebrEntry.lba_start != 0 || ebrEntry.lba_sectors != 0 ||
                                    ebrEntry.start_cylinder != 0 || ebrEntry.start_head != 0 ||
                                    ebrEntry.start_sector != 0 || ebrEntry.end_cylinder != 0 ||
                                    ebrEntry.end_head != 0 || ebrEntry.end_sector != 0;

                        if (ebrEntry.lba_start == 0 &&
                            ebrEntry.lba_sectors == 0 &&
                            extValid)
                        {
                            extStart = CHS.ToLBA(startCylinder, ebrEntry.start_head, startSector,
                                                 imagePlugin.Info.Heads, imagePlugin.Info.SectorsPerTrack);

                            extSectors = CHS.ToLBA(endCylinder, ebrEntry.end_head, ebrEntry.end_sector,
                                                   imagePlugin.Info.Heads, imagePlugin.Info.SectorsPerTrack) - extStart;
                        }

                        extMinix |= ebrEntry.type == 0x81 || ebrEntry.type == 0x80;

                        // For optical media
                        extStart   /= divider;
                        extSectors /= divider;

                        AaruConsole.DebugWriteLine("MBR plugin", "ext_start {0}", extStart);
                        AaruConsole.DebugWriteLine("MBR plugin", "ext_sectors {0}", extSectors);

                        if (ebrEntry.type == 0x05 ||
                            ebrEntry.type == 0x0F ||
                            ebrEntry.type == 0x15 ||
                            ebrEntry.type == 0x1F ||
                            ebrEntry.type == 0x85 ||
                            ebrEntry.type == 0x91 ||
                            ebrEntry.type == 0x9B ||
                            ebrEntry.type == 0xC5 ||
                            ebrEntry.type == 0xCF ||
                            ebrEntry.type == 0xD5)
                        {
                            extValid  = false;
                            nextStart = chainStart + extStart;
                        }

                        extStart += lbaStart;
                        extValid &= extStart <= imagePlugin.Info.Sectors;

                        // Some buggy implementations do some rounding errors getting a few sectors beyond device size
                        if (extStart + extSectors > imagePlugin.Info.Sectors)
                        {
                            extSectors = imagePlugin.Info.Sectors - extStart;
                        }

                        if (extValid && extMinix) // Let's mix the fun
                        {
                            if (GetMinix(imagePlugin, lbaStart, divider, sectorOffset, sectorSize,
                                         out List <Partition> mnxParts))
                            {
                                partitions.AddRange(mnxParts);
                            }
                            else
                            {
                                extMinix = false;
                            }
                        }

                        if (!extValid || extMinix)
                        {
                            continue;
                        }

                        var part = new Partition();

                        if (extStart > 0 &&
                            extSectors > 0)
                        {
                            part.Start  = extStart + sectorOffset;
                            part.Length = extSectors;
                            part.Offset = part.Start * sectorSize;
                            part.Size   = part.Length * sectorSize;
                        }
                        else
                        {
                            extValid = false;
                        }

                        if (!extValid)
                        {
                            continue;
                        }

                        part.Type        = $"0x{ebrEntry.type:X2}";
                        part.Name        = DecodeMbrType(ebrEntry.type);
                        part.Sequence    = counter;
                        part.Description = ebrEntry.status == 0x80 ? "Partition is bootable." : "";
                        part.Scheme      = Name;
                        counter++;

                        partitions.Add(part);
                    }

                    AaruConsole.DebugWriteLine("MBR plugin", "next_start {0}", nextStart);
                    processingExtended &= nextStart != 0;
                    processingExtended &= nextStart <= imagePlugin.Info.Sectors;
                    lbaStart            = nextStart;
                }
            }

            // An empty MBR may exist, NeXT creates one and then hardcodes its disklabel
            return(partitions.Count != 0);
        }
Example #27
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();

            SuperBlock superBlock;

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

            superBlock = magic == HAMMER_FSBUF_VOLUME?Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector)
                             : Marshal.ByteArrayToStructureBigEndian <SuperBlock>(sbSector);

            sb.AppendLine("HAMMER filesystem");

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

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

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

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

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

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

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

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

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

            information = sb.ToString();
        }
Example #28
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("ibm850");
            information = "";

            var sb = new StringBuilder();

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

            byte[] hpfsSbSector =
                imagePlugin.ReadSector(16 + partition.Start); // Seek to superblock, on logical sector 16

            byte[] hpfsSpSector =
                imagePlugin.ReadSector(17 + partition.Start); // Seek to spareblock, on logical sector 17

            BiosParameterBlock bpb = Marshal.ByteArrayToStructureLittleEndian <BiosParameterBlock>(hpfsBpbSector);

            SuperBlock hpfsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(hpfsSbSector);

            SpareBlock sp = Marshal.ByteArrayToStructureLittleEndian <SpareBlock>(hpfsSpSector);

            if (StringHandlers.CToString(bpb.fs_type) != "HPFS    " ||
                hpfsSb.magic1 != 0xF995E849 ||
                hpfsSb.magic2 != 0xFA53E9C5 ||
                sp.magic1 != 0xF9911849 ||
                sp.magic2 != 0xFA5229C5)
            {
                sb.AppendLine("This may not be HPFS, following information may be not correct.");
                sb.AppendFormat("File system type: \"{0}\" (Should be \"HPFS    \")", bpb.fs_type).AppendLine();
                sb.AppendFormat("Superblock magic1: 0x{0:X8} (Should be 0xF995E849)", hpfsSb.magic1).AppendLine();
                sb.AppendFormat("Superblock magic2: 0x{0:X8} (Should be 0xFA53E9C5)", hpfsSb.magic2).AppendLine();
                sb.AppendFormat("Spareblock magic1: 0x{0:X8} (Should be 0xF9911849)", sp.magic1).AppendLine();
                sb.AppendFormat("Spareblock magic2: 0x{0:X8} (Should be 0xFA5229C5)", sp.magic2).AppendLine();
            }

            sb.AppendFormat("OEM name: {0}", StringHandlers.CToString(bpb.oem_name)).AppendLine();
            sb.AppendFormat("{0} bytes per sector", bpb.bps).AppendLine();

            //          sb.AppendFormat("{0} sectors per cluster", hpfs_bpb.spc).AppendLine();
            //          sb.AppendFormat("{0} reserved sectors", hpfs_bpb.rsectors).AppendLine();
            //          sb.AppendFormat("{0} FATs", hpfs_bpb.fats_no).AppendLine();
            //          sb.AppendFormat("{0} entries on root directory", hpfs_bpb.root_ent).AppendLine();
            //          sb.AppendFormat("{0} mini sectors on volume", hpfs_bpb.sectors).AppendLine();
            sb.AppendFormat("Media descriptor: 0x{0:X2}", bpb.media).AppendLine();

            //          sb.AppendFormat("{0} sectors per FAT", hpfs_bpb.spfat).AppendLine();
            //          sb.AppendFormat("{0} sectors per track", hpfs_bpb.sptrk).AppendLine();
            //          sb.AppendFormat("{0} heads", hpfs_bpb.heads).AppendLine();
            sb.AppendFormat("{0} sectors hidden before BPB", bpb.hsectors).AppendLine();

            sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfsSb.sectors, hpfsSb.sectors * bpb.bps).AppendLine();

            //          sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfs_bpb.big_sectors, hpfs_bpb.big_sectors * hpfs_bpb.bps).AppendLine();
            sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", bpb.drive_no).AppendLine();
            sb.AppendFormat("NT Flags: 0x{0:X2}", bpb.nt_flags).AppendLine();
            sb.AppendFormat("Signature: 0x{0:X2}", bpb.signature).AppendLine();
            sb.AppendFormat("Serial number: 0x{0:X8}", bpb.serial_no).AppendLine();
            sb.AppendFormat("Volume label: {0}", StringHandlers.CToString(bpb.volume_label, Encoding)).AppendLine();

            //          sb.AppendFormat("Filesystem type: \"{0}\"", hpfs_bpb.fs_type).AppendLine();

            DateTime lastChk   = DateHandlers.UnixToDateTime(hpfsSb.last_chkdsk);
            DateTime lastOptim = DateHandlers.UnixToDateTime(hpfsSb.last_optim);

            sb.AppendFormat("HPFS version: {0}", hpfsSb.version).AppendLine();
            sb.AppendFormat("Functional version: {0}", hpfsSb.func_version).AppendLine();
            sb.AppendFormat("Sector of root directory FNode: {0}", hpfsSb.root_fnode).AppendLine();
            sb.AppendFormat("{0} sectors are marked bad", hpfsSb.badblocks).AppendLine();
            sb.AppendFormat("Sector of free space bitmaps: {0}", hpfsSb.bitmap_lsn).AppendLine();
            sb.AppendFormat("Sector of bad blocks list: {0}", hpfsSb.badblock_lsn).AppendLine();

            if (hpfsSb.last_chkdsk > 0)
            {
                sb.AppendFormat("Date of last integrity check: {0}", lastChk).AppendLine();
            }
            else
            {
                sb.AppendLine("Filesystem integrity has never been checked");
            }

            if (hpfsSb.last_optim > 0)
            {
                sb.AppendFormat("Date of last optimization {0}", lastOptim).AppendLine();
            }
            else
            {
                sb.AppendLine("Filesystem has never been optimized");
            }

            sb.AppendFormat("Directory band has {0} sectors", hpfsSb.dband_sectors).AppendLine();
            sb.AppendFormat("Directory band starts at sector {0}", hpfsSb.dband_start).AppendLine();
            sb.AppendFormat("Directory band ends at sector {0}", hpfsSb.dband_last).AppendLine();
            sb.AppendFormat("Sector of directory band bitmap: {0}", hpfsSb.dband_bitmap).AppendLine();
            sb.AppendFormat("Sector of ACL directory: {0}", hpfsSb.acl_start).AppendLine();

            sb.AppendFormat("Sector of Hotfix directory: {0}", sp.hotfix_start).AppendLine();
            sb.AppendFormat("{0} used Hotfix entries", sp.hotfix_used).AppendLine();
            sb.AppendFormat("{0} total Hotfix entries", sp.hotfix_entries).AppendLine();
            sb.AppendFormat("{0} free spare DNodes", sp.spare_dnodes_free).AppendLine();
            sb.AppendFormat("{0} total spare DNodes", sp.spare_dnodes).AppendLine();
            sb.AppendFormat("Sector of codepage directory: {0}", sp.codepage_lsn).AppendLine();
            sb.AppendFormat("{0} codepages used in the volume", sp.codepages).AppendLine();
            sb.AppendFormat("SuperBlock CRC32: {0:X8}", sp.sb_crc32).AppendLine();
            sb.AppendFormat("SpareBlock CRC32: {0:X8}", sp.sp_crc32).AppendLine();

            sb.AppendLine("Flags:");
            sb.AppendLine((sp.flags1 & 0x01) == 0x01 ? "Filesystem is dirty." : "Filesystem is clean.");

            if ((sp.flags1 & 0x02) == 0x02)
            {
                sb.AppendLine("Spare directory blocks are in use");
            }

            if ((sp.flags1 & 0x04) == 0x04)
            {
                sb.AppendLine("Hotfixes are in use");
            }

            if ((sp.flags1 & 0x08) == 0x08)
            {
                sb.AppendLine("Disk contains bad sectors");
            }

            if ((sp.flags1 & 0x10) == 0x10)
            {
                sb.AppendLine("Disk has a bad bitmap");
            }

            if ((sp.flags1 & 0x20) == 0x20)
            {
                sb.AppendLine("Filesystem was formatted fast");
            }

            if ((sp.flags1 & 0x40) == 0x40)
            {
                sb.AppendLine("Unknown flag 0x40 on flags1 is active");
            }

            if ((sp.flags1 & 0x80) == 0x80)
            {
                sb.AppendLine("Filesystem has been mounted by an old IFS");
            }

            if ((sp.flags2 & 0x01) == 0x01)
            {
                sb.AppendLine("Install DASD limits");
            }

            if ((sp.flags2 & 0x02) == 0x02)
            {
                sb.AppendLine("Resync DASD limits");
            }

            if ((sp.flags2 & 0x04) == 0x04)
            {
                sb.AppendLine("DASD limits are operational");
            }

            if ((sp.flags2 & 0x08) == 0x08)
            {
                sb.AppendLine("Multimedia is active");
            }

            if ((sp.flags2 & 0x10) == 0x10)
            {
                sb.AppendLine("DCE ACLs are active");
            }

            if ((sp.flags2 & 0x20) == 0x20)
            {
                sb.AppendLine("DASD limits are dirty");
            }

            if ((sp.flags2 & 0x40) == 0x40)
            {
                sb.AppendLine("Unknown flag 0x40 on flags2 is active");
            }

            if ((sp.flags2 & 0x80) == 0x80)
            {
                sb.AppendLine("Unknown flag 0x80 on flags2 is active");
            }

            XmlFsType = new FileSystemType();

            // Theoretically everything from BPB to SB is boot code, should I hash everything or only the sector loaded by BIOS itself?
            if (bpb.jump[0] == 0xEB &&
                bpb.jump[1] > 0x3C &&
                bpb.jump[1] < 0x80 &&
                bpb.signature2 == 0xAA55)
            {
                XmlFsType.Bootable = true;
                string bootChk = Sha1Context.Data(bpb.boot_code, out byte[] _);
                sb.AppendLine("Volume is bootable");
                sb.AppendFormat("Boot code's SHA1: {0}", bootChk).AppendLine();
            }

            XmlFsType.Dirty           |= (sp.flags1 & 0x01) == 0x01;
            XmlFsType.Clusters         = hpfsSb.sectors;
            XmlFsType.ClusterSize      = bpb.bps;
            XmlFsType.Type             = "HPFS";
            XmlFsType.VolumeName       = StringHandlers.CToString(bpb.volume_label, Encoding);
            XmlFsType.VolumeSerial     = $"{bpb.serial_no:X8}";
            XmlFsType.SystemIdentifier = StringHandlers.CToString(bpb.oem_name);

            information = sb.ToString();
        }
Example #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();
            uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;

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

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

            SuperBlock jfsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector);

            sb.AppendLine("JFS filesystem");
            sb.AppendFormat("Version {0}", jfsSb.s_version).AppendLine();
            sb.AppendFormat("{0} blocks of {1} bytes", jfsSb.s_size, jfsSb.s_bsize).AppendLine();
            sb.AppendFormat("{0} blocks per allocation group", jfsSb.s_agsize).AppendLine();

            if (jfsSb.s_flags.HasFlag(Flags.Unicode))
            {
                sb.AppendLine("Volume uses Unicode for directory entries");
            }

            if (jfsSb.s_flags.HasFlag(Flags.RemountRO))
            {
                sb.AppendLine("Volume remounts read-only on error");
            }

            if (jfsSb.s_flags.HasFlag(Flags.Continue))
            {
                sb.AppendLine("Volume continues on error");
            }

            if (jfsSb.s_flags.HasFlag(Flags.Panic))
            {
                sb.AppendLine("Volume panics on error");
            }

            if (jfsSb.s_flags.HasFlag(Flags.UserQuota))
            {
                sb.AppendLine("Volume has user quotas enabled");
            }

            if (jfsSb.s_flags.HasFlag(Flags.GroupQuota))
            {
                sb.AppendLine("Volume has group quotas enabled");
            }

            if (jfsSb.s_flags.HasFlag(Flags.NoJournal))
            {
                sb.AppendLine("Volume is not using any journal");
            }

            if (jfsSb.s_flags.HasFlag(Flags.Discard))
            {
                sb.AppendLine("Volume sends TRIM/UNMAP commands to underlying device");
            }

            if (jfsSb.s_flags.HasFlag(Flags.GroupCommit))
            {
                sb.AppendLine("Volume commits in groups of 1");
            }

            if (jfsSb.s_flags.HasFlag(Flags.LazyCommit))
            {
                sb.AppendLine("Volume commits lazy");
            }

            if (jfsSb.s_flags.HasFlag(Flags.Temporary))
            {
                sb.AppendLine("Volume does not commit to log");
            }

            if (jfsSb.s_flags.HasFlag(Flags.InlineLog))
            {
                sb.AppendLine("Volume has log withing itself");
            }

            if (jfsSb.s_flags.HasFlag(Flags.InlineMoving))
            {
                sb.AppendLine("Volume has log withing itself and is moving it out");
            }

            if (jfsSb.s_flags.HasFlag(Flags.BadSAIT))
            {
                sb.AppendLine("Volume has bad current secondary ait");
            }

            if (jfsSb.s_flags.HasFlag(Flags.Sparse))
            {
                sb.AppendLine("Volume supports sparse files");
            }

            if (jfsSb.s_flags.HasFlag(Flags.DASDEnabled))
            {
                sb.AppendLine("Volume has DASD limits enabled");
            }

            if (jfsSb.s_flags.HasFlag(Flags.DASDPrime))
            {
                sb.AppendLine("Volume primes DASD on boot");
            }

            if (jfsSb.s_flags.HasFlag(Flags.SwapBytes))
            {
                sb.AppendLine("Volume is in a big-endian system");
            }

            if (jfsSb.s_flags.HasFlag(Flags.DirIndex))
            {
                sb.AppendLine("Volume has presistent indexes");
            }

            if (jfsSb.s_flags.HasFlag(Flags.Linux))
            {
                sb.AppendLine("Volume supports Linux");
            }

            if (jfsSb.s_flags.HasFlag(Flags.DFS))
            {
                sb.AppendLine("Volume supports DCE DFS LFS");
            }

            if (jfsSb.s_flags.HasFlag(Flags.OS2))
            {
                sb.AppendLine("Volume supports OS/2, and is case insensitive");
            }

            if (jfsSb.s_flags.HasFlag(Flags.AIX))
            {
                sb.AppendLine("Volume supports AIX");
            }

            if (jfsSb.s_state != 0)
            {
                sb.AppendLine("Volume is dirty");
            }

            sb.AppendFormat("Volume was last updated on {0}",
                            DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec)).
            AppendLine();

            if (jfsSb.s_version == 1)
            {
                sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(jfsSb.s_fpack, Encoding)).AppendLine();
            }
            else
            {
                sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(jfsSb.s_label, Encoding)).AppendLine();
            }

            sb.AppendFormat("Volume UUID: {0}", jfsSb.s_uuid).AppendLine();

            XmlFsType = new FileSystemType
            {
                Type                      = "JFS filesystem",
                Clusters                  = jfsSb.s_size,
                ClusterSize               = jfsSb.s_bsize,
                Bootable                  = true,
                VolumeName                = StringHandlers.CToString(jfsSb.s_version == 1 ? jfsSb.s_fpack : jfsSb.s_label, Encoding),
                VolumeSerial              = $"{jfsSb.s_uuid}",
                ModificationDate          = DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec),
                ModificationDateSpecified = true
            };

            if (jfsSb.s_state != 0)
            {
                XmlFsType.Dirty = true;
            }

            information = sb.ToString();
        }
Example #30
0
        public bool Open(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            _vmEHdr = new VMwareExtentHeader();
            _vmCHdr = new VMwareCowHeader();
            bool embedded = false;

            if (stream.Length > Marshal.SizeOf <VMwareExtentHeader>())
            {
                stream.Seek(0, SeekOrigin.Begin);
                byte[] vmEHdrB = new byte[Marshal.SizeOf <VMwareExtentHeader>()];
                stream.Read(vmEHdrB, 0, Marshal.SizeOf <VMwareExtentHeader>());
                _vmEHdr = Marshal.ByteArrayToStructureLittleEndian <VMwareExtentHeader>(vmEHdrB);
            }

            if (stream.Length > Marshal.SizeOf <VMwareCowHeader>())
            {
                stream.Seek(0, SeekOrigin.Begin);
                byte[] vmCHdrB = new byte[Marshal.SizeOf <VMwareCowHeader>()];
                stream.Read(vmCHdrB, 0, Marshal.SizeOf <VMwareCowHeader>());
                _vmCHdr = Marshal.ByteArrayToStructureLittleEndian <VMwareCowHeader>(vmCHdrB);
            }

            var  ddfStream = new MemoryStream();
            bool vmEHdrSet = false;
            bool cowD      = false;

            if (_vmEHdr.magic == VMWARE_EXTENT_MAGIC)
            {
                vmEHdrSet = true;
                _gdFilter = imageFilter;

                if (_vmEHdr.descriptorOffset == 0 ||
                    _vmEHdr.descriptorSize == 0)
                {
                    throw new Exception("Please open VMDK descriptor.");
                }

                byte[] ddfEmbed = new byte[_vmEHdr.descriptorSize * SECTOR_SIZE];

                stream.Seek((long)(_vmEHdr.descriptorOffset * SECTOR_SIZE), SeekOrigin.Begin);
                stream.Read(ddfEmbed, 0, ddfEmbed.Length);
                ddfStream.Write(ddfEmbed, 0, ddfEmbed.Length);

                embedded = true;
            }
            else if (_vmCHdr.magic == VMWARE_COW_MAGIC)
            {
                _gdFilter = imageFilter;
                cowD      = true;
            }
            else
            {
                byte[] ddfMagic = new byte[0x15];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(ddfMagic, 0, 0x15);

                if (!_ddfMagicBytes.SequenceEqual(ddfMagic))
                {
                    throw new Exception("Not a descriptor.");
                }

                stream.Seek(0, SeekOrigin.Begin);
                byte[] ddfExternal = new byte[imageFilter.GetDataForkLength()];
                stream.Read(ddfExternal, 0, ddfExternal.Length);
                ddfStream.Write(ddfExternal, 0, ddfExternal.Length);
            }

            _extents = new Dictionary <ulong, VMwareExtent>();
            ulong currentSector = 0;

            bool matchedCyls = false, matchedHds = false, matchedSpt = false;

            if (cowD)
            {
                int    cowCount = 1;
                string basePath = Path.GetFileNameWithoutExtension(imageFilter.GetBasePath());

                while (true)
                {
                    string curPath;

                    if (cowCount == 1)
                    {
                        curPath = basePath + ".vmdk";
                    }
                    else
                    {
                        curPath = $"{basePath}-{cowCount:D2}.vmdk";
                    }

                    if (!File.Exists(curPath))
                    {
                        break;
                    }

                    IFilter extentFilter = new FiltersList().GetFilter(curPath);
                    Stream  extentStream = extentFilter.GetDataForkStream();

                    if (stream.Length > Marshal.SizeOf <VMwareCowHeader>())
                    {
                        var extHdrCow = new VMwareCowHeader();
                        extentStream.Seek(0, SeekOrigin.Begin);
                        byte[] vmCHdrB = new byte[Marshal.SizeOf <VMwareCowHeader>()];
                        extentStream.Read(vmCHdrB, 0, Marshal.SizeOf <VMwareCowHeader>());
                        extHdrCow = Marshal.ByteArrayToStructureLittleEndian <VMwareCowHeader>(vmCHdrB);

                        if (extHdrCow.magic != VMWARE_COW_MAGIC)
                        {
                            break;
                        }

                        var newExtent = new VMwareExtent
                        {
                            Access   = "RW",
                            Filter   = extentFilter,
                            Filename = extentFilter.GetFilename(),
                            Offset   = 0,
                            Sectors  = extHdrCow.sectors,
                            Type     = "SPARSE"
                        };

                        AaruConsole.DebugWriteLine("VMware plugin", "{0} {1} {2} \"{3}\" {4}", newExtent.Access,
                                                   newExtent.Sectors, newExtent.Type, newExtent.Filename,
                                                   newExtent.Offset);

                        _extents.Add(currentSector, newExtent);
                        currentSector += newExtent.Sectors;
                    }
                    else
                    {
                        break;
                    }

                    cowCount++;
                }

                _imageType = VM_TYPE_SPLIT_SPARSE;
            }
            else
            {
                ddfStream.Seek(0, SeekOrigin.Begin);

                var regexVersion   = new Regex(REGEX_VERSION);
                var regexCid       = new Regex(REGEX_CID);
                var regexParentCid = new Regex(REGEX_CID_PARENT);
                var regexType      = new Regex(REGEX_TYPE);
                var regexExtent    = new Regex(REGEX_EXTENT);
                var regexParent    = new Regex(PARENT_REGEX);
                var regexCylinders = new Regex(REGEX_DDB_CYLINDERS);
                var regexHeads     = new Regex(REGEX_DDB_HEADS);
                var regexSectors   = new Regex(REGEX_DDB_SECTORS);

                var ddfStreamRdr = new StreamReader(ddfStream);

                while (ddfStreamRdr.Peek() >= 0)
                {
                    string line = ddfStreamRdr.ReadLine();

                    Match matchVersion   = regexVersion.Match(line);
                    Match matchCid       = regexCid.Match(line);
                    Match matchParentCid = regexParentCid.Match(line);
                    Match matchType      = regexType.Match(line);
                    Match matchExtent    = regexExtent.Match(line);
                    Match matchParent    = regexParent.Match(line);
                    Match matchCylinders = regexCylinders.Match(line);
                    Match matchHeads     = regexHeads.Match(line);
                    Match matchSectors   = regexSectors.Match(line);

                    if (matchVersion.Success)
                    {
                        uint.TryParse(matchVersion.Groups["version"].Value, out _version);
                        AaruConsole.DebugWriteLine("VMware plugin", "version = {0}", _version);
                    }
                    else if (matchCid.Success)
                    {
                        _cid = Convert.ToUInt32(matchCid.Groups["cid"].Value, 16);
                        AaruConsole.DebugWriteLine("VMware plugin", "cid = {0:x8}", _cid);
                    }
                    else if (matchParentCid.Success)
                    {
                        _parentCid = Convert.ToUInt32(matchParentCid.Groups["cid"].Value, 16);
                        AaruConsole.DebugWriteLine("VMware plugin", "parentCID = {0:x8}", _parentCid);
                    }
                    else if (matchType.Success)
                    {
                        _imageType = matchType.Groups["type"].Value;
                        AaruConsole.DebugWriteLine("VMware plugin", "createType = \"{0}\"", _imageType);
                    }
                    else if (matchExtent.Success)
                    {
                        var newExtent = new VMwareExtent
                        {
                            Access = matchExtent.Groups["access"].Value
                        };

                        if (!embedded)
                        {
                            newExtent.Filter =
                                new FiltersList().
                                GetFilter(Path.Combine(Path.GetDirectoryName(imageFilter.GetBasePath()),
                                                       matchExtent.Groups["filename"].Value));
                        }
                        else
                        {
                            newExtent.Filter = imageFilter;
                        }

                        uint.TryParse(matchExtent.Groups["offset"].Value, out newExtent.Offset);
                        uint.TryParse(matchExtent.Groups["sectors"].Value, out newExtent.Sectors);
                        newExtent.Type = matchExtent.Groups["type"].Value;

                        AaruConsole.DebugWriteLine("VMware plugin", "{0} {1} {2} \"{3}\" {4}", newExtent.Access,
                                                   newExtent.Sectors, newExtent.Type, newExtent.Filename,
                                                   newExtent.Offset);

                        _extents.Add(currentSector, newExtent);
                        currentSector += newExtent.Sectors;
                    }
                    else if (matchParent.Success)
                    {
                        _parentName = matchParent.Groups["filename"].Value;
                        AaruConsole.DebugWriteLine("VMware plugin", "parentFileNameHint = \"{0}\"", _parentName);
                        _hasParent = true;
                    }
                    else if (matchCylinders.Success)
                    {
                        uint.TryParse(matchCylinders.Groups["cylinders"].Value, out _imageInfo.Cylinders);
                        matchedCyls = true;
                    }
                    else if (matchHeads.Success)
                    {
                        uint.TryParse(matchHeads.Groups["heads"].Value, out _imageInfo.Heads);
                        matchedHds = true;
                    }
                    else if (matchSectors.Success)
                    {
                        uint.TryParse(matchSectors.Groups["sectors"].Value, out _imageInfo.SectorsPerTrack);
                        matchedSpt = true;
                    }
                }
            }

            if (_extents.Count == 0)
            {
                throw new Exception("Did not find any extent");
            }

            switch (_imageType)
            {
            case VM_TYPE_MONO_SPARSE:      //"monolithicSparse";
            case VM_TYPE_MONO_FLAT:        //"monolithicFlat";
            case VM_TYPE_SPLIT_SPARSE:     //"twoGbMaxExtentSparse";
            case VM_TYPE_SPLIT_FLAT:       //"twoGbMaxExtentFlat";
            case VMFS_TYPE_FLAT:           //"vmfsPreallocated";
            case VMFS_TYPE_ZERO:           //"vmfsEagerZeroedThick";
            case VMFS_TYPE_THIN:           //"vmfsThin";
            case VMFS_TYPE_SPARSE:         //"vmfsSparse";
            case VMFS_TYPE:                //"vmfs";
            case VM_TYPE_STREAM:           //"streamOptimized";
                break;

            case VM_TYPE_FULL_DEVICE:     //"fullDevice";
            case VM_TYPE_PART_DEVICE:     //"partitionedDevice";
            case VMFS_TYPE_RDM:           //"vmfsRDM";
            case VMFS_TYPE_RDM_OLD:       //"vmfsRawDeviceMap";
            case VMFS_TYPE_RDMP:          //"vmfsRDMP";
            case VMFS_TYPE_RDMP_OLD:      //"vmfsPassthroughRawDeviceMap";
            case VMFS_TYPE_RAW:           //"vmfsRaw";
                throw new
                      ImageNotSupportedException("Raw device image files are not supported, try accessing the device directly.");

            default: throw new ImageNotSupportedException($"Dunno how to handle \"{_imageType}\" extents.");
            }

            bool oneNoFlat = cowD;

            foreach (VMwareExtent extent in _extents.Values)
            {
                if (extent.Filter == null)
                {
                    throw new Exception($"Extent file {extent.Filename} not found.");
                }

                if (extent.Access == "NOACCESS")
                {
                    throw new Exception("Cannot access NOACCESS extents ;).");
                }

                if (extent.Type == "FLAT" ||
                    extent.Type == "ZERO" ||
                    extent.Type == "VMFS" ||
                    cowD)
                {
                    continue;
                }

                Stream extentStream = extent.Filter.GetDataForkStream();
                extentStream.Seek(0, SeekOrigin.Begin);

                if (extentStream.Length < SECTOR_SIZE)
                {
                    throw new Exception($"Extent {extent.Filename} is too small.");
                }

                byte[] extentHdrB = new byte[Marshal.SizeOf <VMwareExtentHeader>()];
                extentStream.Read(extentHdrB, 0, Marshal.SizeOf <VMwareExtentHeader>());
                VMwareExtentHeader extentHdr = Marshal.ByteArrayToStructureLittleEndian <VMwareExtentHeader>(extentHdrB);

                if (extentHdr.magic != VMWARE_EXTENT_MAGIC)
                {
                    throw new Exception($"{extent.Filter} is not an VMware extent.");
                }

                if (extentHdr.capacity < extent.Sectors)
                {
                    throw new
                          Exception($"Extent contains incorrect number of sectors, {extentHdr.capacity}. {extent.Sectors} were expected");
                }

                // TODO: Support compressed extents
                if (extentHdr.compression != COMPRESSION_NONE)
                {
                    throw new ImageNotSupportedException("Compressed extents are not yet supported.");
                }

                if (!vmEHdrSet)
                {
                    _vmEHdr   = extentHdr;
                    _gdFilter = extent.Filter;
                    vmEHdrSet = true;
                }

                oneNoFlat = true;
            }

            if (oneNoFlat &&
                !vmEHdrSet &&
                !cowD)
            {
                throw new
                      Exception("There are sparse extents but there is no header to find the grain tables, cannot proceed.");
            }

            _imageInfo.Sectors = currentSector;

            uint grains    = 0;
            uint gdEntries = 0;
            long gdOffset  = 0;
            uint gtEsPerGt = 0;

            if (oneNoFlat && !cowD)
            {
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.magic = 0x{0:X8}", _vmEHdr.magic);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.version = {0}", _vmEHdr.version);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.flags = 0x{0:X8}", _vmEHdr.flags);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.capacity = {0}", _vmEHdr.capacity);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.grainSize = {0}", _vmEHdr.grainSize);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.descriptorOffset = {0}", _vmEHdr.descriptorOffset);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.descriptorSize = {0}", _vmEHdr.descriptorSize);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.GTEsPerGT = {0}", _vmEHdr.GTEsPerGT);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.rgdOffset = {0}", _vmEHdr.rgdOffset);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.gdOffset = {0}", _vmEHdr.gdOffset);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.overhead = {0}", _vmEHdr.overhead);
                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.uncleanShutdown = {0}", _vmEHdr.uncleanShutdown);

                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.singleEndLineChar = 0x{0:X2}",
                                           _vmEHdr.singleEndLineChar);

                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.nonEndLineChar = 0x{0:X2}", _vmEHdr.nonEndLineChar);

                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.doubleEndLineChar1 = 0x{0:X2}",
                                           _vmEHdr.doubleEndLineChar1);

                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.doubleEndLineChar2 = 0x{0:X2}",
                                           _vmEHdr.doubleEndLineChar2);

                AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.compression = 0x{0:X4}", _vmEHdr.compression);

                _grainSize = _vmEHdr.grainSize;
                grains     = (uint)(_imageInfo.Sectors / _vmEHdr.grainSize) + 1;
                gdEntries  = grains / _vmEHdr.GTEsPerGT;
                gtEsPerGt  = _vmEHdr.GTEsPerGT;

                if ((_vmEHdr.flags & FLAGS_USE_REDUNDANT_TABLE) == FLAGS_USE_REDUNDANT_TABLE)
                {
                    gdOffset = (long)_vmEHdr.rgdOffset;
                }
                else
                {
                    gdOffset = (long)_vmEHdr.gdOffset;
                }
            }
            else if (oneNoFlat && cowD)
            {
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.magic = 0x{0:X8}", _vmCHdr.magic);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.version = {0}", _vmCHdr.version);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.flags = 0x{0:X8}", _vmCHdr.flags);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.sectors = {0}", _vmCHdr.sectors);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.grainSize = {0}", _vmCHdr.grainSize);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.gdOffset = {0}", _vmCHdr.gdOffset);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.numGDEntries = {0}", _vmCHdr.numGDEntries);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.freeSector = {0}", _vmCHdr.freeSector);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.cylinders = {0}", _vmCHdr.cylinders);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.heads = {0}", _vmCHdr.heads);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.spt = {0}", _vmCHdr.spt);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.generation = {0}", _vmCHdr.generation);

                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.name = {0}",
                                           StringHandlers.CToString(_vmCHdr.name));

                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.description = {0}",
                                           StringHandlers.CToString(_vmCHdr.description));

                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.savedGeneration = {0}", _vmCHdr.savedGeneration);
                AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.uncleanShutdown = {0}", _vmCHdr.uncleanShutdown);

                _grainSize            = _vmCHdr.grainSize;
                grains                = (uint)(_imageInfo.Sectors / _vmCHdr.grainSize) + 1;
                gdEntries             = _vmCHdr.numGDEntries;
                gdOffset              = _vmCHdr.gdOffset;
                gtEsPerGt             = grains / gdEntries;
                _imageInfo.MediaTitle = StringHandlers.CToString(_vmCHdr.name);
                _imageInfo.Comments   = StringHandlers.CToString(_vmCHdr.description);
                _version              = _vmCHdr.version;
            }

            if (oneNoFlat)
            {
                if (grains == 0 ||
                    gdEntries == 0)
                {
                    throw new Exception("Some error ocurred setting GD sizes");
                }

                AaruConsole.DebugWriteLine("VMware plugin", "{0} sectors in {1} grains in {2} tables",
                                           _imageInfo.Sectors, grains, gdEntries);

                Stream gdStream = _gdFilter.GetDataForkStream();

                gdStream.Seek(gdOffset * SECTOR_SIZE, SeekOrigin.Begin);

                AaruConsole.DebugWriteLine("VMware plugin", "Reading grain directory");
                byte[] gdBytes = new byte[gdEntries * 4];
                gdStream.Read(gdBytes, 0, gdBytes.Length);
                Span <uint> gd = MemoryMarshal.Cast <byte, uint>(gdBytes);

                AaruConsole.DebugWriteLine("VMware plugin", "Reading grain tables");
                uint currentGrain = 0;
                _gTable = new uint[grains];

                foreach (uint gtOff in gd)
                {
                    byte[] gtBytes = new byte[gtEsPerGt * 4];
                    gdStream.Seek(gtOff * SECTOR_SIZE, SeekOrigin.Begin);
                    gdStream.Read(gtBytes, 0, gtBytes.Length);

                    uint[] currentGt = MemoryMarshal.Cast <byte, uint>(gtBytes).ToArray();
                    Array.Copy(currentGt, 0, _gTable, currentGrain, gtEsPerGt);
                    currentGrain += gtEsPerGt;

                    // TODO: Check speed here

                    /*
                     * for(int i = 0; i < gtEsPerGt; i++)
                     * {
                     *  gTable[currentGrain] = BitConverter.ToUInt32(gtBytes, i * 4);
                     *  currentGrain++;
                     * }
                     */
                }

                _maxCachedGrains = (uint)(MAX_CACHE_SIZE / (_grainSize * SECTOR_SIZE));

                _grainCache = new Dictionary <ulong, byte[]>();
            }

            if (_hasParent)
            {
                IFilter parentFilter =
                    new FiltersList().GetFilter(Path.Combine(imageFilter.GetParentFolder(), _parentName));

                if (parentFilter == null)
                {
                    throw new Exception($"Cannot find parent \"{_parentName}\".");
                }

                _parentImage = new VMware();

                if (!_parentImage.Open(parentFilter))
                {
                    throw new Exception($"Cannot open parent \"{_parentName}\".");
                }
            }

            _sectorCache = new Dictionary <ulong, byte[]>();

            _imageInfo.CreationTime         = imageFilter.GetCreationTime();
            _imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
            _imageInfo.MediaTitle           = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
            _imageInfo.SectorSize           = SECTOR_SIZE;
            _imageInfo.XmlMediaType         = XmlMediaType.BlockMedia;
            _imageInfo.MediaType            = MediaType.GENERIC_HDD;
            _imageInfo.ImageSize            = _imageInfo.Sectors * SECTOR_SIZE;

            // VMDK version 1 started on VMware 4, so there is a previous version, "COWD"
            _imageInfo.Version = cowD ? $"{_version}" : $"{_version + 3}";

            if (cowD)
            {
                _imageInfo.Cylinders       = _vmCHdr.cylinders;
                _imageInfo.Heads           = _vmCHdr.heads;
                _imageInfo.SectorsPerTrack = _vmCHdr.spt;
            }
            else if (!matchedCyls ||
                     !matchedHds ||
                     !matchedSpt)
            {
                _imageInfo.Cylinders       = (uint)(_imageInfo.Sectors / 16 / 63);
                _imageInfo.Heads           = 16;
                _imageInfo.SectorsPerTrack = 63;
            }

            return(true);
        }