diff options
-rw-r--r-- | src/core/file_sys/content_archive.cpp | 4 | ||||
-rw-r--r-- | src/core/file_sys/content_archive.h | 1 | ||||
-rw-r--r-- | src/core/hle/service/am/library_applet_creator.cpp | 10 | ||||
-rw-r--r-- | src/core/hle/service/am/process.cpp | 23 | ||||
-rw-r--r-- | src/core/hle/service/am/process.h | 2 |
5 files changed, 33 insertions, 7 deletions
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 285fe4db6..665252358 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -172,6 +172,10 @@ u32 NCA::GetSDKVersion() const { return reader->GetSdkAddonVersion(); } +u8 NCA::GetKeyGeneration() const { + return reader->GetKeyGeneration(); +} + bool NCA::IsUpdate() const { return is_update; } diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index f68464eb0..8560617f5 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h @@ -77,6 +77,7 @@ public: u64 GetTitleId() const; RightsId GetRightsId() const; u32 GetSDKVersion() const; + u8 GetKeyGeneration() const; bool IsUpdate() const; VirtualFile GetRomFS() const; diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/library_applet_creator.cpp index c48ed29bc..00d5a0705 100644 --- a/src/core/hle/service/am/library_applet_creator.cpp +++ b/src/core/hle/service/am/library_applet_creator.cpp @@ -102,8 +102,16 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, return {}; } + // TODO: enable other versions of applets + enum : u8 { + Firmware1400 = 14, + Firmware1500 = 15, + Firmware1600 = 16, + Firmware1700 = 17, + }; + auto process = std::make_unique<Process>(system); - if (!process->Initialize(program_id)) { + if (!process->Initialize(program_id, Firmware1400, Firmware1700)) { // Couldn't initialize the guest process return {}; } diff --git a/src/core/hle/service/am/process.cpp b/src/core/hle/service/am/process.cpp index 16b685f86..992c50713 100644 --- a/src/core/hle/service/am/process.cpp +++ b/src/core/hle/service/am/process.cpp @@ -3,6 +3,7 @@ #include "common/scope_exit.h" +#include "core/file_sys/content_archive.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/registered_cache.h" #include "core/hle/kernel/k_process.h" @@ -20,7 +21,7 @@ Process::~Process() { this->Finalize(); } -bool Process::Initialize(u64 program_id) { +bool Process::Initialize(u64 program_id, u8 minimum_key_generation, u8 maximum_key_generation) { // First, ensure we are not holding another process. this->Finalize(); @@ -29,21 +30,33 @@ bool Process::Initialize(u64 program_id) { // Attempt to load program NCA. const FileSys::RegisteredCache* bis_system{}; - FileSys::VirtualFile nca{}; + FileSys::VirtualFile nca_raw{}; // Get the program NCA from built-in storage. bis_system = fsc.GetSystemNANDContents(); if (bis_system) { - nca = bis_system->GetEntryRaw(program_id, FileSys::ContentRecordType::Program); + nca_raw = bis_system->GetEntryRaw(program_id, FileSys::ContentRecordType::Program); } // Ensure we retrieved a program NCA. - if (!nca) { + if (!nca_raw) { return false; } + // Ensure we have a suitable version. + if (minimum_key_generation > 0) { + FileSys::NCA nca(nca_raw); + if (nca.GetStatus() == Loader::ResultStatus::Success && + (nca.GetKeyGeneration() < minimum_key_generation || + nca.GetKeyGeneration() > maximum_key_generation)) { + LOG_WARNING(Service_LDR, "Skipping program {:016X} with generation {}", program_id, + nca.GetKeyGeneration()); + return false; + } + } + // Get the appropriate loader to parse this NCA. - auto app_loader = Loader::GetLoader(m_system, nca, program_id, 0); + auto app_loader = Loader::GetLoader(m_system, nca_raw, program_id, 0); // Ensure we have a loader which can parse the NCA. if (!app_loader) { diff --git a/src/core/hle/service/am/process.h b/src/core/hle/service/am/process.h index 4b908ade4..4b8102fb6 100644 --- a/src/core/hle/service/am/process.h +++ b/src/core/hle/service/am/process.h @@ -21,7 +21,7 @@ public: explicit Process(Core::System& system); ~Process(); - bool Initialize(u64 program_id); + bool Initialize(u64 program_id, u8 minimum_key_generation, u8 maximum_key_generation); void Finalize(); bool Run(); |