From 86f6b6b7b2d930e8203114332b04a5c49a780b06 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 10 Aug 2023 21:34:43 -0400 Subject: vfs: expand support for NCA reading --- src/core/loader/loader.cpp | 4 ++-- src/core/loader/loader.h | 12 ------------ src/core/loader/nax.cpp | 4 ---- src/core/loader/nax.h | 1 - src/core/loader/nca.cpp | 28 ++++++++++++++++++---------- src/core/loader/nca.h | 1 - src/core/loader/nsp.cpp | 4 ---- src/core/loader/nsp.h | 1 - src/core/loader/xci.cpp | 4 ---- src/core/loader/xci.h | 1 - 10 files changed, 20 insertions(+), 40 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index f24474ed8..07c65dc1a 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -135,7 +135,7 @@ constexpr std::array RESULT_MESSAGES{ "The titlekey and/or titlekek is incorrect or the section header is invalid.", "The XCI file is missing a Program-type NCA.", "The NCA file is not an application.", - "The ExeFS partition could not be found.", + "The Program-type NCA contains no executable. An update may be required.", "The XCI file has a bad header.", "The XCI file is missing a partition.", "The file could not be found or does not exist.", @@ -169,7 +169,7 @@ constexpr std::array RESULT_MESSAGES{ "The BKTR-type NCA has a bad Subsection block.", "The BKTR-type NCA has a bad Relocation bucket.", "The BKTR-type NCA has a bad Subsection bucket.", - "The BKTR-type NCA is missing the base RomFS.", + "Game updates cannot be loaded directly. Load the base game instead.", "The NSP or XCI does not contain an update in addition to the base game.", "The KIP file has a bad header.", "The KIP BLZ decompression of the section failed unexpectedly.", diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 7a2a52fd4..721eb8e8c 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -79,8 +79,6 @@ enum class ResultStatus : u16 { ErrorBadPFSHeader, ErrorIncorrectPFSFileSize, ErrorBadNCAHeader, - ErrorCompressedNCA, - ErrorSparseNCA, ErrorMissingProductionKeyFile, ErrorMissingHeaderKey, ErrorIncorrectHeaderKey, @@ -275,16 +273,6 @@ public: return true; } - /** - * Gets the difference between the start of the IVFC header and the start of level 6 (RomFS) - * data. Needed for BKTR patching. - * - * @return IVFC offset for RomFS. - */ - virtual u64 ReadRomFSIVFCOffset() const { - return 0; - } - /** * Get the title of the application * diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp index cf35b1249..3b7b005ff 100644 --- a/src/core/loader/nax.cpp +++ b/src/core/loader/nax.cpp @@ -76,10 +76,6 @@ ResultStatus AppLoader_NAX::ReadRomFS(FileSys::VirtualFile& dir) { return nca_loader->ReadRomFS(dir); } -u64 AppLoader_NAX::ReadRomFSIVFCOffset() const { - return nca_loader->ReadRomFSIVFCOffset(); -} - ResultStatus AppLoader_NAX::ReadProgramId(u64& out_program_id) { return nca_loader->ReadProgramId(out_program_id); } diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h index d7f70db43..81df2bbcd 100644 --- a/src/core/loader/nax.h +++ b/src/core/loader/nax.h @@ -39,7 +39,6 @@ public: LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; - u64 ReadRomFSIVFCOffset() const override; ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadBanner(std::vector& buffer) override; diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 513af194d..09d40e695 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -5,6 +5,8 @@ #include "core/core.h" #include "core/file_sys/content_archive.h" +#include "core/file_sys/nca_metadata.h" +#include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs_factory.h" #include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" @@ -43,9 +45,23 @@ AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::KProcess& process, Core::S return {ResultStatus::ErrorNCANotProgram, {}}; } - const auto exefs = nca->GetExeFS(); + auto exefs = nca->GetExeFS(); if (exefs == nullptr) { - return {ResultStatus::ErrorNoExeFS, {}}; + LOG_INFO(Loader, "No ExeFS found in NCA, looking for ExeFS from update"); + + // This NCA may be a sparse base of an installed title. + // Try to fetch the ExeFS from the installed update. + const auto& installed = system.GetContentProvider(); + const auto update_nca = installed.GetEntry(FileSys::GetUpdateTitleID(nca->GetTitleId()), + FileSys::ContentRecordType::Program); + + if (update_nca) { + exefs = update_nca->GetExeFS(); + } + + if (exefs == nullptr) { + return {ResultStatus::ErrorNoExeFS, {}}; + } } directory_loader = std::make_unique(exefs, true); @@ -77,14 +93,6 @@ ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { return ResultStatus::Success; } -u64 AppLoader_NCA::ReadRomFSIVFCOffset() const { - if (nca == nullptr) { - return 0; - } - - return nca->GetBaseIVFCOffset(); -} - ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) { return ResultStatus::ErrorNotInitialized; diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index d22d9146e..cf356ce63 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -40,7 +40,6 @@ public: LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; - u64 ReadRomFSIVFCOffset() const override; ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadBanner(std::vector& buffer) override; diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 80663e0e0..f9b2549a3 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -121,10 +121,6 @@ ResultStatus AppLoader_NSP::ReadRomFS(FileSys::VirtualFile& out_file) { return secondary_loader->ReadRomFS(out_file); } -u64 AppLoader_NSP::ReadRomFSIVFCOffset() const { - return secondary_loader->ReadRomFSIVFCOffset(); -} - ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& out_file) { if (nsp->IsExtractedType()) { return ResultStatus::ErrorNoPackedUpdate; diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index 003cc345c..79df4586a 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -46,7 +46,6 @@ public: LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; - u64 ReadRomFSIVFCOffset() const override; ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override; ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadProgramIds(std::vector& out_program_ids) override; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index c7b1b3815..3a76bc788 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -89,10 +89,6 @@ ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& out_file) { return nca_loader->ReadRomFS(out_file); } -u64 AppLoader_XCI::ReadRomFSIVFCOffset() const { - return nca_loader->ReadRomFSIVFCOffset(); -} - ResultStatus AppLoader_XCI::ReadUpdateRaw(FileSys::VirtualFile& out_file) { u64 program_id{}; nca_loader->ReadProgramId(program_id); diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 2affb6c6e..ff05e6f62 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -46,7 +46,6 @@ public: LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; - u64 ReadRomFSIVFCOffset() const override; ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override; ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadProgramIds(std::vector& out_program_ids) override; -- cgit v1.2.3