示例#1
0
        public Header(Keyset keyset, BinaryReader reader)
        {
            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);

            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);
        }
示例#2
0
        public Savefile(Keyset keyset, Stream file, bool enableIntegrityChecks)
        {
            SavefileSource = new SharedStreamSource(file);

            using (var reader = new BinaryReader(SavefileSource.CreateStream(), Encoding.Default, true))
            {
                Header = new Header(keyset, reader);
                FsLayout layout = Header.Layout;

                FileRemap = new RemapStream(
                    SavefileSource.CreateStream(layout.FileMapDataOffset, layout.FileMapDataSize),
                    Header.FileMapEntries, Header.FileRemap.MapSegmentCount);

                FileRemapSource = new SharedStreamSource(FileRemap);

                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 = FileRemapSource.CreateStream(layout.DuplexL1OffsetA, layout.DuplexL1Size),
                    DataB = FileRemapSource.CreateStream(layout.DuplexL1OffsetB, layout.DuplexL1Size),
                    Info  = Header.Duplex.Layers[1]
                };

                duplexLayers[2] = new DuplexFsLayerInfo
                {
                    DataA = FileRemapSource.CreateStream(layout.DuplexDataOffsetA, layout.DuplexDataSize),
                    DataB = FileRemapSource.CreateStream(layout.DuplexDataOffsetB, layout.DuplexDataSize),
                    Info  = Header.Duplex.Layers[2]
                };

                DuplexL1A   = FileRemapSource.CreateStream(layout.DuplexL1OffsetA, layout.DuplexL1Size);
                DuplexL1B   = FileRemapSource.CreateStream(layout.DuplexL1OffsetB, layout.DuplexL1Size);
                DuplexDataA = FileRemapSource.CreateStream(layout.DuplexDataOffsetA, layout.DuplexDataSize);
                DuplexDataB = FileRemapSource.CreateStream(layout.DuplexDataOffsetB, layout.DuplexDataSize);
                JournalData = FileRemapSource.CreateStream(layout.JournalDataOffset, layout.JournalDataSizeB + layout.SizeReservedArea);

                DuplexData      = new LayeredDuplexFs(duplexLayers, Header.Layout.DuplexIndex == 1);
                MetaRemap       = new RemapStream(DuplexData, Header.MetaMapEntries, Header.MetaRemap.MapSegmentCount);
                MetaRemapSource = new SharedStreamSource(MetaRemap);

                JournalTable = MetaRemapSource.CreateStream(layout.JournalTableOffset, layout.JournalTableSize);
                JournalBitmapUpdatedPhysical = MetaRemapSource.CreateStream(layout.JournalBitmapUpdatedPhysicalOffset, layout.JournalBitmapUpdatedPhysicalSize);
                JournalBitmapUpdatedVirtual  = MetaRemapSource.CreateStream(layout.JournalBitmapUpdatedVirtualOffset, layout.JournalBitmapUpdatedVirtualSize);
                JournalBitmapUnassigned      = MetaRemapSource.CreateStream(layout.JournalBitmapUnassignedOffset, layout.JournalBitmapUnassignedSize);
                JournalLayer1Hash            = MetaRemapSource.CreateStream(layout.IvfcL1Offset, layout.IvfcL1Size);
                JournalLayer2Hash            = MetaRemapSource.CreateStream(layout.IvfcL2Offset, layout.IvfcL2Size);
                JournalLayer3Hash            = MetaRemapSource.CreateStream(layout.IvfcL3Offset, layout.IvfcL3Size);
                JournalFat      = MetaRemapSource.CreateStream(layout.FatOffset, layout.FatSize);
                AllocationTable = new AllocationTable(JournalFat);

                MappingEntry[] journalMap = JournalStream.ReadMappingEntries(JournalTable, Header.Journal.MainDataBlockCount);

                SharedStream journalData = FileRemapSource.CreateStream(layout.JournalDataOffset,
                                                                        layout.JournalDataSizeB + layout.SizeReservedArea);
                JournalStream       = new JournalStream(journalData, journalMap, (int)Header.Journal.BlockSize);
                JournalStreamSource = new SharedStreamSource(JournalStream);

                IvfcStream       = InitIvfcStream(enableIntegrityChecks);
                IvfcStreamSource = new SharedStreamSource(IvfcStream);

                ReadFileInfo();
                var dictionary = new Dictionary <string, FileEntry>();
                foreach (FileEntry entry in Files)
                {
                    dictionary[entry.FullPath] = entry;
                }

                FileDict = dictionary;
            }
        }