Exemple #1
0
        private HierarchicalIntegrityVerificationStorage InitJournalIvfcStorage(IntegrityCheckLevel integrityCheckLevel)
        {
            const int  ivfcLevels = 5;
            IvfcHeader ivfc       = Header.Ivfc;
            var        levels     = new List <IStorage> {
                Header.DataIvfcMaster
            };

            for (int i = 0; i < ivfcLevels - 2; i++)
            {
                IvfcLevelHeader level = ivfc.LevelHeaders[i];
                levels.Add(MetaRemapStorage.Slice(level.Offset, level.Size));
            }

            IvfcLevelHeader dataLevel = ivfc.LevelHeaders[ivfcLevels - 2];

            levels.Add(JournalStorage.Slice(dataLevel.Offset, dataLevel.Size));

            return(new HierarchicalIntegrityVerificationStorage(ivfc, levels, IntegrityStorageType.Save, integrityCheckLevel, LeaveOpen));
        }
Exemple #2
0
 public HLEConfiguration(VirtualFileSystem virtualFileSystem,
                         ContentManager contentManager,
                         AccountManager accountManager,
                         UserChannelPersistence userChannelPersistence,
                         IRenderer gpuRenderer,
                         IHardwareDeviceDriver audioDeviceDriver,
                         MemoryConfiguration memoryConfiguration,
                         IHostUiHandler hostUiHandler,
                         SystemLanguage systemLanguage,
                         RegionCode region,
                         bool enableVsync,
                         bool enableDockedMode,
                         bool enablePtc,
                         IntegrityCheckLevel fsIntegrityCheckLevel,
                         int fsGlobalAccessLogMode,
                         long systemTimeOffset,
                         string timeZone,
                         bool ignoreMissingServices,
                         AspectRatio aspectRatio)
 {
     VirtualFileSystem      = virtualFileSystem;
     AccountManager         = accountManager;
     ContentManager         = contentManager;
     UserChannelPersistence = userChannelPersistence;
     GpuRenderer            = gpuRenderer;
     AudioDeviceDriver      = audioDeviceDriver;
     MemoryConfiguration    = memoryConfiguration;
     HostUiHandler          = hostUiHandler;
     SystemLanguage         = systemLanguage;
     Region                = region;
     EnableVsync           = enableVsync;
     EnableDockedMode      = enableDockedMode;
     EnablePtc             = enablePtc;
     FsIntegrityCheckLevel = fsIntegrityCheckLevel;
     FsGlobalAccessLogMode = fsGlobalAccessLogMode;
     SystemTimeOffset      = systemTimeOffset;
     TimeZone              = timeZone;
     IgnoreMissingServices = ignoreMissingServices;
     AspectRatio           = aspectRatio;
 }
