Esempio n. 1
0
        private void Initialize() {
            Console.WriteLine("Start Ext2.Initialize");
            mBuffer = new byte[mBackend.BlockSize];
            fixed (byte* xBufferAddress = &mBuffer[0]) {
                mBufferAddress = xBufferAddress;
            }
            // first get the superblock;
            var mBufferAsSuperblock = (SuperBlock*)mBufferAddress;
            int xAddr = (int)mBufferAddress;
            Console.WriteLine("Buffer address: " + xAddr);
            Console.WriteLine("Start reading superblock");
            mBackend.ReadBlock(2,
                               mBuffer);
            Console.WriteLine("End reading");
            mSuperblock = *mBufferAsSuperblock;
            DebugUtil.Send_Ext2SuperBlock(mSuperblock);
            // read the group descriptors
            Console.WriteLine("INodeCount: " + mSuperblock.INodesCount);
            Console.WriteLine("INode#1: " + mBufferAddress[0]);
            Console.WriteLine("INode#2: " + mBufferAddress[1]);
            Console.WriteLine("INode#3: " + mBufferAddress[2]);
            Console.WriteLine("INode#4: " + mBufferAddress[3]);

            Console.WriteLine("BlockCount: " + mSuperblock.BlockCount);
            Console.WriteLine("INodesPerGroup: " + (int)mSuperblock.INodesPerGroup);
            if (mSuperblock.INodesPerGroup == 0x4000)
            {
                Console.WriteLine("INodesPerGroup has correct value!");
            }
            uint xGroupDescriptorCount = mSuperblock.INodesCount / mSuperblock.INodesPerGroup;
            mGroupDescriptors = new GroupDescriptor[xGroupDescriptorCount];
            var xDescriptorPtr = (GroupDescriptor*)mBufferAddress;
            Console.WriteLine("Process GroupDescriptors: " + xGroupDescriptorCount);
            //Console.ReadLine();
            for (int i = 0; i < xGroupDescriptorCount; i++) {
                Console.WriteLine("Processing GroupDescriptor " + i);
                uint xATABlock ;

                if ( BlockSize == 1024 )
                {
                    xATABlock = ( BlockSize * 2 ) / mBackend.BlockSize ;
                }
                else
                {
                    xATABlock = ( BlockSize ) / mBackend.BlockSize ;
                }

                xATABlock += (uint)(i / 16);
                if ((i % 16) == 0) {
                    Console.WriteLine("Read new GroupDescriptorBlock");
                    mBackend.ReadBlock(xATABlock,
                                       mBuffer);
                    Console.WriteLine("End Read");
                }
                mGroupDescriptors[i] = xDescriptorPtr[i % 16];
                Console.WriteLine("End of GroupDescriptor check");
            }
            Console.WriteLine("Send GroupDescriptors to log");
            DebugUtil.Send_Ext2GroupDescriptors(mGroupDescriptors);
        }
Esempio n. 2
0
 public FileSystemPropertiesWindow(SuperBlock sb)
 {
     InitializeComponent();
     fsTypeEdit.Text      = sb.FsType;
     clusterSizeEdit.Text = sb.ClusterSize.ToString() + " байт";
     rootSizeEdit.Text    = sb.RootSize.ToString() + " байт";
     diskSizeEdit.Text    = sb.DiskSize.ToString() + " байт";
     fat1OffsetEdit.Text  = sb.Fat1Offset.ToString() + " байт";
     fat2OffsetEdit.Text  = sb.Fat2Offset.ToString() + " байт";
     rootOffsetEdit.Text  = sb.RootOffset.ToString() + " байт";
     dataOffsetEdit.Text  = sb.DataOffset.ToString() + " байт";
 }
Esempio n. 3
0
File: VxFS.cs Progetto: 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
            };
        }
        /// <summary>
        /// Detects if the stream contains a SquashFs file system.
        /// </summary>
        /// <param name="stream">The stream to inspect</param>
        /// <returns><c>true</c> if stream appears to be a SquashFs file system.</returns>
        public static bool Detect(Stream stream)
        {
            stream.Position = 0;

            SuperBlock superBlock = new SuperBlock();

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

            byte[] buffer = Utilities.ReadFully(stream, superBlock.Size);
            superBlock.ReadFrom(buffer, 0);

            return superBlock.Magic == SuperBlock.SquashFsMagic;
        }
Esempio n. 5
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
            };
        }
        public void FormatTest()
        {
            DiskAdapterService diskAdapterService = new DiskAdapterService(_diskConnectService);

            diskAdapterService.Format();

            SuperBlock superBlock = diskAdapterService.ReadSuperBlock();

            Assert.AreEqual(6, superBlock.FreeBlockSize);
            Assert.AreEqual(5, superBlock.FreeBlock[0]);
            DataBlock dataBlock = diskAdapterService.ReadDataBlock(5, DataMode.Group);

            for (int i = 1; i < 51; i++)
            {
                Assert.AreEqual(56 - i, dataBlock.GroupMode[i]);
            }
        }
Esempio n. 7
0
        public void Format()
        {
            int        count     = 1;
            List <int> blockList = new List <int>();

            blockList.Add(Constant.Constant.Nicfreeblk - 1);
            blockList.Add(-1);
            for (int i = 40954; i >= 0; i--)
            {
                if (count == Constant.Constant.Nicfreeblk)
                {
                    DataBlock dataBlock = new DataBlock()
                    {
                        GroupMode = blockList
                    };
                    WriteDataBlock(dataBlock, i, DataMode.Group);
                    count = 1;
                    blockList.Clear();
                    if (i >= Constant.Constant.Nicfreeblk)
                    {
                        blockList.Add(Constant.Constant.Nicfreeblk);
                    }
                    blockList.Add(i);
                }
                else
                {
                    blockList.Add(i);
                    count++;
                }
            }
            List <int> initInodeList = new List <int>();

            for (int j = 1; j < Constant.Constant.Dinodeblk; j++)
            {
                initInodeList.Add(j);
            }
            SuperBlock superBlock = new SuperBlock()
            {
                FreeBlockSize = count,
                FreeBlock     = blockList,
                FreeInodeSize = Constant.Constant.Dinodeblk,
                FreeInode     = initInodeList
            };

            WriteSuperBlock(superBlock);
        }
Esempio n. 8
0
        public int GetFreeInode(FileMode fileMode)
        {
            SuperBlock superBlock = _diskAdapterService.ReadSuperBlock();

            superBlock.FreeInodeSize--;
            int freeInode = superBlock.FreeInode[0];

            superBlock.FreeInode.RemoveAt(0);
            _diskAdapterService.WriteDiskInode(new DiskInode()
            {
                Number = 0,
                Mode   = (int)fileMode,
                Size   = 0,
                Addrs  = new List <int>()
            }, freeInode);
            _diskAdapterService.WriteSuperBlock(superBlock);

            return(freeInode);
        }
Esempio n. 9
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);
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
        public void CreatFileTest()
        {
            SuperBlock superBlock = new SuperBlock()
            {
                FreeBlockSize = 3,
                FreeBlock     = new List <int>()
                {
                    1, 2, 3
                },
                FreeInodeSize = 3,
                FreeInode     = new List <int>()
                {
                    1, 2, 3
                }
            };
            Dir dir = new Dir()
            {
                Size     = 0,
                DirItems = new List <DirItem>()
            };

            diskAdapterService.WriteSuperBlock(superBlock);
            diskManagementService.WriteDir(dir, 0);
            coreService.CreatFile(new User(), "newFile", 0);

            SuperBlock reSuperBlock = diskAdapterService.ReadSuperBlock();
            Dir        reDir        = diskManagementService.ReadDir(0);

            Assert.AreEqual(1, reDir.Size);
            Assert.AreEqual("newFile", reDir.DirItems[0].Name);
            Assert.AreEqual(1, reDir.DirItems[0].Inode);
            Assert.AreEqual(2, reSuperBlock.FreeInodeSize);

            coreService.DeleteFile(new User(), "newFile", 0);

            reSuperBlock = diskAdapterService.ReadSuperBlock();
            reDir        = diskManagementService.ReadDir(0);
            Assert.AreEqual(superBlock.FreeInodeSize, reSuperBlock.FreeInodeSize);
            Assert.AreEqual(dir.Size, reDir.Size);
            Assert.AreEqual(0, reDir.DirItems.Count);
        }
Esempio n. 12
0
        public void WriteSuperBlock(SuperBlock superBlock)
        {
            //超级块字节化
            byte[]     bytes     = new byte[Constant.Constant.Blocksize];
            int        count     = 0;
            List <int> blockInfo = new List <int>();

            blockInfo.Add(superBlock.FreeBlockSize);
            blockInfo.AddRange(superBlock.FreeBlock);
            blockInfo.Add(superBlock.FreeInodeSize);
            blockInfo.AddRange(superBlock.FreeInode);
            blockInfo.ForEach(delegate(int index) {
                Array.Copy(BitConverter.GetBytes(index),
                           0, bytes, count, 4);
                count += 4;
            });
            //超级块写入虚拟磁盘
            fileStream = _diskConnectService.GetFileStream();
            fileStream.Seek(0, SeekOrigin.Begin);
            fileStream.Write(bytes, 0, bytes.Length);
            fileStream.Close();
        }
Esempio n. 13
0
        public void Format()
        {
            SuperBlock = new SuperBlock
            {
                BlockSize           = 2, //this should be calculated
                TotalReservedBlocks = 20,
                TotalBlocks         = BlockDevice.TotalBlocks,
                SizeOfIndexInBytes  = 0,
                Checksum            = 0,
                DataSizeInBlocks    = 0,
                TimeStamp           = 0
            };

            SuperBlock.SizeOfIndexInBytes = 64 * 2;
            SuperBlock.Write(BlockBuffer);


            var volumeIdentifier = new VolumeIdentifier
            {
                TimeStamp  = 0,
                VolumeName = "SFS Volume"
            };

            var offset = 1;

            BlockBuffer.Offset = BlockDevice.BlockSize * BlockDevice.TotalBlocks - offset * 64;

            volumeIdentifier.Write(BlockBuffer);
            offset++;

            BlockBuffer.Offset = BlockDevice.BlockSize * BlockDevice.TotalBlocks - offset * 64;

            var marker = new StartingMarkerEntry();

            marker.Write(BlockBuffer);

            ReadIndexAria();
        }
Esempio n. 14
0
        public List <int> GetFreeBlocks(int num)
        {
            SuperBlock superBlock = _diskAdapterService.ReadSuperBlock();
            List <int> blockList  = new List <int>();

            for (int i = 0; i < num; i++)
            {
                if (superBlock.FreeBlockSize == 1)
                {
                    if (superBlock.FreeBlock[0] == -1)
                    {
                        RetrieveBlocks(blockList);
                        return(null);
                        //TODO:不知此处返回什么
                        //throw new NotImplementedException();
                    }
                    else
                    {
                        int group = superBlock.FreeBlock[0];
                        blockList.Add(group);
                        DataBlock dataBlock = _diskAdapterService.ReadDataBlock(group, DataMode.Group);
                        superBlock.FreeBlockSize = dataBlock.GroupMode[0];
                        superBlock.FreeBlock     = dataBlock.GroupMode.GetRange(1, superBlock.FreeBlockSize);
                    }
                }
                else
                {
                    superBlock.FreeBlockSize--;
                    blockList.Add(superBlock.FreeBlock[superBlock.FreeBlock.Count - 1]);
                    superBlock.FreeBlock.RemoveAt(superBlock.FreeBlock.Count - 1);
                }

                _diskAdapterService.WriteSuperBlock(superBlock);
            }

            return(blockList);
        }
