private static RemapSegment[] InitSegments(RemapHeader header, MapEntry[] mapEntries) { var segments = new RemapSegment[header.MapSegmentCount]; int entryIdx = 0; for (int i = 0; i < header.MapSegmentCount; i++) { var seg = new RemapSegment(); seg.Entries.Add(mapEntries[entryIdx]); seg.Offset = mapEntries[entryIdx].VirtualOffset; mapEntries[entryIdx].Segment = seg; entryIdx++; while (entryIdx < mapEntries.Length && mapEntries[entryIdx - 1].VirtualOffsetEnd == mapEntries[entryIdx].VirtualOffset) { mapEntries[entryIdx].Segment = seg; mapEntries[entryIdx - 1].Next = mapEntries[entryIdx]; seg.Entries.Add(mapEntries[entryIdx]); entryIdx++; } seg.Length = seg.Entries[seg.Entries.Count - 1].VirtualOffsetEnd - seg.Entries[0].VirtualOffset; segments[i] = seg; } return(segments); }
/// <summary> /// Creates a new <see cref="RemapStorage"/> /// </summary> /// <param name="data">A <see cref="Stream"/> of the main data of the RemapStream. /// The <see cref="RemapStorage"/> object takes complete ownership of the Stream.</param> /// <param name="header">The header for this RemapStorage.</param> /// <param name="mapEntries">The remapping entries for this RemapStorage.</param> public RemapStorage(Stream data, RemapHeader header, MapEntry[] mapEntries) { StreamSource = new SharedStreamSource(data); Header = header; MapEntries = mapEntries; Segments = InitSegments(Header, MapEntries); }
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); }