예제 #1
0
        public bool VerifyFsChecksum(iQueFsHeader fatHeader, int fatBlockIdx)
        {
            io.Stream.Position = (fatBlockIdx * BLOCK_SZ);

            ushort sum = 0;

            for (int i = 0; i < 0x1FFF; i++)
            {
                sum += io.Reader.ReadUInt16().EndianSwap();
            }

            sum += fatHeader.CheckSum; // should be EndianSwap'd already by ReadFilesystem
            return(sum == 0xCAD7);
        }
예제 #2
0
        private bool ReadFilesystem()
        {
            FsHeaders          = new List <iQueFsHeader>();
            FsBlocks           = new List <int>();
            FsBadBlocks        = new List <int>();
            FsInodes           = new List <List <iQueFsInode> >();
            FsAllocationTables = new List <List <short> >();

            int latestSeqNo = -1;

            for (int i = 0; i < NUM_FAT_BLOCKS; i++)
            {
                var blockNum = (NUM_BLOCKS_IN_FAT - 1) - i; // read FAT area from end to beginning
                SeekToBlock(blockNum);

                io.Stream.Position += FS_HEADER_ADDR;
                var header = io.Reader.ReadStruct <iQueFsHeader>();
                header.EndianSwap();
                if (header.Magic != MAGIC_BBFS) // todo: && header.Magic != MAGIC_BBFL, once we know what BBFL/"linked fats" actually are
                {
                    continue;
                }

                if (!SkipVerifyFsChecksums && InodesOffset == 0) // only care about fs checksum if this is a proper dump and we aren't using hacky InodesOffset hack
                {
                    if (!VerifyFsChecksum(header, blockNum))
                    {
                        FsBadBlocks.Add(blockNum);
                        continue; // bad FS checksum :(
                    }
                }

                FsHeaders.Add(header);
                FsBlocks.Add(blockNum);

                if (header.SeqNo > latestSeqNo)
                {
                    MainFs      = header;
                    MainFsBlock = blockNum;
                    MainFsIndex = FsHeaders.Count - 1;
                    latestSeqNo = header.SeqNo;
                }

                io.Stream.Position = blockNum * BLOCK_SZ;
                var allocTable = new List <short>();
                for (int y = 0; y < NUM_BLOCKS_IN_FAT; y++)
                {
                    allocTable.Add((short)(io.Reader.ReadUInt16().EndianSwap()));
                }

                int numEntries = NUM_FS_ENTRIES;
                if (InodesOffset > 0)
                {
                    io.Stream.Position += InodesOffset; // skip weird truncated inode if needed
                    numEntries--;                       // and now we'll have to read one less entry
                }

                // now begin reading inodes
                var inodes = new List <iQueFsInode>();
                for (int y = 0; y < numEntries; y++)
                {
                    var inode = io.Reader.ReadStruct <iQueFsInode>();
                    inode.EndianSwap();
                    inodes.Add(inode);
                }

                FsAllocationTables.Add(allocTable);
                FsInodes.Add(inodes);
            }

            return(latestSeqNo >= 0);
        }