Esempio n. 15
0
File: QNX6.cs Progetto: 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);
        }
        public void GetRetrieveBlock()
        {
            SuperBlock superBlock = new SuperBlock()
            {
                FreeBlockSize = 1,
                FreeBlock     = new List <int>()
                {
                    0
                },
                FreeInodeSize = 3,
                FreeInode     = new List <int>()
                {
                    1, 2, 3
                }
            };

            diskAdapterService.WriteSuperBlock(superBlock);
            DataBlock dataBlock = new DataBlock()
            {
                GroupMode = new List <int>()
                {
                    3, -1, 2, 1
                }
            };

            diskAdapterService.WriteDataBlock(dataBlock, 0, DataMode.Group);
            List <int> tFreeBlock = diskManagementService.GetFreeBlocks(2);

            Assert.AreEqual(0, tFreeBlock[0]);
            Assert.AreEqual(1, tFreeBlock[1]);
            tFreeBlock = diskManagementService.GetFreeBlocks(10);
            Assert.IsNull(tFreeBlock);
            superBlock = diskAdapterService.ReadSuperBlock();
            Assert.AreEqual(2, superBlock.FreeBlockSize);
            Assert.AreEqual(2, superBlock.FreeBlock[1]);
        }
Esempio n. 17
0
File: QNX6.cs Progetto: paulyc/Aaru
        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 sectors     = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize;
            uint bootSectors = QNX6_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;

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

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

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

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

            bool audi = audiSb.magic == QNX6_MAGIC;

            if (audi)
            {
                sb.AppendLine("QNX6 (Audi) filesystem");
                sb.AppendFormat("Checksum: 0x{0:X8}", audiSb.checksum).AppendLine();
                sb.AppendFormat("Serial: 0x{0:X16}", audiSb.checksum).AppendLine();
                sb.AppendFormat("{0} bytes per block", audiSb.blockSize).AppendLine();
                sb.AppendFormat("{0} inodes free of {1}", audiSb.freeInodes, audiSb.numInodes).AppendLine();

                sb.AppendFormat("{0} blocks ({1} bytes) free of {2} ({3} bytes)", audiSb.freeBlocks,
                                audiSb.freeBlocks * audiSb.blockSize, audiSb.numBlocks,
                                audiSb.numBlocks * audiSb.blockSize).AppendLine();

                XmlFsType = new FileSystemType
                {
                    Type                  = "QNX6 (Audi) filesystem",
                    Clusters              = audiSb.numBlocks,
                    ClusterSize           = audiSb.blockSize,
                    Bootable              = true,
                    Files                 = audiSb.numInodes - audiSb.freeInodes,
                    FilesSpecified        = true,
                    FreeClusters          = audiSb.freeBlocks,
                    FreeClustersSpecified = true,
                    VolumeSerial          = $"{audiSb.serial:X16}"
                };

                //xmlFSType.VolumeName = CurrentEncoding.GetString(audiSb.id);

                information = sb.ToString();

                return;
            }

            sb.AppendLine("QNX6 filesystem");
            sb.AppendFormat("Checksum: 0x{0:X8}", qnxSb.checksum).AppendLine();
            sb.AppendFormat("Serial: 0x{0:X16}", qnxSb.checksum).AppendLine();
            sb.AppendFormat("Created on {0}", DateHandlers.UnixUnsignedToDateTime(qnxSb.ctime)).AppendLine();
            sb.AppendFormat("Last mounted on {0}", DateHandlers.UnixUnsignedToDateTime(qnxSb.atime)).AppendLine();
            sb.AppendFormat("Flags: 0x{0:X8}", qnxSb.flags).AppendLine();
            sb.AppendFormat("Version1: 0x{0:X4}", qnxSb.version1).AppendLine();
            sb.AppendFormat("Version2: 0x{0:X4}", qnxSb.version2).AppendLine();

            //sb.AppendFormat("Volume ID: \"{0}\"", CurrentEncoding.GetString(qnxSb.volumeid)).AppendLine();
            sb.AppendFormat("{0} bytes per block", qnxSb.blockSize).AppendLine();
            sb.AppendFormat("{0} inodes free of {1}", qnxSb.freeInodes, qnxSb.numInodes).AppendLine();

            sb.AppendFormat("{0} blocks ({1} bytes) free of {2} ({3} bytes)", qnxSb.freeBlocks,
                            qnxSb.freeBlocks * qnxSb.blockSize, qnxSb.numBlocks, qnxSb.numBlocks * qnxSb.blockSize).
            AppendLine();

            XmlFsType = new FileSystemType
            {
                Type                      = "QNX6 filesystem",
                Clusters                  = qnxSb.numBlocks,
                ClusterSize               = qnxSb.blockSize,
                Bootable                  = true,
                Files                     = qnxSb.numInodes - qnxSb.freeInodes,
                FilesSpecified            = true,
                FreeClusters              = qnxSb.freeBlocks,
                FreeClustersSpecified     = true,
                VolumeSerial              = $"{qnxSb.serial:X16}",
                CreationDate              = DateHandlers.UnixUnsignedToDateTime(qnxSb.ctime),
                CreationDateSpecified     = true,
                ModificationDate          = DateHandlers.UnixUnsignedToDateTime(qnxSb.atime),
                ModificationDateSpecified = true
            };

            //xmlFSType.VolumeName = CurrentEncoding.GetString(qnxSb.volumeid);

            information = sb.ToString();
        }
Esempio n. 18
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();
        }
Esempio n. 19
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            var sb = new StringBuilder();

            var besb = new SuperBlock();

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

            bool littleEndian;

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

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

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

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

            besb = littleEndian ? Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector)
                       : Marshal.ByteArrayToStructureBigEndian <SuperBlock>(sbSector);

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

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

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

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

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

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

                break;

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

                break;

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

                break;
            }

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

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

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

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

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

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

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

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

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

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

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Clusters              = (ulong)besb.num_blocks,
                ClusterSize           = besb.block_size,
                Dirty                 = besb.flags == BEFS_DIRTY,
                FreeClusters          = (ulong)(besb.num_blocks - besb.used_blocks),
                FreeClustersSpecified = true,
                Type       = "BeFS",
                VolumeName = StringHandlers.CToString(besb.name, Encoding)
            };
        }
Esempio n. 20
0
        public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
                           Dictionary <string, string> options, string @namespace)
        {
            // TODO: Find correct default encoding
            Encoding = Encoding.ASCII;

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

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

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

            SuperBlock sb = Marshal.ByteArrayToStructureBigEndian <SuperBlock>(sbSector);

            if (sb.record_type != 1 ||
                sb.record_version != 1)
            {
                return(Errno.InvalidArgument);
            }

            if (Encoding.ASCII.GetString(sb.sync_bytes) != SYNC)
            {
                return(Errno.InvalidArgument);
            }

            if (imagePlugin.Info.SectorSize == 2336 ||
                imagePlugin.Info.SectorSize == 2352 ||
                imagePlugin.Info.SectorSize == 2448)
            {
                volumeBlockSizeRatio = sb.block_size / 2048;
            }
            else
            {
                volumeBlockSizeRatio = sb.block_size / imagePlugin.Info.SectorSize;
            }

            XmlFsType = new FileSystemType
            {
                Type         = "Opera", VolumeName = StringHandlers.CToString(sb.volume_label, Encoding),
                ClusterSize  = sb.block_size, Clusters = sb.block_count, Bootable = true,
                VolumeSerial = $"{sb.volume_id:X8}"
            };

            statfs = new FileSystemInfo
            {
                Blocks = sb.block_count, FilenameLength = MAX_NAME, FreeBlocks = 0, Id = new FileSystemId
                {
                    IsInt = true, Serial32 = sb.volume_id
                },
                PluginId = Id, Type = "Opera"
            };

            image = imagePlugin;
            int firstRootBlock = BigEndianBitConverter.ToInt32(sbSector, Marshal.SizeOf <SuperBlock>());

            rootDirectoryCache = DecodeDirectory(firstRootBlock);
            directoryCache     = new Dictionary <string, Dictionary <string, DirectoryEntryWithPointers> >();
            mounted            = true;

            return(Errno.NoError);
        }
