Procházet zdrojové kódy

am: use applet program loading for tested versions

Liam před 2 roky
rodič
revize
4677fd3f64

+ 4 - 0
src/core/file_sys/content_archive.cpp

@@ -172,6 +172,10 @@ u32 NCA::GetSDKVersion() const {
     return reader->GetSdkAddonVersion();
     return reader->GetSdkAddonVersion();
 }
 }
 
 
+u8 NCA::GetKeyGeneration() const {
+    return reader->GetKeyGeneration();
+}
+
 bool NCA::IsUpdate() const {
 bool NCA::IsUpdate() const {
     return is_update;
     return is_update;
 }
 }

+ 1 - 0
src/core/file_sys/content_archive.h

@@ -77,6 +77,7 @@ public:
     u64 GetTitleId() const;
     u64 GetTitleId() const;
     RightsId GetRightsId() const;
     RightsId GetRightsId() const;
     u32 GetSDKVersion() const;
     u32 GetSDKVersion() const;
+    u8 GetKeyGeneration() const;
     bool IsUpdate() const;
     bool IsUpdate() const;
 
 
     VirtualFile GetRomFS() const;
     VirtualFile GetRomFS() const;

+ 9 - 1
src/core/hle/service/am/library_applet_creator.cpp

@@ -102,8 +102,16 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
         return {};
         return {};
     }
     }
 
 
+    // TODO: enable other versions of applets
+    enum : u8 {
+        Firmware1400 = 14,
+        Firmware1500 = 15,
+        Firmware1600 = 16,
+        Firmware1700 = 17,
+    };
+
     auto process = std::make_unique<Process>(system);
     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
         // Couldn't initialize the guest process
         return {};
         return {};
     }
     }

+ 18 - 5
src/core/hle/service/am/process.cpp

@@ -3,6 +3,7 @@
 
 
 #include "common/scope_exit.h"
 #include "common/scope_exit.h"
 
 
+#include "core/file_sys/content_archive.h"
 #include "core/file_sys/nca_metadata.h"
 #include "core/file_sys/nca_metadata.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/hle/kernel/k_process.h"
 #include "core/hle/kernel/k_process.h"
@@ -20,7 +21,7 @@ Process::~Process() {
     this->Finalize();
     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.
     // First, ensure we are not holding another process.
     this->Finalize();
     this->Finalize();
 
 
@@ -29,21 +30,33 @@ bool Process::Initialize(u64 program_id) {
 
 
     // Attempt to load program NCA.
     // Attempt to load program NCA.
     const FileSys::RegisteredCache* bis_system{};
     const FileSys::RegisteredCache* bis_system{};
-    FileSys::VirtualFile nca{};
+    FileSys::VirtualFile nca_raw{};
 
 
     // Get the program NCA from built-in storage.
     // Get the program NCA from built-in storage.
     bis_system = fsc.GetSystemNANDContents();
     bis_system = fsc.GetSystemNANDContents();
     if (bis_system) {
     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.
     // Ensure we retrieved a program NCA.
-    if (!nca) {
+    if (!nca_raw) {
         return false;
         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.
     // 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.
     // Ensure we have a loader which can parse the NCA.
     if (!app_loader) {
     if (!app_loader) {

+ 1 - 1
src/core/hle/service/am/process.h

@@ -21,7 +21,7 @@ public:
     explicit Process(Core::System& system);
     explicit Process(Core::System& system);
     ~Process();
     ~Process();
 
 
-    bool Initialize(u64 program_id);
+    bool Initialize(u64 program_id, u8 minimum_key_generation, u8 maximum_key_generation);
     void Finalize();
     void Finalize();
 
 
     bool Run();
     bool Run();