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