Esempio n. 21
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();

            bool newExt2 = false;
            bool ext3    = false;
            bool ext4    = false;

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

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

            ulong sbSectorOff = SB_POS / imagePlugin.Info.SectorSize;
            uint  sbOff       = SB_POS % imagePlugin.Info.SectorSize;

            byte[] sbSector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSizeInSectors);
            byte[] sblock   = new byte[sbSizeInBytes];
            Array.Copy(sbSector, sbOff, sblock, 0, sbSizeInBytes);
            SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sblock);

            XmlFsType = new FileSystemType();

            switch (supblk.magic)
            {
            case EXT2_MAGIC_OLD:
                sb.AppendLine("ext2 (old) filesystem");
                XmlFsType.Type = "ext2";

                break;

            case EXT2_MAGIC:
                ext3 |= (supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL ||
                        (supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) == EXT3_FEATURE_INCOMPAT_RECOVER ||
                        (supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) ==
                        EXT3_FEATURE_INCOMPAT_JOURNAL_DEV;

                if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) == EXT4_FEATURE_RO_COMPAT_HUGE_FILE ||
                    (supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) == EXT4_FEATURE_RO_COMPAT_GDT_CSUM ||
                    (supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) == EXT4_FEATURE_RO_COMPAT_DIR_NLINK ||
                    (supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) ==
                    EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE ||
                    (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT ||
                    (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP) == EXT4_FEATURE_INCOMPAT_MMP ||
                    (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) == EXT4_FEATURE_INCOMPAT_FLEX_BG ||
                    (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE) == EXT4_FEATURE_INCOMPAT_EA_INODE ||
                    (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA) == EXT4_FEATURE_INCOMPAT_DIRDATA)
                {
                    ext3 = false;
                    ext4 = true;
                }

                newExt2 |= !ext3 && !ext4;

                if (newExt2)
                {
                    sb.AppendLine("ext2 filesystem");
                    XmlFsType.Type = "ext2";
                }

                if (ext3)
                {
                    sb.AppendLine("ext3 filesystem");
                    XmlFsType.Type = "ext3";
                }

                if (ext4)
                {
                    sb.AppendLine("ext4 filesystem");
                    XmlFsType.Type = "ext4";
                }

                break;

            default:
                information = "Not a ext2/3/4 filesystem" + Environment.NewLine;

                return;
            }

            string extOs;

            switch (supblk.creator_os)
            {
            case EXT2_OS_FREEBSD:
                extOs = "FreeBSD";

                break;

            case EXT2_OS_HURD:
                extOs = "Hurd";

                break;

            case EXT2_OS_LINUX:
                extOs = "Linux";

                break;

            case EXT2_OS_LITES:
                extOs = "Lites";

                break;

            case EXT2_OS_MASIX:
                extOs = "MasIX";

                break;

            default:
                extOs = $"Unknown OS ({supblk.creator_os})";

                break;
            }

            XmlFsType.SystemIdentifier = extOs;

            if (supblk.mkfs_t > 0)
            {
                sb.AppendFormat("Volume was created on {0} for {1}", DateHandlers.UnixUnsignedToDateTime(supblk.mkfs_t),
                                extOs).AppendLine();

                XmlFsType.CreationDate          = DateHandlers.UnixUnsignedToDateTime(supblk.mkfs_t);
                XmlFsType.CreationDateSpecified = true;
            }
            else
            {
                sb.AppendFormat("Volume was created for {0}", extOs).AppendLine();
            }

            byte[] tempBytes = new byte[8];
            ulong  blocks, reserved, free;

            if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT)
            {
                byte[] tempLo = BitConverter.GetBytes(supblk.blocks);
                byte[] tempHi = BitConverter.GetBytes(supblk.blocks_hi);
                tempBytes[0] = tempLo[0];
                tempBytes[1] = tempLo[1];
                tempBytes[2] = tempLo[2];
                tempBytes[3] = tempLo[3];
                tempBytes[4] = tempHi[0];
                tempBytes[5] = tempHi[1];
                tempBytes[6] = tempHi[2];
                tempBytes[7] = tempHi[3];
                blocks       = BitConverter.ToUInt64(tempBytes, 0);

                tempLo       = BitConverter.GetBytes(supblk.reserved_blocks);
                tempHi       = BitConverter.GetBytes(supblk.reserved_blocks_hi);
                tempBytes[0] = tempLo[0];
                tempBytes[1] = tempLo[1];
                tempBytes[2] = tempLo[2];
                tempBytes[3] = tempLo[3];
                tempBytes[4] = tempHi[0];
                tempBytes[5] = tempHi[1];
                tempBytes[6] = tempHi[2];
                tempBytes[7] = tempHi[3];
                reserved     = BitConverter.ToUInt64(tempBytes, 0);

                tempLo       = BitConverter.GetBytes(supblk.free_blocks);
                tempHi       = BitConverter.GetBytes(supblk.free_blocks_hi);
                tempBytes[0] = tempLo[0];
                tempBytes[1] = tempLo[1];
                tempBytes[2] = tempLo[2];
                tempBytes[3] = tempLo[3];
                tempBytes[4] = tempHi[0];
                tempBytes[5] = tempHi[1];
                tempBytes[6] = tempHi[2];
                tempBytes[7] = tempHi[3];
                free         = BitConverter.ToUInt64(tempBytes, 0);
            }
            else
            {
                blocks   = supblk.blocks;
                reserved = supblk.reserved_blocks;
                free     = supblk.free_blocks;
            }

            if (supblk.block_size == 0) // Then it is 1024 bytes
            {
                supblk.block_size = 1024;
            }

            sb.AppendFormat("Volume has {0} blocks of {1} bytes, for a total of {2} bytes", blocks,
                            1024 << (int)supblk.block_size, blocks * (ulong)(1024 << (int)supblk.block_size)).
            AppendLine();

            XmlFsType.Clusters    = blocks;
            XmlFsType.ClusterSize = (uint)(1024 << (int)supblk.block_size);

            if (supblk.mount_t > 0 ||
                supblk.mount_c > 0)
            {
                if (supblk.mount_t > 0)
                {
                    sb.AppendFormat("Last mounted on {0}", DateHandlers.UnixUnsignedToDateTime(supblk.mount_t)).
                    AppendLine();
                }

                if (supblk.max_mount_c != -1)
                {
                    sb.AppendFormat("Volume has been mounted {0} times of a maximum of {1} mounts before checking",
                                    supblk.mount_c, supblk.max_mount_c).AppendLine();
                }
                else
                {
                    sb.AppendFormat("Volume has been mounted {0} times with no maximum no. of mounts before checking",
                                    supblk.mount_c).AppendLine();
                }

                if (!string.IsNullOrEmpty(StringHandlers.CToString(supblk.last_mount_dir, Encoding)))
                {
                    sb.AppendFormat("Last mounted on: \"{0}\"",
                                    StringHandlers.CToString(supblk.last_mount_dir, Encoding)).AppendLine();
                }

                if (!string.IsNullOrEmpty(StringHandlers.CToString(supblk.mount_options, Encoding)))
                {
                    sb.AppendFormat("Last used mount options were: {0}",
                                    StringHandlers.CToString(supblk.mount_options, Encoding)).AppendLine();
                }
            }
            else
            {
                sb.AppendLine("Volume has never been mounted");

                if (supblk.max_mount_c != -1)
                {
                    sb.AppendFormat("Volume can be mounted {0} times before checking", supblk.max_mount_c).AppendLine();
                }
                else
                {
                    sb.AppendLine("Volume has no maximum no. of mounts before checking");
                }
            }

            if (supblk.check_t > 0)
            {
                if (supblk.check_inv > 0)
                {
                    sb.AppendFormat("Last checked on {0} (should check every {1} seconds)",
                                    DateHandlers.UnixUnsignedToDateTime(supblk.check_t), supblk.check_inv).AppendLine();
                }
                else
                {
                    sb.AppendFormat("Last checked on {0}", DateHandlers.UnixUnsignedToDateTime(supblk.check_t)).
                    AppendLine();
                }
            }
            else
            {
                if (supblk.check_inv > 0)
                {
                    sb.AppendFormat("Volume has never been checked (should check every {0})", supblk.check_inv).
                    AppendLine();
                }
                else
                {
                    sb.AppendLine("Volume has never been checked");
                }
            }

            if (supblk.write_t > 0)
            {
                sb.AppendFormat("Last written on {0}", DateHandlers.UnixUnsignedToDateTime(supblk.write_t)).
                AppendLine();

                XmlFsType.ModificationDate          = DateHandlers.UnixUnsignedToDateTime(supblk.write_t);
                XmlFsType.ModificationDateSpecified = true;
            }
            else
            {
                sb.AppendLine("Volume has never been written");
            }

            XmlFsType.Dirty = true;

            switch (supblk.state)
            {
            case EXT2_VALID_FS:
                sb.AppendLine("Volume is clean");
                XmlFsType.Dirty = false;

                break;

            case EXT2_ERROR_FS:
                sb.AppendLine("Volume is dirty");

                break;

            case EXT3_ORPHAN_FS:
                sb.AppendLine("Volume is recovering orphan files");

                break;

            default:
                sb.AppendFormat("Volume is in an unknown state ({0})", supblk.state).AppendLine();

                break;
            }

            if (!string.IsNullOrEmpty(StringHandlers.CToString(supblk.volume_name, Encoding)))
            {
                sb.AppendFormat("Volume name: \"{0}\"", StringHandlers.CToString(supblk.volume_name, Encoding)).
                AppendLine();

                XmlFsType.VolumeName = StringHandlers.CToString(supblk.volume_name, Encoding);
            }

            switch (supblk.err_behaviour)
            {
            case EXT2_ERRORS_CONTINUE:
                sb.AppendLine("On errors, filesystem should continue");

                break;

            case EXT2_ERRORS_RO:
                sb.AppendLine("On errors, filesystem should remount read-only");

                break;

            case EXT2_ERRORS_PANIC:
                sb.AppendLine("On errors, filesystem should panic");

                break;

            default:
                sb.AppendFormat("On errors filesystem will do an unknown thing ({0})", supblk.err_behaviour).
                AppendLine();

                break;
            }

            if (supblk.revision > 0)
            {
                sb.AppendFormat("Filesystem revision: {0}.{1}", supblk.revision, supblk.minor_revision).AppendLine();
            }

            if (supblk.uuid != Guid.Empty)
            {
                sb.AppendFormat("Volume UUID: {0}", supblk.uuid).AppendLine();
                XmlFsType.VolumeSerial = supblk.uuid.ToString();
            }

            if (supblk.kbytes_written > 0)
            {
                sb.AppendFormat("{0} KiB has been written on volume", supblk.kbytes_written).AppendLine();
            }

            sb.AppendFormat("{0} reserved and {1} free blocks", reserved, free).AppendLine();
            XmlFsType.FreeClusters          = free;
            XmlFsType.FreeClustersSpecified = true;

            sb.AppendFormat("{0} inodes with {1} free inodes ({2}%)", supblk.inodes, supblk.free_inodes,
                            (supblk.free_inodes * 100) / supblk.inodes).AppendLine();

            if (supblk.first_inode > 0)
            {
                sb.AppendFormat("First inode is {0}", supblk.first_inode).AppendLine();
            }

            if (supblk.frag_size > 0)
            {
                sb.AppendFormat("{0} bytes per fragment", supblk.frag_size).AppendLine();
            }

            if (supblk.blocks_per_grp > 0 &&
                supblk.flags_per_grp > 0 &&
                supblk.inodes_per_grp > 0)
            {
                sb.AppendFormat("{0} blocks, {1} flags and {2} inodes per group", supblk.blocks_per_grp,
                                supblk.flags_per_grp, supblk.inodes_per_grp).AppendLine();
            }

            if (supblk.first_block > 0)
            {
                sb.AppendFormat("{0} is first data block", supblk.first_block).AppendLine();
            }

            sb.AppendFormat("Default UID: {0}, GID: {1}", supblk.default_uid, supblk.default_gid).AppendLine();

            if (supblk.block_group_no > 0)
            {
                sb.AppendFormat("Block group number is {0}", supblk.block_group_no).AppendLine();
            }

            if (supblk.desc_grp_size > 0)
            {
                sb.AppendFormat("Group descriptor size is {0} bytes", supblk.desc_grp_size).AppendLine();
            }

            if (supblk.first_meta_bg > 0)
            {
                sb.AppendFormat("First metablock group is {0}", supblk.first_meta_bg).AppendLine();
            }

            if (supblk.raid_stride > 0)
            {
                sb.AppendFormat("RAID stride: {0}", supblk.raid_stride).AppendLine();
            }

            if (supblk.raid_stripe_width > 0)
            {
                sb.AppendFormat("{0} blocks on all data disks", supblk.raid_stripe_width).AppendLine();
            }

            if (supblk.mmp_interval > 0 &&
                supblk.mmp_block > 0)
            {
                sb.AppendFormat("{0} seconds for multi-mount protection wait, on block {1}", supblk.mmp_interval,
                                supblk.mmp_block).AppendLine();
            }

            if (supblk.flex_bg_grp_size > 0)
            {
                sb.AppendFormat("{0} Flexible block group size", supblk.flex_bg_grp_size).AppendLine();
            }

            if (supblk.hash_seed_1 > 0 &&
                supblk.hash_seed_2 > 0 &&
                supblk.hash_seed_3 > 0 &&
                supblk.hash_seed_4 > 0)
            {
                sb.AppendFormat("Hash seed: {0:X8}{1:X8}{2:X8}{3:X8}, version {4}", supblk.hash_seed_1,
                                supblk.hash_seed_2, supblk.hash_seed_3, supblk.hash_seed_4, supblk.hash_version).
                AppendLine();
            }

            if ((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL ||
                (supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
            {
                sb.AppendLine("Volume is journaled");

                if (supblk.journal_uuid != Guid.Empty)
                {
                    sb.AppendFormat("Journal UUID: {0}", supblk.journal_uuid).AppendLine();
                }

                sb.AppendFormat("Journal has inode {0}", supblk.journal_inode).AppendLine();

                if ((supblk.ftr_compat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV &&
                    supblk.journal_dev > 0)
                {
                    sb.AppendFormat("Journal is on device {0}", supblk.journal_dev).AppendLine();
                }

                if (supblk.jnl_backup_type > 0)
                {
                    sb.AppendFormat("Journal backup type: {0}", supblk.jnl_backup_type).AppendLine();
                }

                if (supblk.last_orphan > 0)
                {
                    sb.AppendFormat("Last orphaned inode is {0}", supblk.last_orphan).AppendLine();
                }
                else
                {
                    sb.AppendLine("There are no orphaned inodes");
                }
            }

            if (ext4)
            {
                if (supblk.snapshot_id > 0)
                {
                    sb.
                    AppendFormat("Active snapshot has ID {0}, on inode {1}, with {2} blocks reserved, list starting on block {3}",
                                 supblk.snapshot_id, supblk.snapshot_inum, supblk.snapshot_blocks,
                                 supblk.snapshot_list).AppendLine();
                }

                if (supblk.error_count > 0)
                {
                    sb.AppendFormat("{0} errors registered", supblk.error_count).AppendLine();

                    sb.AppendFormat("First error occurred on {0}, last on {1}",
                                    DateHandlers.UnixUnsignedToDateTime(supblk.first_error_t),
                                    DateHandlers.UnixUnsignedToDateTime(supblk.last_error_t)).AppendLine();

                    sb.AppendFormat("First error inode is {0}, last is {1}", supblk.first_error_inode,
                                    supblk.last_error_inode).AppendLine();

                    sb.AppendFormat("First error block is {0}, last is {1}", supblk.first_error_block,
                                    supblk.last_error_block).AppendLine();

                    sb.AppendFormat("First error function is \"{0}\", last is \"{1}\"", supblk.first_error_func,
                                    supblk.last_error_func).AppendLine();
                }
            }

            sb.AppendFormat("Flags…:").AppendLine();

            if ((supblk.flags & EXT2_FLAGS_SIGNED_HASH) == EXT2_FLAGS_SIGNED_HASH)
            {
                sb.AppendLine("Signed directory hash is in use");
            }

            if ((supblk.flags & EXT2_FLAGS_UNSIGNED_HASH) == EXT2_FLAGS_UNSIGNED_HASH)
            {
                sb.AppendLine("Unsigned directory hash is in use");
            }

            if ((supblk.flags & EXT2_FLAGS_TEST_FILESYS) == EXT2_FLAGS_TEST_FILESYS)
            {
                sb.AppendLine("Volume is testing development code");
            }

            if ((supblk.flags & 0xFFFFFFF8) != 0)
            {
                sb.AppendFormat("Unknown set flags: {0:X8}", supblk.flags);
            }

            sb.AppendLine();

            sb.AppendFormat("Default mount options…:").AppendLine();

            if ((supblk.default_mnt_opts & EXT2_DEFM_DEBUG) == EXT2_DEFM_DEBUG)
            {
                sb.AppendLine("(debug): Enable debugging code");
            }

            if ((supblk.default_mnt_opts & EXT2_DEFM_BSDGROUPS) == EXT2_DEFM_BSDGROUPS)
            {
                sb.AppendLine("(bsdgroups): Emulate BSD behaviour when creating new files");
            }

            if ((supblk.default_mnt_opts & EXT2_DEFM_XATTR_USER) == EXT2_DEFM_XATTR_USER)
            {
                sb.AppendLine("(user_xattr): Enable user-specified extended attributes");
            }

            if ((supblk.default_mnt_opts & EXT2_DEFM_ACL) == EXT2_DEFM_ACL)
            {
                sb.AppendLine("(acl): Enable POSIX ACLs");
            }

            if ((supblk.default_mnt_opts & EXT2_DEFM_UID16) == EXT2_DEFM_UID16)
            {
                sb.AppendLine("(uid16): Disable 32bit UIDs and GIDs");
            }

            if ((supblk.default_mnt_opts & EXT3_DEFM_JMODE_DATA) == EXT3_DEFM_JMODE_DATA)
            {
                sb.AppendLine("(journal_data): Journal data and metadata");
            }

            if ((supblk.default_mnt_opts & EXT3_DEFM_JMODE_ORDERED) == EXT3_DEFM_JMODE_ORDERED)
            {
                sb.AppendLine("(journal_data_ordered): Write data before journaling metadata");
            }

            if ((supblk.default_mnt_opts & EXT3_DEFM_JMODE_WBACK) == EXT3_DEFM_JMODE_WBACK)
            {
                sb.AppendLine("(journal_data_writeback): Write journal before data");
            }

            if ((supblk.default_mnt_opts & 0xFFFFFE20) != 0)
            {
                sb.AppendFormat("Unknown set default mount options: {0:X8}", supblk.default_mnt_opts);
            }

            sb.AppendLine();

            sb.AppendFormat("Compatible features…:").AppendLine();

            if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_DIR_PREALLOC) == EXT2_FEATURE_COMPAT_DIR_PREALLOC)
            {
                sb.AppendLine("Pre-allocate directories");
            }

            if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES) == EXT2_FEATURE_COMPAT_IMAGIC_INODES)
            {
                sb.AppendLine("imagic inodes ?");
            }

            if ((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL)
            {
                sb.AppendLine("Has journal (ext3)");
            }

            if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) == EXT2_FEATURE_COMPAT_EXT_ATTR)
            {
                sb.AppendLine("Has extended attribute blocks");
            }

            if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_RESIZE_INO) == EXT2_FEATURE_COMPAT_RESIZE_INO)
            {
                sb.AppendLine("Has online filesystem resize reservations");
            }

            if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) == EXT2_FEATURE_COMPAT_DIR_INDEX)
            {
                sb.AppendLine("Can use hashed indexes on directories");
            }

            if ((supblk.ftr_compat & 0xFFFFFFC0) != 0)
            {
                sb.AppendFormat("Unknown compatible features: {0:X8}", supblk.ftr_compat);
            }

            sb.AppendLine();

            sb.AppendFormat("Compatible features if read-only…:").AppendLine();

            if ((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) == EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
            {
                sb.AppendLine("Reduced number of superblocks");
            }

            if ((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
            {
                sb.AppendLine("Can have files bigger than 2GiB");
            }

            if ((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_BTREE_DIR) == EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
            {
                sb.AppendLine("Uses B-Tree for directories");
            }

            if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) == EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
            {
                sb.AppendLine("Can have files bigger than 2TiB (ext4)");
            }

            if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) == EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
            {
                sb.AppendLine("Group descriptor checksums and sparse inode table (ext4)");
            }

            if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) == EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
            {
                sb.AppendLine("More than 32000 directory entries (ext4)");
            }

            if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) == EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
            {
                sb.AppendLine("Supports nanosecond timestamps and creation time (ext4)");
            }

            if ((supblk.ftr_ro_compat & 0xFFFFFF80) != 0)
            {
                sb.AppendFormat("Unknown read-only compatible features: {0:X8}", supblk.ftr_ro_compat);
            }

            sb.AppendLine();

            sb.AppendFormat("Incompatible features…:").AppendLine();

            if ((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) == EXT2_FEATURE_INCOMPAT_COMPRESSION)
            {
                sb.AppendLine("Uses compression");
            }

            if ((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE) == EXT2_FEATURE_INCOMPAT_FILETYPE)
            {
                sb.AppendLine("Filetype in directory entries");
            }

            if ((supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) == EXT3_FEATURE_INCOMPAT_RECOVER)
            {
                sb.AppendLine("Journal needs recovery (ext3)");
            }

            if ((supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
            {
                sb.AppendLine("Has journal on another device (ext3)");
            }

            if ((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_META_BG) == EXT2_FEATURE_INCOMPAT_META_BG)
            {
                sb.AppendLine("Reduced block group backups");
            }

            if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EXTENTS) == EXT4_FEATURE_INCOMPAT_EXTENTS)
            {
                sb.AppendLine("Volume use extents (ext4)");
            }

            if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT)
            {
                sb.AppendLine("Supports volumes bigger than 2^32 blocks (ext4)");
            }

            if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP) == EXT4_FEATURE_INCOMPAT_MMP)
            {
                sb.AppendLine("Multi-mount protection (ext4)");
            }

            if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) == EXT4_FEATURE_INCOMPAT_FLEX_BG)
            {
                sb.AppendLine("Flexible block group metadata location (ext4)");
            }

            if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE) == EXT4_FEATURE_INCOMPAT_EA_INODE)
            {
                sb.AppendLine("Extended attributes can reside in inode (ext4)");
            }

            if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA) == EXT4_FEATURE_INCOMPAT_DIRDATA)
            {
                sb.AppendLine("Data can reside in directory entry (ext4)");
            }

            if ((supblk.ftr_incompat & 0xFFFFF020) != 0)
            {
                sb.AppendFormat("Unknown incompatible features: {0:X8}", supblk.ftr_incompat);
            }

            information = sb.ToString();
        }
