aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.HLE/FileSystem
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.HLE/FileSystem')
-rw-r--r--src/Ryujinx.HLE/FileSystem/ContentManager.cs42
-rw-r--r--src/Ryujinx.HLE/FileSystem/ContentMetaData.cs61
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;
+ }
+ }
+}