Beispiel #1
0
        public void CreateModifiedInodes()
        {
            if (ModifiedInodes != null)
            {
                return;
            }

            ModifiedInodes = new List <BbInode>();
            foreach (var node in MainFsInodes)
            {
                var newNode = new BbInode();
                ModifiedInodes.Add(newNode.Copy(node));
            }

            ModifiedAllocTable = new List <short>();
            foreach (var alloc in MainFsAllocTable)
            {
                ModifiedAllocTable.Add(alloc);
            }

            var newSeqNo = MainFs.SeqNo + 1;

            MainFs          = new BbFat16();
            MainFs.Magic    = MAGIC_BBFS;
            MainFs.SeqNo    = newSeqNo;
            MainFs.Link     = 0;
            MainFs.CheckSum = 0;

            FsHeaders.Add(MainFs);
            FsInodes.Add(ModifiedInodes);
            FsAllocationTables.Add(ModifiedAllocTable);

            MainFsIndex = FsHeaders.Count - 1;
        }
Beispiel #2
0
        public bool VerifyFsChecksum(BbFat16 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);
        }
Beispiel #3
0
        private bool ReadFilesystem()
        {
            FsHeaders          = new List <BbFat16>();
            FsBlocks           = new List <int>();
            FsBadBlocks        = new List <int>();
            FsInodes           = new List <List <BbInode> >();
            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 <BbFat16>();
                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 <BbInode>();
                for (int y = 0; y < numEntries; y++)
                {
                    var inode = io.Reader.ReadStruct <BbInode>();
                    inode.EndianSwap();
                    inodes.Add(inode);
                }
                var invalidInodes = new List <int>();
                for (int y = 0; y < inodes.Count; y++)
                {
                    if (!inodes[y].IsValid)
                    {
                        invalidInodes.Add(y);
                    }
                }

                for (int y = invalidInodes.Count - 1; y >= 0; y--)
                {
                    inodes.RemoveAt(invalidInodes[y]);
                }

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

            return(latestSeqNo >= 0);
        }