Esempio n. 22
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";
            var sbInformation = new StringBuilder();

            uint magic = 0;
            uint sb_size_in_sectors;

            byte[] ufs_sb_sectors;
            ulong  sb_offset     = partition.Start;
            bool   fs_type_42bsd = false;
            bool   fs_type_43bsd = false;
            bool   fs_type_44bsd = false;
            bool   fs_type_ufs   = false;
            bool   fs_type_ufs2  = false;
            bool   fs_type_sun   = false;
            bool   fs_type_sun86 = false;

            if (imagePlugin.Info.SectorSize == 2336 ||
                imagePlugin.Info.SectorSize == 2352 ||
                imagePlugin.Info.SectorSize == 2448)
            {
                sb_size_in_sectors = block_size / 2048;
            }
            else
            {
                sb_size_in_sectors = block_size / imagePlugin.Info.SectorSize;
            }

            ulong[] locations =
            {
                sb_start_floppy,                    sb_start_boot,                       sb_start_long_boot, sb_start_piggy, sb_start_att_dsdd,
                8192 / imagePlugin.Info.SectorSize, 65536 / imagePlugin.Info.SectorSize,
                262144 / imagePlugin.Info.SectorSize
            };

            foreach (ulong loc in locations.Where(loc => partition.End > partition.Start + loc + sb_size_in_sectors))
            {
                ufs_sb_sectors = imagePlugin.ReadSectors(partition.Start + loc, sb_size_in_sectors);
                magic          = BitConverter.ToUInt32(ufs_sb_sectors, 0x055C);

                if (magic == UFS_MAGIC ||
                    magic == UFS_CIGAM ||
                    magic == UFS_MAGIC_BW ||
                    magic == UFS_CIGAM_BW ||
                    magic == UFS2_MAGIC ||
                    magic == UFS2_CIGAM ||
                    magic == UFS_BAD_MAGIC ||
                    magic == UFS_BAD_CIGAM)
                {
                    sb_offset = partition.Start + loc;

                    break;
                }

                magic = 0;
            }

            if (magic == 0)
            {
                information = "Not a UFS filesystem, I shouldn't have arrived here!";

                return;
            }

            XmlFsType = new FileSystemType();

            switch (magic)
            {
            case UFS_MAGIC:
                sbInformation.AppendLine("UFS filesystem");
                XmlFsType.Type = "UFS";

                break;

            case UFS_CIGAM:
                sbInformation.AppendLine("Big-endian UFS filesystem");
                XmlFsType.Type = "UFS";

                break;

            case UFS_MAGIC_BW:
                sbInformation.AppendLine("BorderWare UFS filesystem");
                XmlFsType.Type = "UFS";

                break;

            case UFS_CIGAM_BW:
                sbInformation.AppendLine("Big-endian BorderWare UFS filesystem");
                XmlFsType.Type = "UFS";

                break;

            case UFS2_MAGIC:
                sbInformation.AppendLine("UFS2 filesystem");
                XmlFsType.Type = "UFS2";

                break;

            case UFS2_CIGAM:
                sbInformation.AppendLine("Big-endian UFS2 filesystem");
                XmlFsType.Type = "UFS2";

                break;

            case UFS_BAD_MAGIC:
                sbInformation.AppendLine("Incompletely initialized UFS filesystem");
                sbInformation.AppendLine("BEWARE!!! Following information may be completely wrong!");
                XmlFsType.Type = "UFS";

                break;

            case UFS_BAD_CIGAM:
                sbInformation.AppendLine("Incompletely initialized big-endian UFS filesystem");
                sbInformation.AppendLine("BEWARE!!! Following information may be completely wrong!");
                XmlFsType.Type = "UFS";

                break;
            }

            // Fun with seeking follows on superblock reading!
            ufs_sb_sectors = imagePlugin.ReadSectors(sb_offset, sb_size_in_sectors);

            SuperBlock sb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(ufs_sb_sectors);

            SuperBlock bs_sfu = Marshal.ByteArrayToStructureBigEndian <SuperBlock>(ufs_sb_sectors);

            if ((bs_sfu.fs_magic == UFS_MAGIC && sb.fs_magic == UFS_CIGAM) ||
                (bs_sfu.fs_magic == UFS_MAGIC_BW && sb.fs_magic == UFS_CIGAM_BW) ||
                (bs_sfu.fs_magic == UFS2_MAGIC && sb.fs_magic == UFS2_CIGAM) ||
                (bs_sfu.fs_magic == UFS_BAD_MAGIC && sb.fs_magic == UFS_BAD_CIGAM))
            {
                sb = bs_sfu;
                sb.fs_old_cstotal.cs_nbfree  = Swapping.Swap(sb.fs_old_cstotal.cs_nbfree);
                sb.fs_old_cstotal.cs_ndir    = Swapping.Swap(sb.fs_old_cstotal.cs_ndir);
                sb.fs_old_cstotal.cs_nffree  = Swapping.Swap(sb.fs_old_cstotal.cs_nffree);
                sb.fs_old_cstotal.cs_nifree  = Swapping.Swap(sb.fs_old_cstotal.cs_nifree);
                sb.fs_cstotal.cs_numclusters = Swapping.Swap(sb.fs_cstotal.cs_numclusters);
                sb.fs_cstotal.cs_nbfree      = Swapping.Swap(sb.fs_cstotal.cs_nbfree);
                sb.fs_cstotal.cs_ndir        = Swapping.Swap(sb.fs_cstotal.cs_ndir);
                sb.fs_cstotal.cs_nffree      = Swapping.Swap(sb.fs_cstotal.cs_nffree);
                sb.fs_cstotal.cs_nifree      = Swapping.Swap(sb.fs_cstotal.cs_nifree);
                sb.fs_cstotal.cs_spare[0]    = Swapping.Swap(sb.fs_cstotal.cs_spare[0]);
                sb.fs_cstotal.cs_spare[1]    = Swapping.Swap(sb.fs_cstotal.cs_spare[1]);
                sb.fs_cstotal.cs_spare[2]    = Swapping.Swap(sb.fs_cstotal.cs_spare[2]);
            }

            AaruConsole.DebugWriteLine("FFS plugin", "sb offset: 0x{0:X8}", sb_offset);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_rlink: 0x{0:X8}", sb.fs_rlink);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_sblkno: 0x{0:X8}", sb.fs_sblkno);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_cblkno: 0x{0:X8}", sb.fs_cblkno);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_iblkno: 0x{0:X8}", sb.fs_iblkno);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_dblkno: 0x{0:X8}", sb.fs_dblkno);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_size: 0x{0:X8}", sb.fs_size);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_dsize: 0x{0:X8}", sb.fs_dsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_ncg: 0x{0:X8}", sb.fs_ncg);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_bsize: 0x{0:X8}", sb.fs_bsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fsize: 0x{0:X8}", sb.fs_fsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_frag: 0x{0:X8}", sb.fs_frag);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_minfree: 0x{0:X8}", sb.fs_minfree);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_bmask: 0x{0:X8}", sb.fs_bmask);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fmask: 0x{0:X8}", sb.fs_fmask);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_bshift: 0x{0:X8}", sb.fs_bshift);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fshift: 0x{0:X8}", sb.fs_fshift);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_maxcontig: 0x{0:X8}", sb.fs_maxcontig);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_maxbpg: 0x{0:X8}", sb.fs_maxbpg);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fragshift: 0x{0:X8}", sb.fs_fragshift);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fsbtodb: 0x{0:X8}", sb.fs_fsbtodb);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_sbsize: 0x{0:X8}", sb.fs_sbsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_csmask: 0x{0:X8}", sb.fs_csmask);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_csshift: 0x{0:X8}", sb.fs_csshift);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_nindir: 0x{0:X8}", sb.fs_nindir);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_inopb: 0x{0:X8}", sb.fs_inopb);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_optim: 0x{0:X8}", sb.fs_optim);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_id_1: 0x{0:X8}", sb.fs_id_1);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_id_2: 0x{0:X8}", sb.fs_id_2);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_csaddr: 0x{0:X8}", sb.fs_csaddr);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_cssize: 0x{0:X8}", sb.fs_cssize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_cgsize: 0x{0:X8}", sb.fs_cgsize);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_ipg: 0x{0:X8}", sb.fs_ipg);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fpg: 0x{0:X8}", sb.fs_fpg);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_fmod: 0x{0:X2}", sb.fs_fmod);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_clean: 0x{0:X2}", sb.fs_clean);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_ronly: 0x{0:X2}", sb.fs_ronly);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_flags: 0x{0:X2}", sb.fs_flags);
            AaruConsole.DebugWriteLine("FFS plugin", "fs_magic: 0x{0:X8}", sb.fs_magic);

            if (sb.fs_magic == UFS2_MAGIC)
            {
                fs_type_ufs2 = true;
            }
            else
            {
                const uint
                    SunOSEpoch =
                    0x1A54C580;     // We are supposing there cannot be a Sun's fs created before 1/1/1982 00:00:00

                fs_type_43bsd =
                    true; // There is no way of knowing this is the version, but there is of knowing it is not.

                if (sb.fs_link > 0)
                {
                    fs_type_42bsd = true; // It was used in 4.2BSD
                    fs_type_43bsd = false;
                }

                if ((sb.fs_maxfilesize & 0xFFFFFFFF) > SunOSEpoch &&
                    DateHandlers.UnixUnsignedToDateTime(sb.fs_maxfilesize & 0xFFFFFFFF) < DateTime.Now)
                {
                    fs_type_42bsd = false;
                    fs_type_sun   = true;
                    fs_type_43bsd = false;
                }

                // This is for sure, as it is shared with a sectors/track with non-x86 SunOS, Epoch is absurdly high for that
                if (sb.fs_old_npsect > SunOSEpoch &&
                    DateHandlers.UnixToDateTime(sb.fs_old_npsect) < DateTime.Now)
                {
                    fs_type_42bsd = false;
                    fs_type_sun86 = true;
                    fs_type_sun   = false;
                    fs_type_43bsd = false;
                }

                if (sb.fs_cgrotor > 0x00000000 &&
                    (uint)sb.fs_cgrotor < 0xFFFFFFFF)
                {
                    fs_type_42bsd = false;
                    fs_type_sun   = false;
                    fs_type_sun86 = false;
                    fs_type_ufs   = true;
                    fs_type_43bsd = false;
                }

                // 4.3BSD code does not use these fields, they are always set up to 0
                fs_type_43bsd &= sb.fs_id_2 == 0 && sb.fs_id_1 == 0;

                // This is the only 4.4BSD inode format
                fs_type_44bsd |= sb.fs_old_inodefmt == 2;
            }

            if (!fs_type_ufs2)
            {
                sbInformation.AppendLine("There are a lot of variants of UFS using overlapped values on same fields");

                sbInformation.
                AppendLine("I will try to guess which one it is, but unless it's UFS2, I may be surely wrong");
            }

            if (fs_type_42bsd)
            {
                sbInformation.AppendLine("Guessed as 42BSD FFS");
            }

            if (fs_type_43bsd)
            {
                sbInformation.AppendLine("Guessed as 43BSD FFS");
            }

            if (fs_type_44bsd)
            {
                sbInformation.AppendLine("Guessed as 44BSD FFS");
            }

            if (fs_type_sun)
            {
                sbInformation.AppendLine("Guessed as SunOS FFS");
            }

            if (fs_type_sun86)
            {
                sbInformation.AppendLine("Guessed as SunOS/x86 FFS");
            }

            if (fs_type_ufs)
            {
                sbInformation.AppendLine("Guessed as UFS");
            }

            if (fs_type_42bsd)
            {
                sbInformation.AppendFormat("Linked list of filesystems: 0x{0:X8}", sb.fs_link).AppendLine();
            }

            sbInformation.AppendFormat("Superblock LBA: {0}", sb.fs_sblkno).AppendLine();
            sbInformation.AppendFormat("Cylinder-block LBA: {0}", sb.fs_cblkno).AppendLine();
            sbInformation.AppendFormat("inode-block LBA: {0}", sb.fs_iblkno).AppendLine();
            sbInformation.AppendFormat("First data block LBA: {0}", sb.fs_dblkno).AppendLine();
            sbInformation.AppendFormat("Cylinder group offset in cylinder: {0}", sb.fs_old_cgoffset).AppendLine();

            sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(sb.fs_old_time)).
            AppendLine();

            XmlFsType.ModificationDate          = DateHandlers.UnixToDateTime(sb.fs_old_time);
            XmlFsType.ModificationDateSpecified = true;

            sbInformation.AppendFormat("{0} blocks in volume ({1} bytes)", sb.fs_old_size,
                                       (long)sb.fs_old_size * sb.fs_fsize).AppendLine();

            XmlFsType.Clusters    = (ulong)sb.fs_old_size;
            XmlFsType.ClusterSize = (uint)sb.fs_fsize;

            sbInformation.AppendFormat("{0} data blocks in volume ({1} bytes)", sb.fs_old_dsize,
                                       (long)sb.fs_old_dsize * sb.fs_fsize).AppendLine();

            sbInformation.AppendFormat("{0} cylinder groups in volume", sb.fs_ncg).AppendLine();
            sbInformation.AppendFormat("{0} bytes in a basic block", sb.fs_bsize).AppendLine();
            sbInformation.AppendFormat("{0} bytes in a frag block", sb.fs_fsize).AppendLine();
            sbInformation.AppendFormat("{0} frags in a block", sb.fs_frag).AppendLine();
            sbInformation.AppendFormat("{0}% of blocks must be free", sb.fs_minfree).AppendLine();
            sbInformation.AppendFormat("{0}ms for optimal next block", sb.fs_old_rotdelay).AppendLine();

            sbInformation.AppendFormat("disk rotates {0} times per second ({1}rpm)", sb.fs_old_rps, sb.fs_old_rps * 60).
            AppendLine();

            /*          sbInformation.AppendFormat("fs_bmask: 0x{0:X8}", sb.fs_bmask).AppendLine();
             *          sbInformation.AppendFormat("fs_fmask: 0x{0:X8}", sb.fs_fmask).AppendLine();
             *          sbInformation.AppendFormat("fs_bshift: 0x{0:X8}", sb.fs_bshift).AppendLine();
             *          sbInformation.AppendFormat("fs_fshift: 0x{0:X8}", sb.fs_fshift).AppendLine();*/
            sbInformation.AppendFormat("{0} contiguous blocks at maximum", sb.fs_maxcontig).AppendLine();
            sbInformation.AppendFormat("{0} blocks per cylinder group at maximum", sb.fs_maxbpg).AppendLine();
            sbInformation.AppendFormat("Superblock is {0} bytes", sb.fs_sbsize).AppendLine();
            sbInformation.AppendFormat("NINDIR: 0x{0:X8}", sb.fs_nindir).AppendLine();
            sbInformation.AppendFormat("INOPB: 0x{0:X8}", sb.fs_inopb).AppendLine();
            sbInformation.AppendFormat("NSPF: 0x{0:X8}", sb.fs_old_nspf).AppendLine();

            switch (sb.fs_optim)
            {
            case 0:
                sbInformation.AppendLine("Filesystem will minimize allocation time");

                break;

            case 1:
                sbInformation.AppendLine("Filesystem will minimize volume fragmentation");

                break;

            default:
                sbInformation.AppendFormat("Unknown optimization value: 0x{0:X8}", sb.fs_optim).AppendLine();

                break;
            }

            if (fs_type_sun)
            {
                sbInformation.AppendFormat("{0} sectors/track", sb.fs_old_npsect).AppendLine();
            }
            else if (fs_type_sun86)
            {
                sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(sb.fs_old_npsect)).
                AppendLine();
            }

            sbInformation.AppendFormat("Hardware sector interleave: {0}", sb.fs_old_interleave).AppendLine();
            sbInformation.AppendFormat("Sector 0 skew: {0}/track", sb.fs_old_trackskew).AppendLine();

            if (!fs_type_43bsd &&
                sb.fs_id_1 > 0 &&
                sb.fs_id_2 > 0)
            {
                sbInformation.AppendFormat("Volume ID: 0x{0:X8}{1:X8}", sb.fs_id_1, sb.fs_id_2).AppendLine();
            }
            else if (fs_type_43bsd &&
                     sb.fs_id_1 > 0 &&
                     sb.fs_id_2 > 0)
            {
                sbInformation.AppendFormat("{0} µsec for head switch", sb.fs_id_1).AppendLine();
                sbInformation.AppendFormat("{0} µsec for track-to-track seek", sb.fs_id_2).AppendLine();
            }

            sbInformation.AppendFormat("Cylinder group summary LBA: {0}", sb.fs_old_csaddr).AppendLine();
            sbInformation.AppendFormat("{0} bytes in cylinder group summary", sb.fs_cssize).AppendLine();
            sbInformation.AppendFormat("{0} bytes in cylinder group", sb.fs_cgsize).AppendLine();
            sbInformation.AppendFormat("{0} tracks/cylinder", sb.fs_old_ntrak).AppendLine();
            sbInformation.AppendFormat("{0} sectors/track", sb.fs_old_nsect).AppendLine();
            sbInformation.AppendFormat("{0} sectors/cylinder", sb.fs_old_spc).AppendLine();
            sbInformation.AppendFormat("{0} cylinder in volume", sb.fs_old_ncyl).AppendLine();
            sbInformation.AppendFormat("{0} cylinders/group", sb.fs_old_cpg).AppendLine();
            sbInformation.AppendFormat("{0} inodes per cylinder group", sb.fs_ipg).AppendLine();
            sbInformation.AppendFormat("{0} blocks per group", sb.fs_fpg / sb.fs_frag).AppendLine();
            sbInformation.AppendFormat("{0} directories", sb.fs_old_cstotal.cs_ndir).AppendLine();

            sbInformation.AppendFormat("{0} free blocks ({1} bytes)", sb.fs_old_cstotal.cs_nbfree,
                                       (long)sb.fs_old_cstotal.cs_nbfree * sb.fs_fsize).AppendLine();

            XmlFsType.FreeClusters          = (ulong)sb.fs_old_cstotal.cs_nbfree;
            XmlFsType.FreeClustersSpecified = true;
            sbInformation.AppendFormat("{0} free inodes", sb.fs_old_cstotal.cs_nifree).AppendLine();
            sbInformation.AppendFormat("{0} free frags", sb.fs_old_cstotal.cs_nffree).AppendLine();

            if (sb.fs_fmod == 1)
            {
                sbInformation.AppendLine("Superblock is under modification");
                XmlFsType.Dirty = true;
            }

            if (sb.fs_clean == 1)
            {
                sbInformation.AppendLine("Volume is clean");
            }

            if (sb.fs_ronly == 1)
            {
                sbInformation.AppendLine("Volume is read-only");
            }

            sbInformation.AppendFormat("Volume flags: 0x{0:X2}", sb.fs_flags).AppendLine();

            if (fs_type_ufs)
            {
                sbInformation.AppendFormat("Volume last mounted on \"{0}\"", StringHandlers.CToString(sb.fs_fsmnt)).
                AppendLine();
            }
            else if (fs_type_ufs2)
            {
                sbInformation.AppendFormat("Volume last mounted on \"{0}\"", StringHandlers.CToString(sb.fs_fsmnt)).
                AppendLine();

                sbInformation.AppendFormat("Volume name: \"{0}\"", StringHandlers.CToString(sb.fs_volname)).
                AppendLine();

                XmlFsType.VolumeName = StringHandlers.CToString(sb.fs_volname);
                sbInformation.AppendFormat("Volume ID: 0x{0:X16}", sb.fs_swuid).AppendLine();

                //xmlFSType.VolumeSerial = string.Format("{0:X16}", sb.fs_swuid);
                sbInformation.AppendFormat("Last searched cylinder group: {0}", sb.fs_cgrotor).AppendLine();
                sbInformation.AppendFormat("{0} contiguously allocated directories", sb.fs_contigdirs).AppendLine();
                sbInformation.AppendFormat("Standard superblock LBA: {0}", sb.fs_sblkno).AppendLine();
                sbInformation.AppendFormat("{0} directories", sb.fs_cstotal.cs_ndir).AppendLine();

                sbInformation.AppendFormat("{0} free blocks ({1} bytes)", sb.fs_cstotal.cs_nbfree,
                                           sb.fs_cstotal.cs_nbfree * sb.fs_fsize).AppendLine();

                XmlFsType.FreeClusters          = (ulong)sb.fs_cstotal.cs_nbfree;
                XmlFsType.FreeClustersSpecified = true;
                sbInformation.AppendFormat("{0} free inodes", sb.fs_cstotal.cs_nifree).AppendLine();
                sbInformation.AppendFormat("{0} free frags", sb.fs_cstotal.cs_nffree).AppendLine();
                sbInformation.AppendFormat("{0} free clusters", sb.fs_cstotal.cs_numclusters).AppendLine();

                sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(sb.fs_time)).
                AppendLine();

                XmlFsType.ModificationDate          = DateHandlers.UnixToDateTime(sb.fs_time);
                XmlFsType.ModificationDateSpecified = true;

                sbInformation.AppendFormat("{0} blocks ({1} bytes)", sb.fs_size, sb.fs_size * sb.fs_fsize).AppendLine();

                XmlFsType.Clusters = (ulong)sb.fs_size;

                sbInformation.AppendFormat("{0} data blocks ({1} bytes)", sb.fs_dsize, sb.fs_dsize * sb.fs_fsize).
                AppendLine();

                sbInformation.AppendFormat("Cylinder group summary area LBA: {0}", sb.fs_csaddr).AppendLine();
                sbInformation.AppendFormat("{0} blocks pending of being freed", sb.fs_pendingblocks).AppendLine();
                sbInformation.AppendFormat("{0} inodes pending of being freed", sb.fs_pendinginodes).AppendLine();
            }

            if (fs_type_sun)
            {
                sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(sb.fs_old_npsect)).
                AppendLine();
            }
            else if (fs_type_sun86)
            {
                sbInformation.AppendFormat("{0} sectors/track", sb.fs_state).AppendLine();
            }
            else if (fs_type_44bsd)
            {
                sbInformation.AppendFormat("{0} blocks on cluster summary array", sb.fs_contigsumsize).AppendLine();

                sbInformation.AppendFormat("Maximum length of a symbolic link: {0}", sb.fs_maxsymlinklen).AppendLine();

                sbInformation.AppendFormat("A file can be {0} bytes at max", sb.fs_maxfilesize).AppendLine();

                sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(sb.fs_state)).
                AppendLine();
            }

            if (sb.fs_old_nrpos > 0)
            {
                sbInformation.AppendFormat("{0} rotational positions", sb.fs_old_nrpos).AppendLine();
            }

            if (sb.fs_old_rotbloff > 0)
            {
                sbInformation.AppendFormat("{0} blocks per rotation", sb.fs_old_rotbloff).AppendLine();
            }

            information = sbInformation.ToString();
        }
