public Savefile(Keyset keyset, Stream file, IntegrityCheckLevel integrityCheckLevel) { SavefileSource = new SharedStreamSource(file); Header = new Header(keyset, SavefileSource); FsLayout layout = Header.Layout; DataRemapStorage = new RemapStorage(SavefileSource.CreateStream(layout.FileMapDataOffset, layout.FileMapDataSize), Header.FileRemap, Header.FileMapEntries); DuplexData = InitDuplexStream(DataRemapStorage, Header); MetaRemapStorage = new RemapStorage(DuplexData, Header.MetaRemap, Header.MetaMapEntries); Stream journalTable = MetaRemapStorage.OpenStream(layout.JournalTableOffset, layout.JournalTableSize); MappingEntry[] journalMap = JournalStream.ReadMappingEntries(journalTable, Header.Journal.MainDataBlockCount); Stream journalData = DataRemapStorage.OpenStream(layout.JournalDataOffset, layout.JournalDataSizeB + layout.SizeReservedArea); var journalStream = new JournalStream(journalData, journalMap, (int)Header.Journal.BlockSize); JournalStreamSource = new SharedStreamSource(journalStream); IvfcStream = InitIvfcStream(integrityCheckLevel); SaveFs = new SaveFs(IvfcStream, MetaRemapStorage.OpenStream(layout.FatOffset, layout.FatSize), Header.Save); IvfcStreamSource = new SharedStreamSource(IvfcStream); }
private static LayeredDuplexFs InitDuplexStream(RemapStorage baseStorage, Header header) { FsLayout layout = header.Layout; var duplexLayers = new DuplexFsLayerInfo[3]; duplexLayers[0] = new DuplexFsLayerInfo { DataA = new MemoryStream(header.DuplexMasterA), DataB = new MemoryStream(header.DuplexMasterB), Info = header.Duplex.Layers[0] }; duplexLayers[1] = new DuplexFsLayerInfo { DataA = baseStorage.OpenStream(layout.DuplexL1OffsetA, layout.DuplexL1Size), DataB = baseStorage.OpenStream(layout.DuplexL1OffsetB, layout.DuplexL1Size), Info = header.Duplex.Layers[1] }; duplexLayers[2] = new DuplexFsLayerInfo { DataA = baseStorage.OpenStream(layout.DuplexDataOffsetA, layout.DuplexDataSize), DataB = baseStorage.OpenStream(layout.DuplexDataOffsetB, layout.DuplexDataSize), Info = header.Duplex.Layers[2] }; return(new LayeredDuplexFs(duplexLayers, layout.DuplexIndex == 1)); }
public Header(Keyset keyset, SharedStreamSource streamSource) { var reader = new BinaryReader(streamSource.CreateStream()); reader.BaseStream.Position = 0; Data = reader.ReadBytes(0x4000); reader.BaseStream.Position = 0; Cmac = reader.ReadBytes(0x10); reader.BaseStream.Position = 0x100; Layout = new FsLayout(reader); reader.BaseStream.Position = 0x300; Duplex = new DuplexHeader(reader); reader.BaseStream.Position = 0x344; Ivfc = new IvfcHeader(reader); reader.BaseStream.Position = 0x408; Journal = new JournalHeader(reader); reader.BaseStream.Position = 0x608; Save = new SaveHeader(reader); reader.BaseStream.Position = 0x650; FileRemap = new RemapHeader(reader); reader.BaseStream.Position = 0x690; MetaRemap = new RemapHeader(reader); reader.BaseStream.Position = 0x6D8; ExtraData = new ExtraData(reader); reader.BaseStream.Position = Layout.IvfcMasterHashOffsetA; MasterHashA = reader.ReadBytes((int)Layout.IvfcMasterHashSize); reader.BaseStream.Position = Layout.IvfcMasterHashOffsetB; MasterHashB = reader.ReadBytes((int)Layout.IvfcMasterHashSize); MasterHash = streamSource.CreateStream(Layout.IvfcMasterHashOffsetA, Layout.IvfcMasterHashSize); reader.BaseStream.Position = Layout.DuplexMasterOffsetA; DuplexMasterA = reader.ReadBytes((int)Layout.DuplexMasterSize); reader.BaseStream.Position = Layout.DuplexMasterOffsetB; DuplexMasterB = reader.ReadBytes((int)Layout.DuplexMasterSize); reader.BaseStream.Position = Layout.FileMapEntryOffset; FileMapEntries = new MapEntry[FileRemap.MapEntryCount]; for (int i = 0; i < FileRemap.MapEntryCount; i++) { FileMapEntries[i] = new MapEntry(reader); } reader.BaseStream.Position = Layout.MetaMapEntryOffset; MetaMapEntries = new MapEntry[MetaRemap.MapEntryCount]; for (int i = 0; i < MetaRemap.MapEntryCount; i++) { MetaMapEntries[i] = new MapEntry(reader); } HeaderHashValidity = Crypto.CheckMemoryHashTable(Data, Layout.Hash, 0x300, 0x3d00); SignatureValidity = ValidateSignature(keyset); }