示例#1
0
        private static HierarchicalDuplexStorage InitDuplexStorage(IStorage baseStorage, Header header)
        {
            FsLayout layout       = header.Layout;
            var      duplexLayers = new DuplexFsLayerInfo[3];

            duplexLayers[0] = new DuplexFsLayerInfo
            {
                DataA = header.DuplexMasterBitmapA,
                DataB = header.DuplexMasterBitmapB,
                Info  = header.Duplex.Layers[0]
            };

            duplexLayers[1] = new DuplexFsLayerInfo
            {
                DataA = baseStorage.Slice(layout.DuplexL1OffsetA, layout.DuplexL1Size),
                DataB = baseStorage.Slice(layout.DuplexL1OffsetB, layout.DuplexL1Size),
                Info  = header.Duplex.Layers[1]
            };

            duplexLayers[2] = new DuplexFsLayerInfo
            {
                DataA = baseStorage.Slice(layout.DuplexDataOffsetA, layout.DuplexDataSize),
                DataB = baseStorage.Slice(layout.DuplexDataOffsetB, layout.DuplexDataSize),
                Info  = header.Duplex.Layers[2]
            };

            return(new HierarchicalDuplexStorage(duplexLayers, layout.DuplexIndex == 1));
        }
示例#2
0
        public Header(IStorage storage, KeySet keySet)
        {
            MainStorage         = storage;
            MainHeader          = MainStorage.Slice(0x100, 0x200);
            DuplexHeader        = MainStorage.Slice(0x300, 0x44);
            DataIvfcHeader      = MainStorage.Slice(0x344, 0xC0);
            JournalHeader       = MainStorage.Slice(0x408, 0x200);
            SaveHeader          = MainStorage.Slice(0x608, 0x48);
            MainRemapHeader     = MainStorage.Slice(0x650, 0x40);
            MetaDataRemapHeader = MainStorage.Slice(0x690, 0x40);
            ExtraDataStorage    = MainStorage.Slice(0x6D8, 0x400);
            FatIvfcHeader       = MainStorage.Slice(0xAD8, 0xC0);

            Layout = new FsLayout(MainHeader);

            DuplexMasterBitmapA = MainStorage.Slice(Layout.DuplexMasterOffsetA, Layout.DuplexMasterSize);
            DuplexMasterBitmapB = MainStorage.Slice(Layout.DuplexMasterOffsetB, Layout.DuplexMasterSize);
            DataIvfcMaster      = MainStorage.Slice(Layout.IvfcMasterHashOffsetA, Layout.IvfcMasterHashSize);
            FatIvfcMaster       = MainStorage.Slice(Layout.FatIvfcMasterHashA, Layout.IvfcMasterHashSize);

            var reader = new BinaryReader(storage.AsStream());

            reader.BaseStream.Position = 0;
            Data = reader.ReadBytes(0x4000);
            reader.BaseStream.Position = 0;

            Cmac = reader.ReadBytes(0x10);

            reader.BaseStream.Position = 0x100;

            reader.BaseStream.Position = 0x300;
            Duplex = new DuplexHeader(reader);

            reader.BaseStream.Position = 0x6D8;
            ExtraData = new ExtraData(reader);

            Ivfc = new IvfcHeader(DataIvfcHeader)
            {
                NumLevels = 5
            };

            if (Layout.Version >= 0x50000)
            {
                FatIvfc = new IvfcHeader(FatIvfcHeader)
                {
                    NumLevels = 4
                };
            }

            MasterHash = storage.Slice(Layout.IvfcMasterHashOffsetA, Layout.IvfcMasterHashSize);

            Span <byte> actualHeaderHash = stackalloc byte[Sha256.DigestSize];

            Sha256.GenerateSha256Hash(Data.AsSpan(0x300, 0x3d00), actualHeaderHash);

            HeaderHashValidity = Utilities.SpansEqual(Layout.Hash, actualHeaderHash) ? Validity.Valid : Validity.Invalid;
            SignatureValidity  = ValidateSignature(keySet);
        }