Esempio n. 23
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
            var sbInformation = new StringBuilder();

            XmlFsType   = new FileSystemType();
            information = "";

            ulong sbSectorOff  = 0x10000 / imagePlugin.Info.SectorSize;
            uint  sbSectorSize = 0x1000 / imagePlugin.Info.SectorSize;

            byte[] sector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize);

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

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.checksum = {0}", btrfsSb.checksum);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.uuid = {0}", btrfsSb.uuid);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.pba = {0}", btrfsSb.pba);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.flags = {0}", btrfsSb.flags);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.magic = {0}", btrfsSb.magic);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.generation = {0}", btrfsSb.generation);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_lba = {0}", btrfsSb.root_lba);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_lba = {0}", btrfsSb.chunk_lba);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_lba = {0}", btrfsSb.log_lba);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_root_transid = {0}", btrfsSb.log_root_transid);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.total_bytes = {0}", btrfsSb.total_bytes);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.bytes_used = {0}", btrfsSb.bytes_used);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_dir_objectid = {0}", btrfsSb.root_dir_objectid);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.num_devices = {0}", btrfsSb.num_devices);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.sectorsize = {0}", btrfsSb.sectorsize);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.nodesize = {0}", btrfsSb.nodesize);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.leafsize = {0}", btrfsSb.leafsize);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.stripesize = {0}", btrfsSb.stripesize);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.n = {0}", btrfsSb.n);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_root_generation = {0}",
                                       btrfsSb.chunk_root_generation);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.compat_flags = 0x{0:X16}", btrfsSb.compat_flags);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.compat_ro_flags = 0x{0:X16}", btrfsSb.compat_ro_flags);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.incompat_flags = 0x{0:X16}", btrfsSb.incompat_flags);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.csum_type = {0}", btrfsSb.csum_type);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_level = {0}", btrfsSb.root_level);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_root_level = {0}", btrfsSb.chunk_root_level);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_root_level = {0}", btrfsSb.log_root_level);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.id = 0x{0:X16}", btrfsSb.dev_item.id);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.bytes = {0}", btrfsSb.dev_item.bytes);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.used = {0}", btrfsSb.dev_item.used);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.optimal_align = {0}",
                                       btrfsSb.dev_item.optimal_align);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.optimal_width = {0}",
                                       btrfsSb.dev_item.optimal_width);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.minimal_size = {0}",
                                       btrfsSb.dev_item.minimal_size);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.type = {0}", btrfsSb.dev_item.type);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.generation = {0}",
                                       btrfsSb.dev_item.generation);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.start_offset = {0}",
                                       btrfsSb.dev_item.start_offset);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.dev_group = {0}", btrfsSb.dev_item.dev_group);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.seek_speed = {0}",
                                       btrfsSb.dev_item.seek_speed);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.bandwitdh = {0}", btrfsSb.dev_item.bandwitdh);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.device_uuid = {0}",
                                       btrfsSb.dev_item.device_uuid);

            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.uuid = {0}", btrfsSb.dev_item.uuid);
            AaruConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.label = {0}", btrfsSb.label);

            sbInformation.AppendLine("B-tree filesystem");
            sbInformation.AppendFormat("UUID: {0}", btrfsSb.uuid).AppendLine();
            sbInformation.AppendFormat("This superblock resides on physical block {0}", btrfsSb.pba).AppendLine();
            sbInformation.AppendFormat("Root tree starts at LBA {0}", btrfsSb.root_lba).AppendLine();
            sbInformation.AppendFormat("Chunk tree starts at LBA {0}", btrfsSb.chunk_lba).AppendLine();
            sbInformation.AppendFormat("Log tree starts at LBA {0}", btrfsSb.log_lba).AppendLine();

            sbInformation.AppendFormat("Volume has {0} bytes spanned in {1} devices", btrfsSb.total_bytes,
                                       btrfsSb.num_devices).AppendLine();

            sbInformation.AppendFormat("Volume has {0} bytes used", btrfsSb.bytes_used).AppendLine();
            sbInformation.AppendFormat("{0} bytes/sector", btrfsSb.sectorsize).AppendLine();
            sbInformation.AppendFormat("{0} bytes/node", btrfsSb.nodesize).AppendLine();
            sbInformation.AppendFormat("{0} bytes/leaf", btrfsSb.leafsize).AppendLine();
            sbInformation.AppendFormat("{0} bytes/stripe", btrfsSb.stripesize).AppendLine();
            sbInformation.AppendFormat("Flags: 0x{0:X}", btrfsSb.flags).AppendLine();
            sbInformation.AppendFormat("Compatible flags: 0x{0:X}", btrfsSb.compat_flags).AppendLine();
            sbInformation.AppendFormat("Read-only compatible flags: 0x{0:X}", btrfsSb.compat_ro_flags).AppendLine();
            sbInformation.AppendFormat("Incompatible flags: 0x{0:X}", btrfsSb.incompat_flags).AppendLine();
            sbInformation.AppendFormat("Device's UUID: {0}", btrfsSb.dev_item.uuid).AppendLine();
            sbInformation.AppendFormat("Volume label: {0}", btrfsSb.label).AppendLine();

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                Clusters = btrfsSb.total_bytes / btrfsSb.sectorsize, ClusterSize = btrfsSb.sectorsize,
                FreeClustersSpecified = true, VolumeName = btrfsSb.label,
                VolumeSerial          = $"{btrfsSb.uuid}",
                VolumeSetIdentifier   = $"{btrfsSb.dev_item.device_uuid}", Type = Name
            };

            XmlFsType.FreeClusters = XmlFsType.Clusters - (btrfsSb.bytes_used / btrfsSb.sectorsize);
        }
