diff options
| author | 2023-08-10 21:34:43 -0400 | |
|---|---|---|
| committer | 2023-08-15 17:47:25 -0400 | |
| commit | 86f6b6b7b2d930e8203114332b04a5c49a780b06 (patch) | |
| tree | bf7ff58b0a36051d3c3489a40999d80357c570d0 /src/core/loader | |
| parent | Merge pull request #11287 from liamwhite/replaced-bytes (diff) | |
| download | yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.tar.gz yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.tar.xz yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.zip | |
vfs: expand support for NCA reading
Diffstat (limited to 'src/core/loader')
| -rw-r--r-- | src/core/loader/loader.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 12 | ||||
| -rw-r--r-- | src/core/loader/nax.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/nax.h | 1 | ||||
| -rw-r--r-- | src/core/loader/nca.cpp | 28 | ||||
| -rw-r--r-- | src/core/loader/nca.h | 1 | ||||
| -rw-r--r-- | src/core/loader/nsp.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/nsp.h | 1 | ||||
| -rw-r--r-- | src/core/loader/xci.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/xci.h | 1 |
10 files changed, 20 insertions, 40 deletions
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<const char*, 66> RESULT_MESSAGES{ | |||
| 135 | "The titlekey and/or titlekek is incorrect or the section header is invalid.", | 135 | "The titlekey and/or titlekek is incorrect or the section header is invalid.", |
| 136 | "The XCI file is missing a Program-type NCA.", | 136 | "The XCI file is missing a Program-type NCA.", |
| 137 | "The NCA file is not an application.", | 137 | "The NCA file is not an application.", |
| 138 | "The ExeFS partition could not be found.", | 138 | "The Program-type NCA contains no executable. An update may be required.", |
| 139 | "The XCI file has a bad header.", | 139 | "The XCI file has a bad header.", |
| 140 | "The XCI file is missing a partition.", | 140 | "The XCI file is missing a partition.", |
| 141 | "The file could not be found or does not exist.", | 141 | "The file could not be found or does not exist.", |
| @@ -169,7 +169,7 @@ constexpr std::array<const char*, 66> RESULT_MESSAGES{ | |||
| 169 | "The BKTR-type NCA has a bad Subsection block.", | 169 | "The BKTR-type NCA has a bad Subsection block.", |
| 170 | "The BKTR-type NCA has a bad Relocation bucket.", | 170 | "The BKTR-type NCA has a bad Relocation bucket.", |
| 171 | "The BKTR-type NCA has a bad Subsection bucket.", | 171 | "The BKTR-type NCA has a bad Subsection bucket.", |
| 172 | "The BKTR-type NCA is missing the base RomFS.", | 172 | "Game updates cannot be loaded directly. Load the base game instead.", |
| 173 | "The NSP or XCI does not contain an update in addition to the base game.", | 173 | "The NSP or XCI does not contain an update in addition to the base game.", |
| 174 | "The KIP file has a bad header.", | 174 | "The KIP file has a bad header.", |
| 175 | "The KIP BLZ decompression of the section failed unexpectedly.", | 175 | "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 { | |||
| 79 | ErrorBadPFSHeader, | 79 | ErrorBadPFSHeader, |
| 80 | ErrorIncorrectPFSFileSize, | 80 | ErrorIncorrectPFSFileSize, |
| 81 | ErrorBadNCAHeader, | 81 | ErrorBadNCAHeader, |
| 82 | ErrorCompressedNCA, | ||
| 83 | ErrorSparseNCA, | ||
| 84 | ErrorMissingProductionKeyFile, | 82 | ErrorMissingProductionKeyFile, |
| 85 | ErrorMissingHeaderKey, | 83 | ErrorMissingHeaderKey, |
| 86 | ErrorIncorrectHeaderKey, | 84 | ErrorIncorrectHeaderKey, |
| @@ -276,16 +274,6 @@ public: | |||
| 276 | } | 274 | } |
| 277 | 275 | ||
| 278 | /** | 276 | /** |
| 279 | * Gets the difference between the start of the IVFC header and the start of level 6 (RomFS) | ||
| 280 | * data. Needed for BKTR patching. | ||
| 281 | * | ||
| 282 | * @return IVFC offset for RomFS. | ||
| 283 | */ | ||
| 284 | virtual u64 ReadRomFSIVFCOffset() const { | ||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | /** | ||
| 289 | * Get the title of the application | 277 | * Get the title of the application |
| 290 | * | 278 | * |
| 291 | * @param[out] title Reference to store the application title into | 279 | * @param[out] title Reference to store the application title into |
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) { | |||
| 76 | return nca_loader->ReadRomFS(dir); | 76 | return nca_loader->ReadRomFS(dir); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | u64 AppLoader_NAX::ReadRomFSIVFCOffset() const { | ||
| 80 | return nca_loader->ReadRomFSIVFCOffset(); | ||
| 81 | } | ||
| 82 | |||
| 83 | ResultStatus AppLoader_NAX::ReadProgramId(u64& out_program_id) { | 79 | ResultStatus AppLoader_NAX::ReadProgramId(u64& out_program_id) { |
| 84 | return nca_loader->ReadProgramId(out_program_id); | 80 | return nca_loader->ReadProgramId(out_program_id); |
| 85 | } | 81 | } |
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: | |||
| 39 | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; | 39 | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; |
| 40 | 40 | ||
| 41 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | 41 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; |
| 42 | u64 ReadRomFSIVFCOffset() const override; | ||
| 43 | ResultStatus ReadProgramId(u64& out_program_id) override; | 42 | ResultStatus ReadProgramId(u64& out_program_id) override; |
| 44 | 43 | ||
| 45 | ResultStatus ReadBanner(std::vector<u8>& buffer) override; | 44 | ResultStatus ReadBanner(std::vector<u8>& 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 @@ | |||
| 5 | 5 | ||
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/file_sys/content_archive.h" | 7 | #include "core/file_sys/content_archive.h" |
| 8 | #include "core/file_sys/nca_metadata.h" | ||
| 9 | #include "core/file_sys/registered_cache.h" | ||
| 8 | #include "core/file_sys/romfs_factory.h" | 10 | #include "core/file_sys/romfs_factory.h" |
| 9 | #include "core/hle/kernel/k_process.h" | 11 | #include "core/hle/kernel/k_process.h" |
| 10 | #include "core/hle/service/filesystem/filesystem.h" | 12 | #include "core/hle/service/filesystem/filesystem.h" |
| @@ -43,9 +45,23 @@ AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::KProcess& process, Core::S | |||
| 43 | return {ResultStatus::ErrorNCANotProgram, {}}; | 45 | return {ResultStatus::ErrorNCANotProgram, {}}; |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | const auto exefs = nca->GetExeFS(); | 48 | auto exefs = nca->GetExeFS(); |
| 47 | if (exefs == nullptr) { | 49 | if (exefs == nullptr) { |
| 48 | return {ResultStatus::ErrorNoExeFS, {}}; | 50 | LOG_INFO(Loader, "No ExeFS found in NCA, looking for ExeFS from update"); |
| 51 | |||
| 52 | // This NCA may be a sparse base of an installed title. | ||
| 53 | // Try to fetch the ExeFS from the installed update. | ||
| 54 | const auto& installed = system.GetContentProvider(); | ||
| 55 | const auto update_nca = installed.GetEntry(FileSys::GetUpdateTitleID(nca->GetTitleId()), | ||
| 56 | FileSys::ContentRecordType::Program); | ||
| 57 | |||
| 58 | if (update_nca) { | ||
| 59 | exefs = update_nca->GetExeFS(); | ||
| 60 | } | ||
| 61 | |||
| 62 | if (exefs == nullptr) { | ||
| 63 | return {ResultStatus::ErrorNoExeFS, {}}; | ||
| 64 | } | ||
| 49 | } | 65 | } |
| 50 | 66 | ||
| 51 | directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs, true); | 67 | directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs, true); |
| @@ -77,14 +93,6 @@ ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { | |||
| 77 | return ResultStatus::Success; | 93 | return ResultStatus::Success; |
| 78 | } | 94 | } |
| 79 | 95 | ||
| 80 | u64 AppLoader_NCA::ReadRomFSIVFCOffset() const { | ||
| 81 | if (nca == nullptr) { | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | return nca->GetBaseIVFCOffset(); | ||
| 86 | } | ||
| 87 | |||
| 88 | ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { | 96 | ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { |
| 89 | if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) { | 97 | if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) { |
| 90 | return ResultStatus::ErrorNotInitialized; | 98 | 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: | |||
| 40 | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; | 40 | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; |
| 41 | 41 | ||
| 42 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | 42 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; |
| 43 | u64 ReadRomFSIVFCOffset() const override; | ||
| 44 | ResultStatus ReadProgramId(u64& out_program_id) override; | 43 | ResultStatus ReadProgramId(u64& out_program_id) override; |
| 45 | 44 | ||
| 46 | ResultStatus ReadBanner(std::vector<u8>& buffer) override; | 45 | ResultStatus ReadBanner(std::vector<u8>& 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) { | |||
| 121 | return secondary_loader->ReadRomFS(out_file); | 121 | return secondary_loader->ReadRomFS(out_file); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | u64 AppLoader_NSP::ReadRomFSIVFCOffset() const { | ||
| 125 | return secondary_loader->ReadRomFSIVFCOffset(); | ||
| 126 | } | ||
| 127 | |||
| 128 | ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& out_file) { | 124 | ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& out_file) { |
| 129 | if (nsp->IsExtractedType()) { | 125 | if (nsp->IsExtractedType()) { |
| 130 | return ResultStatus::ErrorNoPackedUpdate; | 126 | 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: | |||
| 46 | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; | 46 | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; |
| 47 | 47 | ||
| 48 | ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; | 48 | ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; |
| 49 | u64 ReadRomFSIVFCOffset() const override; | ||
| 50 | ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override; | 49 | ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override; |
| 51 | ResultStatus ReadProgramId(u64& out_program_id) override; | 50 | ResultStatus ReadProgramId(u64& out_program_id) override; |
| 52 | ResultStatus ReadProgramIds(std::vector<u64>& out_program_ids) override; | 51 | ResultStatus ReadProgramIds(std::vector<u64>& 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) { | |||
| 89 | return nca_loader->ReadRomFS(out_file); | 89 | return nca_loader->ReadRomFS(out_file); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | u64 AppLoader_XCI::ReadRomFSIVFCOffset() const { | ||
| 93 | return nca_loader->ReadRomFSIVFCOffset(); | ||
| 94 | } | ||
| 95 | |||
| 96 | ResultStatus AppLoader_XCI::ReadUpdateRaw(FileSys::VirtualFile& out_file) { | 92 | ResultStatus AppLoader_XCI::ReadUpdateRaw(FileSys::VirtualFile& out_file) { |
| 97 | u64 program_id{}; | 93 | u64 program_id{}; |
| 98 | nca_loader->ReadProgramId(program_id); | 94 | 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: | |||
| 46 | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; | 46 | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; |
| 47 | 47 | ||
| 48 | ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; | 48 | ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; |
| 49 | u64 ReadRomFSIVFCOffset() const override; | ||
| 50 | ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override; | 49 | ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override; |
| 51 | ResultStatus ReadProgramId(u64& out_program_id) override; | 50 | ResultStatus ReadProgramId(u64& out_program_id) override; |
| 52 | ResultStatus ReadProgramIds(std::vector<u64>& out_program_ids) override; | 51 | ResultStatus ReadProgramIds(std::vector<u64>& out_program_ids) override; |