示例#3
0
        public Header(IStorage storage, Keyset keyset)
        {
            MainStorage         = storage;
            MainHeader          = MainStorage.Slice(0x100, 0x200);
            DuplexHeader        = MainStorage.Slice(0x300, 0x44);
            DataIvfcHeader      = MainStorage.Slice(0x344, 0xC0);
            JournalHeader       = MainStorage.Slice(0x408, 0x200);
            SaveHeader          = MainStorage.Slice(0x608, 0x48);
            MainRemapHeader     = MainStorage.Slice(0x650, 0x40);
            MetaDataRemapHeader = MainStorage.Slice(0x690, 0x40);
            ExtraDataStorage    = MainStorage.Slice(0x6D8, 0x400);
            FatIvfcHeader       = MainStorage.Slice(0xAD8, 0xC0);

            Layout = new FsLayout(MainHeader);

            DuplexMasterBitmapA = MainStorage.Slice(Layout.DuplexMasterOffsetA, Layout.DuplexMasterSize);
            DuplexMasterBitmapB = MainStorage.Slice(Layout.DuplexMasterOffsetB, Layout.DuplexMasterSize);
            DataIvfcMaster      = MainStorage.Slice(Layout.IvfcMasterHashOffsetA, Layout.IvfcMasterHashSize);
            FatIvfcMaster       = MainStorage.Slice(Layout.FatIvfcMasterHashA, Layout.IvfcMasterHashSize);

            var reader = new BinaryReader(storage.AsStream());

            reader.BaseStream.Position = 0;
            Data = reader.ReadBytes(0x4000);
            reader.BaseStream.Position = 0;

            Cmac = reader.ReadBytes(0x10);

            reader.BaseStream.Position = 0x100;

            reader.BaseStream.Position = 0x300;
            Duplex = new DuplexHeader(reader);

            reader.BaseStream.Position = 0x6D8;
            ExtraData = new ExtraData(reader);

            Ivfc = new IvfcHeader(DataIvfcHeader)
            {
                NumLevels = 5
            };

            if (Layout.Version >= 0x50000)
            {
                FatIvfc = new IvfcHeader(FatIvfcHeader)
                {
                    NumLevels = 4
                };
            }

            MasterHash = storage.Slice(Layout.IvfcMasterHashOffsetA, Layout.IvfcMasterHashSize);

            HeaderHashValidity = Crypto.CheckMemoryHashTable(Data, Layout.Hash, 0x300, 0x3d00);
            SignatureValidity  = ValidateSignature(keyset);
        }
示例#4
0
        public SaveDataFileSystem(Keyset keyset, IStorage storage, IntegrityCheckLevel integrityCheckLevel, bool leaveOpen)
        {
            BaseStorage = storage;
            LeaveOpen   = leaveOpen;
            Keyset      = keyset;

            var headerA = new Header(BaseStorage, keyset);
            var headerB = new Header(BaseStorage.Slice(0x4000), keyset);

            if (headerA.HeaderHashValidity == Validity.Valid)
            {
                IsFirstHeaderInUse = true;
            }
            else if (headerB.HeaderHashValidity == Validity.Valid)
            {
                IsFirstHeaderInUse = false;
            }
            else
            {
                ThrowHelper.ThrowResult(ResultFs.InvalidSaveDataHeader, "Savedata header is not valid.");
            }

            Header = IsFirstHeaderInUse ? headerA : headerB;

            FsLayout layout = Header.Layout;

            IStorage dataRemapBase        = BaseStorage.Slice(layout.FileMapDataOffset, layout.FileMapDataSize);
            IStorage dataRemapEntries     = BaseStorage.Slice(layout.FileMapEntryOffset, layout.FileMapEntrySize);
            IStorage metadataRemapEntries = BaseStorage.Slice(layout.MetaMapEntryOffset, layout.MetaMapEntrySize);

            DataRemapStorage = new RemapStorage(dataRemapBase, Header.MainRemapHeader, dataRemapEntries, leaveOpen);

            DuplexStorage = InitDuplexStorage(DataRemapStorage, Header);

            MetaRemapStorage = new RemapStorage(DuplexStorage, Header.MetaDataRemapHeader, metadataRemapEntries, leaveOpen);

            var journalMapInfo = new JournalMapParams
            {
                MapStorage          = MetaRemapStorage.Slice(layout.JournalMapTableOffset, layout.JournalMapTableSize),
                PhysicalBlockBitmap = MetaRemapStorage.Slice(layout.JournalPhysicalBitmapOffset, layout.JournalPhysicalBitmapSize),
                VirtualBlockBitmap  = MetaRemapStorage.Slice(layout.JournalVirtualBitmapOffset, layout.JournalVirtualBitmapSize),
                FreeBlockBitmap     = MetaRemapStorage.Slice(layout.JournalFreeBitmapOffset, layout.JournalFreeBitmapSize),
            };

            IStorage journalData = DataRemapStorage.Slice(layout.JournalDataOffset,
                                                          layout.JournalDataSizeB + layout.JournalSize);

            JournalStorage = new JournalStorage(journalData, Header.JournalHeader, journalMapInfo, leaveOpen);

            CoreDataIvfcStorage = InitJournalIvfcStorage(integrityCheckLevel);

            IStorage fatStorage = MetaRemapStorage.Slice(layout.FatOffset, layout.FatSize);

            if (Header.Layout.Version >= 0x50000)
            {
                FatIvfcStorage = InitFatIvfcStorage(integrityCheckLevel);
                fatStorage     = FatIvfcStorage;
            }

            SaveDataFileSystemCore = new SaveDataFileSystemCore(CoreDataIvfcStorage, fatStorage, Header.SaveHeader);
        }