Esempio n. 24
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();

            ulong sector = AFS_BOOTBLOCK_SIZE / imagePlugin.Info.SectorSize;
            uint  offset = AFS_BOOTBLOCK_SIZE % imagePlugin.Info.SectorSize;
            uint  run    = 1;

            if (imagePlugin.Info.SectorSize < AFS_SUPERBLOCK_SIZE)
            {
                run = AFS_SUPERBLOCK_SIZE / imagePlugin.Info.SectorSize;
            }

            byte[] tmp      = imagePlugin.ReadSectors(sector + partition.Start, run);
            byte[] sbSector = new byte[AFS_SUPERBLOCK_SIZE];
            Array.Copy(tmp, offset, sbSector, 0, AFS_SUPERBLOCK_SIZE);

            SuperBlock afsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector);

            sb.AppendLine("Atheos filesystem");

            if (afsSb.flags == 1)
            {
                sb.AppendLine("Filesystem is read-only");
            }

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

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

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

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

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

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

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

            sb.AppendFormat("Journal starts in byte {0} and has {1} bytes in {2} blocks", afsSb.log_start,
                            afsSb.log_size, afsSb.log_valid_blocks).AppendLine();

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

            sb.
            AppendFormat("Directory containing files scheduled for deletion's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
                         afsSb.deleted_start, afsSb.deleted_ag, afsSb.deleted_len,
                         afsSb.deleted_len * afsSb.block_size).AppendLine();

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

            sb.AppendFormat("{0} blocks for bootloader ({1} bytes)", afsSb.boot_size,
                            afsSb.boot_size * afsSb.block_size).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Clusters              = (ulong)afsSb.num_blocks,
                ClusterSize           = afsSb.block_size,
                Dirty                 = false,
                FreeClusters          = (ulong)(afsSb.num_blocks - afsSb.used_blocks),
                FreeClustersSpecified = true,
                Type       = "AtheOS filesystem",
                VolumeName = StringHandlers.CToString(afsSb.name, Encoding)
            };
        }
