From 1c75945dc4a89307f04d5f48a4363adb44d08ac8 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 10 Jun 2019 00:19:23 -0400 Subject: [PATCH 1/2] nsp: Use title ID from NPDM metadata for extracted type NSPs Avoids 0 being used as title ID for all extracted NSPs. --- src/core/file_sys/submission_package.cpp | 21 +++++++++++++++++++++ src/core/loader/nsp.cpp | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index c69caae0f8..753d2f58a3 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -85,12 +85,29 @@ Loader::ResultStatus NSP::GetProgramStatus(u64 title_id) const { } u64 NSP::GetFirstTitleID() const { + if (IsExtractedType()) { + return GetProgramTitleID(); + } + if (program_status.empty()) return 0; return program_status.begin()->first; } u64 NSP::GetProgramTitleID() const { + if (IsExtractedType()) { + if (GetExeFS() == nullptr || !IsDirectoryExeFS(GetExeFS())) { + return 0; + } + + ProgramMetadata meta; + if (meta.Load(GetExeFS()->GetFile("main.npdm")) == Loader::ResultStatus::Success) { + return meta.GetTitleID(); + } else { + return 0; + } + } + const auto out = GetFirstTitleID(); if ((out & 0x800) == 0) return out; @@ -102,6 +119,10 @@ u64 NSP::GetProgramTitleID() const { } std::vector NSP::GetTitleIDs() const { + if (IsExtractedType()) { + return {GetProgramTitleID()}; + } + std::vector out; out.reserve(ncas.size()); for (const auto& kv : ncas) diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index ad56bbb385..8b90bbd30a 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -77,7 +77,7 @@ AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::Process& process) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } - if (title_id == 0) { + if (!nsp->IsExtractedType() && title_id == 0) { return {ResultStatus::ErrorNSPMissingProgramNCA, {}}; } From b957a4862ff370f7f8c213159eb49c3743dd93f5 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 10 Jun 2019 00:21:41 -0400 Subject: [PATCH 2/2] nsp: Correct status codes for extracted NSPs Avoids all extracted NSPs being marked as error file type because they don't have program NCAs. --- src/core/file_sys/submission_package.cpp | 5 +++++ src/core/loader/nsp.cpp | 25 ++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index 753d2f58a3..691ca90c8e 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -14,6 +14,7 @@ #include "core/file_sys/content_archive.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/partition_filesystem.h" +#include "core/file_sys/program_metadata.h" #include "core/file_sys/submission_package.h" #include "core/loader/loader.h" @@ -78,6 +79,10 @@ Loader::ResultStatus NSP::GetStatus() const { } Loader::ResultStatus NSP::GetProgramStatus(u64 title_id) const { + if (IsExtractedType() && GetExeFS() != nullptr && FileSys::IsDirectoryExeFS(GetExeFS())) { + return Loader::ResultStatus::Success; + } + const auto iter = program_status.find(title_id); if (iter == program_status.end()) return Loader::ResultStatus::ErrorNSPMissingProgramNCA; diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 8b90bbd30a..9035dc3f9d 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -26,20 +26,18 @@ AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file) if (nsp->GetStatus() != ResultStatus::Success) return; - if (nsp->IsExtractedType()) - return; - - const auto control_nca = - nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control); - if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) - return; - - std::tie(nacp_file, icon_file) = - FileSys::PatchManager(nsp->GetProgramTitleID()).ParseControlNCA(*control_nca); if (nsp->IsExtractedType()) { secondary_loader = std::make_unique(nsp->GetExeFS()); } else { + const auto control_nca = + nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control); + if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) + return; + + std::tie(nacp_file, icon_file) = + FileSys::PatchManager(nsp->GetProgramTitleID()).ParseControlNCA(*control_nca); + if (title_id == 0) return; @@ -56,11 +54,11 @@ FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& file) { if (nsp.GetStatus() == ResultStatus::Success) { // Extracted Type case if (nsp.IsExtractedType() && nsp.GetExeFS() != nullptr && - FileSys::IsDirectoryExeFS(nsp.GetExeFS()) && nsp.GetRomFS() != nullptr) { + FileSys::IsDirectoryExeFS(nsp.GetExeFS())) { return FileType::NSP; } - // Non-Ectracted Type case + // Non-Extracted Type case if (!nsp.IsExtractedType() && nsp.GetNCA(nsp.GetFirstTitleID(), FileSys::ContentRecordType::Program) != nullptr && AppLoader_NCA::IdentifyType(nsp.GetNCAFile( @@ -91,7 +89,8 @@ AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::Process& process) { return {nsp_program_status, {}}; } - if (nsp->GetNCA(title_id, FileSys::ContentRecordType::Program) == nullptr) { + if (!nsp->IsExtractedType() && + nsp->GetNCA(title_id, FileSys::ContentRecordType::Program) == nullptr) { if (!Core::Crypto::KeyManager::KeyFileExists(false)) { return {ResultStatus::ErrorMissingProductionKeyFile, {}}; }