Exemple #3
0
        public IStorage OpenStorage(int index, IntegrityCheckLevel integrityCheckLevel)
        {
            IStorage    rawStorage = OpenRawStorage(index);
            NcaFsHeader header     = Header.GetFsHeader(index);

            if (header.EncryptionType == NcaEncryptionType.AesCtrEx)
            {
                return(rawStorage.Slice(0, header.GetPatchInfo().RelocationTreeOffset));
            }

            switch (header.HashType)
            {
            case NcaHashType.Sha256:
                return(InitIvfcForPartitionFs(header.GetIntegrityInfoSha256(), rawStorage, integrityCheckLevel, true));

            case NcaHashType.Ivfc:
                return(InitIvfcForRomFs(header.GetIntegrityInfoIvfc(), rawStorage, integrityCheckLevel, true));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #4
0
        private IStorage CreateVerificationStorage(IntegrityCheckLevel integrityCheckLevel, NcaFsHeader header,
                                                   IStorage rawStorage)
        {
            switch (header.HashType)
            {
            case NcaHashType.Sha256:
                return(InitIvfcForPartitionFs(header.GetIntegrityInfoSha256(), rawStorage, integrityCheckLevel,
                                              true));

            case NcaHashType.Ivfc:
                // The FS header of an NCA0 section with IVFC verification must be manually skipped
                if (Header.IsNca0())
                {
                    rawStorage = rawStorage.Slice(0x200);
                }

                return(InitIvfcForRomFs(header.GetIntegrityInfoIvfc(), rawStorage, integrityCheckLevel, true));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #5
0
        private static HierarchicalIntegrityVerificationStorage InitIvfcForRomFs(NcaFsIntegrityInfoIvfc ivfc,
                                                                                 IStorage dataStorage, IntegrityCheckLevel integrityCheckLevel, bool leaveOpen)
        {
            var initInfo = new IntegrityVerificationInfo[ivfc.LevelCount];

            initInfo[0] = new IntegrityVerificationInfo
            {
                Data      = new MemoryStorage(ivfc.MasterHash.ToArray()),
                BlockSize = 0
            };

            for (int i = 1; i < ivfc.LevelCount; i++)
            {
                initInfo[i] = new IntegrityVerificationInfo
                {
                    Data      = dataStorage.Slice(ivfc.GetLevelOffset(i - 1), ivfc.GetLevelSize(i - 1)),
                    BlockSize = 1 << ivfc.GetLevelBlockSize(i - 1),
                        Type  = IntegrityStorageType.RomFs
                };
            }

            return(new HierarchicalIntegrityVerificationStorage(initInfo, integrityCheckLevel, leaveOpen));
        }
Exemple #6
0
        private static HierarchicalIntegrityVerificationStorage InitIvfcForPartitionFs(NcaFsIntegrityInfoSha256 info,
                                                                                       IStorage pfsStorage, IntegrityCheckLevel integrityCheckLevel, bool leaveOpen)
        {
            Debug.Assert(info.LevelCount == 2);

            IStorage hashStorage = pfsStorage.Slice(info.GetLevelOffset(0), info.GetLevelSize(0), leaveOpen);
            IStorage dataStorage = pfsStorage.Slice(info.GetLevelOffset(1), info.GetLevelSize(1), leaveOpen);

            var initInfo = new IntegrityVerificationInfo[3];

            // Set the master hash
            initInfo[0] = new IntegrityVerificationInfo
            {
                // todo Get hash directly from header
                Data = new MemoryStorage(info.MasterHash.ToArray()),

                BlockSize = 0,
                Type      = IntegrityStorageType.PartitionFs
            };

            initInfo[1] = new IntegrityVerificationInfo
            {
                Data      = hashStorage,
                BlockSize = (int)info.GetLevelSize(0),
                Type      = IntegrityStorageType.PartitionFs
            };

            initInfo[2] = new IntegrityVerificationInfo
            {
                Data      = dataStorage,
                BlockSize = info.BlockSize,
                Type      = IntegrityStorageType.PartitionFs
            };

            return(new HierarchicalIntegrityVerificationStorage(initInfo, integrityCheckLevel, leaveOpen));
        }
Exemple #7
0
 public IStorage OpenStorageWithPatch(Nca patchNca, NcaSectionType type, IntegrityCheckLevel integrityCheckLevel)
 {
     return(OpenStorageWithPatch(patchNca, GetSectionIndexFromType(type), integrityCheckLevel));
 }
Exemple #8
0
        public IntegrityVerificationStream(IntegrityVerificationInfo info, Stream hashStream, IntegrityCheckLevel integrityCheckLevel)
            : base(info.Data, info.BlockSize)
        {
            HashStream          = hashStream;
            IntegrityCheckLevel = integrityCheckLevel;
            Salt = info.Salt;
            Type = info.Type;

            BlockValidities = new Validity[SectorCount];
        }
 private HierarchicalIntegrityVerificationStorage InitFatIvfcStorage(IntegrityCheckLevel integrityCheckLevel)
 {
     return(new HierarchicalIntegrityVerificationStorage(Header.FatIvfc, Header.FatIvfcMaster, MetaRemapStorage,
                                                         IntegrityStorageType.Save, integrityCheckLevel, LeaveOpen));
 }
 public Result Read(long offset, Span <byte> destination, IntegrityCheckLevel integrityCheckLevel)
 {
     // ValidateParameters(destination, offset);
     return(ReadImpl(offset, destination, integrityCheckLevel));
 }
        private void ReadImpl(Span <byte> destination, long offset, IntegrityCheckLevel integrityCheckLevel)
        {
            int count = destination.Length;

            if (count < 0 || count > SectorSize)
            {
                throw new ArgumentOutOfRangeException(nameof(destination), "Length is invalid.");
            }

            long blockIndex = offset / SectorSize;

            if (BlockValidities[blockIndex] == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
            {
                // Todo: Differentiate between the top and lower layers
                ThrowHelper.ThrowResult(ResultFs.InvalidHashInIvfc, "Hash error!");
            }

            bool needsHashCheck = integrityCheckLevel != IntegrityCheckLevel.None &&
                                  BlockValidities[blockIndex] == Validity.Unchecked;

            if (Type != IntegrityStorageType.Save && !needsHashCheck)
            {
                BaseStorage.Read(destination, offset);
                return;
            }

            Span <byte> hashBuffer = stackalloc byte[DigestSize];
            long        hashPos    = blockIndex * DigestSize;

            HashStorage.Read(hashBuffer, hashPos);

            if (Type == IntegrityStorageType.Save)
            {
                if (Util.IsEmpty(hashBuffer))
                {
                    destination.Clear();
                    BlockValidities[blockIndex] = Validity.Valid;
                    return;
                }

                if (!needsHashCheck)
                {
                    BaseStorage.Read(destination, offset);
                    return;
                }
            }

            byte[] dataBuffer = ArrayPool <byte> .Shared.Rent(SectorSize);

            try
            {
                BaseStorage.Read(destination, offset);
                destination.CopyTo(dataBuffer);

                if (BlockValidities[blockIndex] != Validity.Unchecked)
                {
                    return;
                }

                int bytesToHash = SectorSize;

                if (count < SectorSize)
                {
                    // Pad out unused portion of block
                    Array.Clear(dataBuffer, count, SectorSize - count);

                    // Partition FS hashes don't pad out an incomplete block
                    if (Type == IntegrityStorageType.PartitionFs)
                    {
                        bytesToHash = count;
                    }
                }

                byte[] hash = DoHash(dataBuffer, 0, bytesToHash);

                Validity validity = Util.SpansEqual(hashBuffer, hash) ? Validity.Valid : Validity.Invalid;
                BlockValidities[blockIndex] = validity;

                if (validity == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
                {
                    ThrowHelper.ThrowResult(ResultFs.InvalidHashInIvfc, "Hash error!");
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(dataBuffer);
            }
        }
 public void Read(byte[] buffer, long offset, int count, int bufferOffset, IntegrityCheckLevel integrityCheckLevel)
 {
     ValidateArrayParameters(buffer, offset, count, bufferOffset);
     ReadImpl(buffer.AsSpan(bufferOffset, count), offset, integrityCheckLevel);
 }
        private void ReadImpl(Span <byte> destination, long offset, IntegrityCheckLevel integrityCheckLevel)
        {
            int count = destination.Length;

            if (count < 0 || count > SectorSize)
            {
                throw new ArgumentOutOfRangeException(nameof(destination), "Length is invalid.");
            }

            Span <byte> hashBuffer = stackalloc byte[DigestSize];
            long        blockIndex = offset / SectorSize;
            long        hashPos    = blockIndex * DigestSize;

            if (BlockValidities[blockIndex] == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
            {
                throw new InvalidDataException("Hash error!");
            }

            HashStorage.Read(hashBuffer, hashPos);

            if (Type == IntegrityStorageType.Save && Util.IsEmpty(hashBuffer))
            {
                destination.Clear();
                BlockValidities[blockIndex] = Validity.Valid;
                return;
            }

            byte[] dataBuffer = ArrayPool <byte> .Shared.Rent(SectorSize);

            try
            {
                BaseStorage.Read(dataBuffer, offset, count, 0);
                dataBuffer.AsSpan(0, count).CopyTo(destination);

                if (integrityCheckLevel == IntegrityCheckLevel.None)
                {
                    return;
                }
                if (BlockValidities[blockIndex] != Validity.Unchecked)
                {
                    return;
                }

                int bytesToHash = SectorSize;

                if (count < SectorSize)
                {
                    // Pad out unused portion of block
                    Array.Clear(dataBuffer, count, SectorSize - count);

                    // Partition FS hashes don't pad out an incomplete block
                    if (Type == IntegrityStorageType.PartitionFs)
                    {
                        bytesToHash = count;
                    }
                }

                byte[] hash = DoHash(dataBuffer, 0, bytesToHash);

                Validity validity = Util.SpansEqual(hashBuffer, hash) ? Validity.Valid : Validity.Invalid;
                BlockValidities[blockIndex] = validity;

                if (validity == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
                {
                    throw new InvalidDataException("Hash error!");
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(dataBuffer);
            }
        }
        public HierarchicalIntegrityVerificationStorage(IntegrityVerificationInfo[] levelInfo, IntegrityCheckLevel integrityCheckLevel, bool leaveOpen)
        {
            Levels = new IStorage[levelInfo.Length];
            IntegrityCheckLevel = integrityCheckLevel;
            LevelValidities     = new Validity[levelInfo.Length - 1][];
            IntegrityStorages   = new IntegrityVerificationStorage[levelInfo.Length - 1];

            Levels[0] = levelInfo[0].Data;

            for (int i = 1; i < Levels.Length; i++)
            {
                var levelData = new IntegrityVerificationStorage(levelInfo[i], Levels[i - 1], integrityCheckLevel, leaveOpen);

                Levels[i] = new CachedStorage(levelData, 4, leaveOpen);
                LevelValidities[i - 1]   = levelData.BlockValidities;
                IntegrityStorages[i - 1] = levelData;
            }

            DataLevel = Levels[Levels.Length - 1];
            Length    = DataLevel.Length;

            if (!leaveOpen)
            {
                ToDispose.Add(DataLevel);
            }
        }
Exemple #15
0
 public static void ExportSection(this Nca nca, NcaSectionType type, string filename, bool raw = false,
                                  IntegrityCheckLevel integrityCheckLevel = IntegrityCheckLevel.None, IProgressReport logger = null)
 {
     nca.OpenStorage(type, integrityCheckLevel, raw)
     .WriteAllBytes(filename, logger);
 }
Exemple #16
0
        public int Read(byte[] buffer, int offset, int count, IntegrityCheckLevel integrityCheckLevel)
        {
            long blockNum = CurrentSector;

            HashStream.Position = blockNum * DigestSize;
            HashStream.Read(_hashBuffer, 0, DigestSize);

            int bytesRead   = base.Read(buffer, offset, count);
            int bytesToHash = SectorSize;

            if (bytesRead == 0)
            {
                return(0);
            }

            // If a hash is zero the data for the entire block is zero
            if (Type == IntegrityStreamType.Save && _hashBuffer.IsEmpty())
            {
                Array.Clear(buffer, offset, SectorSize);
                BlockValidities[blockNum] = Validity.Valid;
                return(bytesRead);
            }

            if (bytesRead < SectorSize)
            {
                // Pad out unused portion of block
                Array.Clear(buffer, offset + bytesRead, SectorSize - bytesRead);

                // Partition FS hashes don't pad out an incomplete block
                if (Type == IntegrityStreamType.PartitionFs)
                {
                    bytesToHash = bytesRead;
                }
            }

            if (BlockValidities[blockNum] == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
            {
                throw new InvalidDataException("Hash error!");
            }

            if (integrityCheckLevel == IntegrityCheckLevel.None)
            {
                return(bytesRead);
            }

            if (BlockValidities[blockNum] != Validity.Unchecked)
            {
                return(bytesRead);
            }

            byte[] hash = DoHash(buffer, offset, bytesToHash);

            Validity validity = Util.ArraysEqual(_hashBuffer, hash) ? Validity.Valid : Validity.Invalid;

            BlockValidities[blockNum] = validity;

            if (validity == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
            {
                throw new InvalidDataException("Hash error!");
            }

            return(bytesRead);
        }
Exemple #17
0
        // fs must contain AOC nca files in its root
        public void AddAocData(IFileSystem fs, string containerPath, ulong aocBaseId, IntegrityCheckLevel integrityCheckLevel)
        {
            _virtualFileSystem.ImportTickets(fs);

            foreach (var ncaPath in fs.EnumerateEntries("*.cnmt.nca", SearchOptions.Default))
            {
                using var ncaFile = new UniqueRef <IFile>();

                fs.OpenFile(ref ncaFile.Ref(), ncaPath.FullPath.ToU8Span(), OpenMode.Read);
                var nca = new Nca(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
                if (nca.Header.ContentType != NcaContentType.Meta)
                {
                    Logger.Warning?.Print(LogClass.Application, $"{ncaPath} is not a valid metadata file");

                    continue;
                }

                using var pfs0     = nca.OpenFileSystem(0, integrityCheckLevel);
                using var cnmtFile = new UniqueRef <IFile>();

                pfs0.OpenFile(ref cnmtFile.Ref(), pfs0.EnumerateEntries().Single().FullPath.ToU8Span(), OpenMode.Read);

                var cnmt = new Cnmt(cnmtFile.Get.AsStream());

                if (cnmt.Type != ContentMetaType.AddOnContent || (cnmt.TitleId & 0xFFFFFFFFFFFFE000) != aocBaseId)
                {
                    continue;
                }

                string ncaId = BitConverter.ToString(cnmt.ContentEntries[0].NcaId).Replace("-", "").ToLower();
                if (!_aocData.TryAdd(cnmt.TitleId, new AocItem(containerPath, $"{ncaId}.nca", true)))
                {
                    Logger.Warning?.Print(LogClass.Application, $"Duplicate AddOnContent detected. TitleId {cnmt.TitleId:X16}");
                }
                else
                {
                    Logger.Info?.Print(LogClass.Application, $"Found AddOnContent with TitleId {cnmt.TitleId:X16}");
                }
            }
        }
        public HierarchicalIntegrityVerificationStorage(IntegrityVerificationInfo[] levelInfo, IntegrityCheckLevel integrityCheckLevel, bool leaveOpen)
        {
            Levels = new IStorage[levelInfo.Length];
            IntegrityCheckLevel = integrityCheckLevel;
            LevelValidities     = new Validity[levelInfo.Length - 1][];
            IntegrityStorages   = new IntegrityVerificationStorage[levelInfo.Length - 1];

            Levels[0] = levelInfo[0].Data;

            for (int i = 1; i < Levels.Length; i++)
            {
                var levelData = new IntegrityVerificationStorage(levelInfo[i], Levels[i - 1], integrityCheckLevel, leaveOpen);

                int cacheCount = Math.Min((int)Util.DivideByRoundUp(levelData.GetSize(), levelInfo[i].BlockSize), 4);

                Levels[i] = new CachedStorage(levelData, cacheCount, leaveOpen);
                LevelValidities[i - 1]   = levelData.BlockValidities;
                IntegrityStorages[i - 1] = levelData;
            }

            DataLevel = Levels[Levels.Length - 1];
            _length   = DataLevel.GetSize();

            if (!leaveOpen)
            {
                ToDispose.Add(DataLevel);
            }
        }
 public void Read(Span <byte> destination, long offset, IntegrityCheckLevel integrityCheckLevel)
 {
     ValidateParameters(destination, offset);
     ReadImpl(destination, offset, integrityCheckLevel);
 }
 public HierarchicalIntegrityVerificationStorage(IvfcHeader header, IList <IStorage> levels,
                                                 IntegrityStorageType type, IntegrityCheckLevel integrityCheckLevel, bool leaveOpen)
     : this(GetIvfcInfo(header, levels, type), integrityCheckLevel, leaveOpen)
 {
 }
Exemple #21
0
        public HierarchicalIntegrityVerificationStorage(IntegrityVerificationInfo[] levelInfo, IntegrityCheckLevel integrityCheckLevel, bool leaveOpen)
        {
            Levels = new IStorage[levelInfo.Length];
            IntegrityCheckLevel = integrityCheckLevel;
            LevelValidities     = new Validity[levelInfo.Length - 1][];
            IntegrityStorages   = new IntegrityVerificationStorage[levelInfo.Length - 1];

            Levels[0] = levelInfo[0].Data;

            for (int i = 1; i < Levels.Length; i++)
            {
                var levelData = new IntegrityVerificationStorage(levelInfo[i], Levels[i - 1], integrityCheckLevel, leaveOpen);
                levelData.GetSize(out long levelSize).ThrowIfFailure();

                int cacheCount = Math.Min((int)Utilities.DivideByRoundUp(levelSize, levelInfo[i].BlockSize), 4);

                Levels[i] = new CachedStorage(levelData, cacheCount, leaveOpen);
                LevelValidities[i - 1]   = levelData.BlockValidities;
                IntegrityStorages[i - 1] = levelData;
            }

            DataLevel = Levels[Levels.Length - 1];
            DataLevel.GetSize(out long dataSize).ThrowIfFailure();
            Length = dataSize;

            LeaveOpen = leaveOpen;
        }
Exemple #22
0
        public void InitializeInstance(VirtualFileSystem virtualFileSystem, ContentManager contentManager, IntegrityCheckLevel fsIntegrityCheckLevel)
        {
            _virtualFileSystem     = virtualFileSystem;
            _contentManager        = contentManager;
            _fsIntegrityCheckLevel = fsIntegrityCheckLevel;

            InitializeLocationNameCache();
        }
 public HierarchicalIntegrityVerificationStorage(IvfcHeader header, IStorage masterHash, IStorage data,
                                                 IntegrityStorageType type, IntegrityCheckLevel integrityCheckLevel, bool leaveOpen)
     : this(header, ToStorageList(header, masterHash, data, leaveOpen), type, integrityCheckLevel, leaveOpen)
 {
 }
Exemple #24
0
 public IFileSystem OpenFileSystem(NcaSectionType type, IntegrityCheckLevel integrityCheckLevel)
 {
     return(OpenFileSystem(GetSectionIndexFromType(type), integrityCheckLevel));
 }
Exemple #25
0
        public HierarchicalIntegrityVerificationStream(IntegrityVerificationInfo[] levelInfo, IntegrityCheckLevel integrityCheckLevel)
        {
            Levels = new Stream[levelInfo.Length];
            IntegrityCheckLevel = integrityCheckLevel;
            LevelValidities     = new Validity[levelInfo.Length - 1][];
            IntegrityStreams    = new IntegrityVerificationStream[levelInfo.Length - 1];

            Levels[0] = levelInfo[0].Data;

            for (int i = 1; i < Levels.Length; i++)
            {
                var levelData = new IntegrityVerificationStream(levelInfo[i], Levels[i - 1], integrityCheckLevel);

                Levels[i] = new RandomAccessSectorStream(levelData);
                LevelValidities[i - 1]  = levelData.BlockValidities;
                IntegrityStreams[i - 1] = levelData;
            }

            DataLevel = Levels[Levels.Length - 1];
        }
Exemple #26
0
 public IFileSystem OpenFileSystemWithPatch(Nca patchNca, NcaSectionType type, IntegrityCheckLevel integrityCheckLevel)
 {
     return(OpenFileSystemWithPatch(patchNca, GetSectionIndexFromType(type), integrityCheckLevel));
 }
        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);
        }
Exemple #28
0
 public IStorage OpenStorage(NcaSectionType type, IntegrityCheckLevel integrityCheckLevel)
 {
     return(OpenStorage(GetSectionIndexFromType(type), integrityCheckLevel));
 }