diff options
Diffstat (limited to 'src/Ryujinx.HLE/FileSystem')
| -rw-r--r-- | src/Ryujinx.HLE/FileSystem/ContentManager.cs | 42 | ||||
| -rw-r--r-- | src/Ryujinx.HLE/FileSystem/ContentMetaData.cs | 61 |
2 files changed, 63 insertions, 40 deletions
diff --git a/src/Ryujinx.HLE/FileSystem/ContentManager.cs b/src/Ryujinx.HLE/FileSystem/ContentManager.cs index 3c34a886..e6c0fce0 100644 --- a/src/Ryujinx.HLE/FileSystem/ContentManager.cs +++ b/src/Ryujinx.HLE/FileSystem/ContentManager.cs @@ -14,6 +14,7 @@ using Ryujinx.Common.Utilities; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Services.Ssl; using Ryujinx.HLE.HOS.Services.Time; +using Ryujinx.HLE.Utilities; using System; using System.Collections.Generic; using System.IO; @@ -184,41 +185,6 @@ namespace Ryujinx.HLE.FileSystem } } - // 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).ThrowIfFailure(); - 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).ThrowIfFailure(); - - var cnmt = new Cnmt(cnmtFile.Get.AsStream()); - if (cnmt.Type != ContentMetaType.AddOnContent || (cnmt.TitleId & 0xFFFFFFFFFFFFE000) != aocBaseId) - { - continue; - } - - string ncaId = Convert.ToHexString(cnmt.ContentEntries[0].NcaId).ToLower(); - - AddAocItem(cnmt.TitleId, containerPath, $"/{ncaId}.nca", true); - } - } - public void AddAocItem(ulong titleId, string containerPath, string ncaPath, bool mergedToContainer = false) { // TODO: Check Aoc version. @@ -232,11 +198,7 @@ namespace Ryujinx.HLE.FileSystem if (!mergedToContainer) { - using FileStream fileStream = File.OpenRead(containerPath); - using PartitionFileSystem partitionFileSystem = new(); - partitionFileSystem.Initialize(fileStream.AsStorage()).ThrowIfFailure(); - - _virtualFileSystem.ImportTickets(partitionFileSystem); + using var pfs = PartitionFileSystemUtils.OpenApplicationFileSystem(containerPath, _virtualFileSystem); } } } diff --git a/src/Ryujinx.HLE/FileSystem/ContentMetaData.cs b/src/Ryujinx.HLE/FileSystem/ContentMetaData.cs new file mode 100644 index 00000000..aebcf798 --- /dev/null +++ b/src/Ryujinx.HLE/FileSystem/ContentMetaData.cs @@ -0,0 +1,61 @@ +using LibHac.Common.Keys; +using LibHac.Fs.Fsa; +using LibHac.Ncm; +using LibHac.Tools.FsSystem.NcaUtils; +using LibHac.Tools.Ncm; +using Ryujinx.HLE.Loaders.Processes.Extensions; +using System; + +namespace Ryujinx.HLE.FileSystem +{ + /// <summary> + /// Thin wrapper around <see cref="Cnmt"/> + /// </summary> + public class ContentMetaData + { + private readonly IFileSystem _pfs; + private readonly Cnmt _cnmt; + + public ulong Id => _cnmt.TitleId; + public TitleVersion Version => _cnmt.TitleVersion; + public ContentMetaType Type => _cnmt.Type; + public ulong ApplicationId => _cnmt.ApplicationTitleId; + public ulong PatchId => _cnmt.PatchTitleId; + public TitleVersion RequiredSystemVersion => _cnmt.MinimumSystemVersion; + public TitleVersion RequiredApplicationVersion => _cnmt.MinimumApplicationVersion; + public byte[] Digest => _cnmt.Hash; + + public ulong ProgramBaseId => Id & ~0x1FFFUL; + public bool IsSystemTitle => _cnmt.Type < ContentMetaType.Application; + + public ContentMetaData(IFileSystem pfs, Cnmt cnmt) + { + _pfs = pfs; + _cnmt = cnmt; + } + + public Nca GetNcaByType(KeySet keySet, ContentType type, int programIndex = 0) + { + // TODO: Replace this with a check for IdOffset as soon as LibHac supports it: + // && entry.IdOffset == programIndex + + foreach (var entry in _cnmt.ContentEntries) + { + if (entry.Type != type) + { + continue; + } + + string ncaId = BitConverter.ToString(entry.NcaId).Replace("-", null).ToLower(); + Nca nca = _pfs.GetNca(keySet, $"/{ncaId}.nca"); + + if (nca.GetProgramIndex() == programIndex) + { + return nca; + } + } + + return null; + } + } +} |