Esempio n. 25
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();
        }
Esempio n. 26
0
File: Ext2.cs Progetto: zer09/Cosmos
        private void Initialize()
        {
            Console.WriteLine("Start Ext2.Initialize");
            mBuffer = new byte[mBackend.BlockSize];
            fixed(byte *xBufferAddress = &mBuffer[0])
            {
                mBufferAddress = xBufferAddress;
            }

            // first get the superblock;
            var mBufferAsSuperblock = (SuperBlock *)mBufferAddress;
            int xAddr = (int)mBufferAddress;

            Console.WriteLine("Buffer address: " + xAddr);
            Console.WriteLine("Start reading superblock");
            mBackend.ReadBlock(2,
                               mBuffer);
            Console.WriteLine("End reading");
            mSuperblock = *mBufferAsSuperblock;
            DebugUtil.Send_Ext2SuperBlock(mSuperblock);
            // read the group descriptors
            Console.WriteLine("INodeCount: " + mSuperblock.INodesCount);
            Console.WriteLine("INode#1: " + mBufferAddress[0]);
            Console.WriteLine("INode#2: " + mBufferAddress[1]);
            Console.WriteLine("INode#3: " + mBufferAddress[2]);
            Console.WriteLine("INode#4: " + mBufferAddress[3]);

            Console.WriteLine("BlockCount: " + mSuperblock.BlockCount);
            Console.WriteLine("INodesPerGroup: " + (int)mSuperblock.INodesPerGroup);
            if (mSuperblock.INodesPerGroup == 0x4000)
            {
                Console.WriteLine("INodesPerGroup has correct value!");
            }
            uint xGroupDescriptorCount = mSuperblock.INodesCount / mSuperblock.INodesPerGroup;

            mGroupDescriptors = new GroupDescriptor[xGroupDescriptorCount];
            var xDescriptorPtr = (GroupDescriptor *)mBufferAddress;

            Console.WriteLine("Process GroupDescriptors: " + xGroupDescriptorCount);
            //Console.ReadLine();
            for (int i = 0; i < xGroupDescriptorCount; i++)
            {
                Console.WriteLine("Processing GroupDescriptor " + i);
                uint xATABlock;

                if (BlockSize == 1024)
                {
                    xATABlock = (BlockSize * 2) / mBackend.BlockSize;
                }
                else
                {
                    xATABlock = (BlockSize) / mBackend.BlockSize;
                }

                xATABlock += (uint)(i / 16);
                if ((i % 16) == 0)
                {
                    Console.WriteLine("Read new GroupDescriptorBlock");
                    mBackend.ReadBlock(xATABlock,
                                       mBuffer);
                    Console.WriteLine("End Read");
                }
                mGroupDescriptors[i] = xDescriptorPtr[i % 16];
                Console.WriteLine("End of GroupDescriptor check");
            }
            Console.WriteLine("Send GroupDescriptors to log");
            DebugUtil.Send_Ext2GroupDescriptors(mGroupDescriptors);
        }
Esempio n. 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();

            uint sector = 2;
            uint offset = 0;

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

            bool   minix3 = false;
            int    filenamesize;
            string minixVersion;

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

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

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

            XmlFsType = new FileSystemType();

            bool littleEndian;

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

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

                    break;

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

                    break;

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

                    break;
                }

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

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

                    break;

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

                    break;

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

                    break;

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

                    break;

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

                    break;

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

                    break;

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

                    break;

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

                    break;

                default: return;
                }
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            information = sb.ToString();
        }
        /// <summary>
        /// Writes the file system to an existing stream.
        /// </summary>
        /// <param name="output">The stream to write to.</param>
        /// <remarks>The <c>output</c> stream must support seeking and writing.</remarks>
        public void Build(Stream output)
        {
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }

            if (!output.CanWrite)
            {
                throw new ArgumentException("Output stream must be writable", "output");
            }

            if (!output.CanSeek)
            {
                throw new ArgumentException("Output stream must support seeking", "output");
            }

            _context = new BuilderContext()
            {
                RawStream = output,
                DataBlockSize = DefaultBlockSize,
                IoBuffer = new byte[DefaultBlockSize],
            };

            MetablockWriter inodeWriter = new MetablockWriter();
            MetablockWriter dirWriter = new MetablockWriter();
            FragmentWriter fragWriter = new FragmentWriter(_context);
            IdTableWriter idWriter = new IdTableWriter(_context);

            _context.AllocateInode = AllocateInode;
            _context.AllocateId = idWriter.AllocateId;
            _context.WriteDataBlock = WriteDataBlock;
            _context.WriteFragment = fragWriter.WriteFragment;
            _context.InodeWriter = inodeWriter;
            _context.DirectoryWriter = dirWriter;

            _nextInode = 1;

            SuperBlock superBlock = new SuperBlock();
            superBlock.Magic = SuperBlock.SquashFsMagic;
            superBlock.CreationTime = DateTime.Now;
            superBlock.BlockSize = (uint)_context.DataBlockSize;
            superBlock.Compression = 1; // DEFLATE
            superBlock.BlockSizeLog2 = (ushort)Utilities.Log2(superBlock.BlockSize);
            superBlock.MajorVersion = 4;
            superBlock.MinorVersion = 0;

            output.Position = superBlock.Size;

            GetRoot().Reset();
            GetRoot().Write(_context);
            fragWriter.Flush();
            superBlock.RootInode = GetRoot().InodeRef;
            superBlock.InodesCount = _nextInode - 1;
            superBlock.FragmentsCount = (uint)fragWriter.FragmentCount;
            superBlock.UidGidCount = (ushort)idWriter.IdCount;

            superBlock.InodeTableStart = output.Position;
            inodeWriter.Persist(output);

            superBlock.DirectoryTableStart = output.Position;
            dirWriter.Persist(output);

            if (fragWriter.FragmentCount > 0)
            {
                superBlock.FragmentTableStart = output.Position;
                fragWriter.Persist();
            }
            else
            {
                superBlock.FragmentTableStart = -1;
            }

            superBlock.LookupTableStart = -1;

            if (idWriter.IdCount > 0)
            {
                superBlock.UidGidTableStart = output.Position;
                idWriter.Persist();
            }
            else
            {
                superBlock.UidGidTableStart = -1;
            }

            superBlock.ExtendedAttrsTableStart = -1;

            superBlock.BytesUsed = output.Position;

            // Pad to 4KB
            long end = Utilities.RoundUp(output.Position, 4 * Sizes.OneKiB);
            if (end != output.Position)
            {
                byte[] padding = new byte[(int)(end - output.Position)];
                output.Write(padding, 0, padding.Length);
            }

            // Go back and write the superblock
            output.Position = 0;
            byte[] buffer = new byte[superBlock.Size];
            superBlock.WriteTo(buffer, 0);
            output.Write(buffer, 0, buffer.Length);
            output.Position = end;
        }
