ContentMetaData.cs
1 using LibHac.Common.Keys; 2 using LibHac.Fs.Fsa; 3 using LibHac.Ncm; 4 using LibHac.Tools.FsSystem.NcaUtils; 5 using LibHac.Tools.Ncm; 6 using Ryujinx.HLE.Loaders.Processes.Extensions; 7 using System; 8 9 namespace Ryujinx.HLE.FileSystem 10 { 11 /// <summary> 12 /// Thin wrapper around <see cref="Cnmt"/> 13 /// </summary> 14 public class ContentMetaData 15 { 16 private readonly IFileSystem _pfs; 17 private readonly Cnmt _cnmt; 18 19 public ulong Id => _cnmt.TitleId; 20 public TitleVersion Version => _cnmt.TitleVersion; 21 public ContentMetaType Type => _cnmt.Type; 22 public ulong ApplicationId => _cnmt.ApplicationTitleId; 23 public ulong PatchId => _cnmt.PatchTitleId; 24 public TitleVersion RequiredSystemVersion => _cnmt.MinimumSystemVersion; 25 public TitleVersion RequiredApplicationVersion => _cnmt.MinimumApplicationVersion; 26 public byte[] Digest => _cnmt.Hash; 27 28 public ulong ProgramBaseId => Id & ~0x1FFFUL; 29 public bool IsSystemTitle => _cnmt.Type < ContentMetaType.Application; 30 31 public ContentMetaData(IFileSystem pfs, Cnmt cnmt) 32 { 33 _pfs = pfs; 34 _cnmt = cnmt; 35 } 36 37 public Nca GetNcaByType(KeySet keySet, ContentType type, int programIndex = 0) 38 { 39 // TODO: Replace this with a check for IdOffset as soon as LibHac supports it: 40 // && entry.IdOffset == programIndex 41 42 foreach (var entry in _cnmt.ContentEntries) 43 { 44 if (entry.Type != type) 45 { 46 continue; 47 } 48 49 string ncaId = BitConverter.ToString(entry.NcaId).Replace("-", null).ToLower(); 50 Nca nca = _pfs.GetNca(keySet, $"/{ncaId}.nca"); 51 52 if (nca.GetProgramIndex() == programIndex) 53 { 54 return nca; 55 } 56 } 57 58 return null; 59 } 60 } 61 }