Esempio n. 29
0
 public VirtualFileSystem()
 {
     ufdtArr       = new UFDT[Constants.TOTALFILES];
     superBlockObj = new SuperBlock();
     Head          = null;
 }
Esempio n. 30
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            // TODO: Find correct default encoding
            Encoding    = Encoding.ASCII;
            information = "";
            StringBuilder superBlockMetadata = new StringBuilder();

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

            SuperBlock sb = Marshal.ByteArrayToStructureBigEndian <SuperBlock>(sbSector);

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

            superBlockMetadata.AppendFormat("Opera filesystem disc.").AppendLine();
            if (!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_label, Encoding)))
            {
                superBlockMetadata
                .AppendFormat("Volume label: {0}", StringHandlers.CToString(sb.volume_label, Encoding)).AppendLine();
            }
            if (!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_comment, Encoding)))
            {
                superBlockMetadata
                .AppendFormat("Volume comment: {0}", StringHandlers.CToString(sb.volume_comment, Encoding))
                .AppendLine();
            }
            superBlockMetadata.AppendFormat("Volume identifier: 0x{0:X8}", sb.volume_id).AppendLine();
            superBlockMetadata.AppendFormat("Block size: {0} bytes", sb.block_size).AppendLine();
            if (imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 ||
                imagePlugin.Info.SectorSize == 2448)
            {
                if (sb.block_size != 2048)
                {
                    superBlockMetadata
                    .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block",
                                  sb.block_size, 2048);
                }
            }
            else if (imagePlugin.Info.SectorSize != sb.block_size)
            {
                superBlockMetadata
                .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block",
                              sb.block_size, imagePlugin.Info.SectorSize);
            }

            superBlockMetadata
            .AppendFormat("Volume size: {0} blocks, {1} bytes", sb.block_count, sb.block_size * sb.block_count)
            .AppendLine();
            if (sb.block_count > imagePlugin.Info.Sectors)
            {
                superBlockMetadata
                .AppendFormat("WARNING: Filesystem indicates {0} blocks while device indicates {1} blocks",
                              sb.block_count, imagePlugin.Info.Sectors);
            }
            superBlockMetadata.AppendFormat("Root directory identifier: 0x{0:X8}", sb.root_dirid).AppendLine();
            superBlockMetadata.AppendFormat("Root directory block size: {0} bytes", sb.rootdir_bsize).AppendLine();
            superBlockMetadata.AppendFormat("Root directory size: {0} blocks, {1} bytes", sb.rootdir_blocks,
                                            sb.rootdir_bsize * sb.rootdir_blocks).AppendLine();
            superBlockMetadata.AppendFormat("Last root directory copy: {0}", sb.last_root_copy).AppendLine();

            information = superBlockMetadata.ToString();

            XmlFsType = new FileSystemType
            {
                Type        = "Opera",
                VolumeName  = StringHandlers.CToString(sb.volume_label, Encoding),
                ClusterSize = sb.block_size,
                Clusters    = sb.block_count
            };
        }
Esempio n. 31
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.UTF8;
            byte[] sector = imagePlugin.ReadSector(partition.Start);
            uint   magic  = BitConverter.ToUInt32(sector, 0x00);

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

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

                break;

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

                break;
            }

            var sbInformation = new StringBuilder();

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

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

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

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

                break;

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

                break;

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

                break;

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

                break;

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

                break;

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

                break;

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

                break;
            }

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                Type                  = "Squash file system",
                CreationDate          = DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time),
                CreationDateSpecified = true,
                Clusters              = (((partition.End - partition.Start) + 1) * imagePlugin.Info.SectorSize) / sqSb.block_size,
                ClusterSize           = sqSb.block_size,
                Files                 = sqSb.inodes,
                FilesSpecified        = true,
                FreeClusters          = 0,
                FreeClustersSpecified = true
            };
        }
Esempio n. 32
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PdbFile"/> class.
        /// </summary>
        /// <param name="path">Path to PDB file.</param>
        public PdbFile(string path)
        {
            File   = new MMFile(path);
            Reader = new MMFileReader(File);

            // Parse file headers

            // Initialize MSF super block
            SuperBlock = MSF.SuperBlock.Read(Reader);

            SuperBlock.Validate();
            if (File.Length % SuperBlock.BlockSize != 0)
            {
                throw new Exception("File size is not a multiple of block size");
            }

            // Initialize Free Page Map.
            // The Fpm exists either at block 1 or block 2 of the MSF. However, this
            // allows for a maximum of getBlockSize() * 8 blocks bits in the Fpm, and
            // thusly an equal number of total blocks in the file. For a block size
            // of 4KiB (very common), this would yield 32KiB total blocks in file, for a
            // maximum file size of 32KiB * 4KiB = 128MiB. Obviously this won't do, so
            // the Fpm is split across the file at `getBlockSize()` intervals.  As a
            // result, every block whose index is of the form |{1,2} + getBlockSize() * k|
            // for any non-negative integer k is an Fpm block. In theory, we only really
            // need to reserve blocks of the form |{1,2} + getBlockSize() * 8 * k|, but
            // current versions of the MSF format already expect the Fpm to be arranged
            // at getBlockSize() intervals, so we have to be compatible.
            // See the function fpmPn() for more information:
            // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/msf/msf.cpp#L489
            uint fpmIntervals = (SuperBlock.NumBlocks + 8 * SuperBlock.BlockSize - 1) / (8 * SuperBlock.BlockSize);

            uint[] fpmBlocks       = new uint[fpmIntervals];
            uint   currentFpmBlock = SuperBlock.FreeBlockMapBlock;

            for (int i = 0; i < fpmBlocks.Length; i++)
            {
                fpmBlocks[i]     = currentFpmBlock;
                currentFpmBlock += SuperBlock.BlockSize;
            }

            IBinaryReader fpmStream = new MappedBlockBinaryReader <MMFileReader>(fpmBlocks, SuperBlock.BlockSize, (SuperBlock.NumBlocks + 7) / 8, Reader);

            FreePageMap = Reader.ReadByteArray((int)fpmStream.Length);

            // Read directory blocks
            Reader.Position = (long)SuperBlock.BlockMapOffset;
            uint[] directoryBlocks = Reader.ReadUintArray((int)SuperBlock.NumDirectoryBlocks);

            // Parse stream data
            uint      NumStreams      = 0;
            PdbStream directoryStream = new PdbStream(directoryBlocks, SuperBlock.NumDirectoryBytes, this);

            NumStreams = directoryStream.Reader.ReadUint();
            streams    = new PdbStream[NumStreams];
            uint[] streamSizes = directoryStream.Reader.ReadUintArray(streams.Length);
            for (int i = 0; i < streams.Length; i++)
            {
                uint   streamSize = streamSizes[i];
                uint   NumExpectedStreamBlocks = streamSize == uint.MaxValue ? 0 : SuperBlock.BytesToBlocks(streamSize);
                uint[] blocks = directoryStream.Reader.ReadUintArray((int)NumExpectedStreamBlocks);

                foreach (uint block in blocks)
                {
                    ulong blockEndOffset = SuperBlock.BlocksToBytes(block + 1);

                    if (blockEndOffset > (ulong)File.Length)
                    {
                        throw new Exception("Stream block map is corrupt.");
                    }
                }

                streams[i] = new PdbStream(blocks, streamSize, this);
            }

            if (directoryStream.Reader.Position != SuperBlock.NumDirectoryBytes)
            {
                throw new Exception("Not whole directory stream was read");
            }

            dbiStreamCache       = SimpleCache.CreateStruct(() => new DbiStream(streams[(uint)SpecialStream.StreamDBI]));
            pdbSymbolStreamCache = SimpleCache.CreateStruct(() => new SymbolStream(streams[DbiStream.SymbolRecordStreamIndex]));
            tpiStreamCache       = SimpleCache.CreateStruct(() => new TpiStream(streams[(uint)SpecialStream.StreamTPI]));
            ipiStreamCache       = SimpleCache.CreateStruct(() => new TpiStream(streams[(uint)SpecialStream.StreamIPI]));
        }
Esempio n. 33
0
File: extFS.cs Progetto: paulyc/Aaru
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            var sb = new StringBuilder();

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

            ulong sbSectorOff = SB_POS / imagePlugin.Info.SectorSize;
            uint  sbOff       = SB_POS % imagePlugin.Info.SectorSize;

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

            byte[] sblock   = imagePlugin.ReadSector(sbSectorOff + partition.Start);
            byte[] sbSector = new byte[512];
            Array.Copy(sblock, sbOff, sbSector, 0, 512);

            var extSb = new SuperBlock
            {
                inodes        = BitConverter.ToUInt32(sbSector, 0x000),
                zones         = BitConverter.ToUInt32(sbSector, 0x004),
                firstfreeblk  = BitConverter.ToUInt32(sbSector, 0x008),
                freecountblk  = BitConverter.ToUInt32(sbSector, 0x00C),
                firstfreeind  = BitConverter.ToUInt32(sbSector, 0x010),
                freecountind  = BitConverter.ToUInt32(sbSector, 0x014),
                firstdatazone = BitConverter.ToUInt32(sbSector, 0x018),
                logzonesize   = BitConverter.ToUInt32(sbSector, 0x01C),
                maxsize       = BitConverter.ToUInt32(sbSector, 0x020)
            };

            sb.AppendLine("ext filesystem");
            sb.AppendFormat("{0} zones on volume", extSb.zones);
            sb.AppendFormat("{0} free blocks ({1} bytes)", extSb.freecountblk, extSb.freecountblk * 1024);

            sb.AppendFormat("{0} inodes on volume, {1} free ({2}%)", extSb.inodes, extSb.freecountind,
                            (extSb.freecountind * 100) / extSb.inodes);

            sb.AppendFormat("First free inode is {0}", extSb.firstfreeind);
            sb.AppendFormat("First free block is {0}", extSb.firstfreeblk);
            sb.AppendFormat("First data zone is {0}", extSb.firstdatazone);
            sb.AppendFormat("Log zone size: {0}", extSb.logzonesize);
            sb.AppendFormat("Max zone size: {0}", extSb.maxsize);

            XmlFsType = new FileSystemType
            {
                Type                  = "ext",
                FreeClusters          = extSb.freecountblk,
                FreeClustersSpecified = true,
                ClusterSize           = 1024,
                Clusters              = (((partition.End - partition.Start) + 1) * imagePlugin.Info.SectorSize) / 1024
            };

            information = sb.ToString();
        }