diff options
| author | 2018-09-05 18:06:11 -0400 | |
|---|---|---|
| committer | 2018-09-05 18:06:11 -0400 | |
| commit | a6ae7654105fe6ec46ff0bcabb714b8447b83899 (patch) | |
| tree | 0ff4d2396cb0730ec5952181e4e67947b64832ec /src/core/loader | |
| parent | Merge pull request #1245 from degasus/optimizations (diff) | |
| parent | bktr: Fix bucket overlap error (diff) | |
| download | yuzu-a6ae7654105fe6ec46ff0bcabb714b8447b83899.tar.gz yuzu-a6ae7654105fe6ec46ff0bcabb714b8447b83899.tar.xz yuzu-a6ae7654105fe6ec46ff0bcabb714b8447b83899.zip | |
Merge pull request #1179 from DarkLordZach/bktr
file_sys: Add support for BKTR format (Game Updates)
Diffstat (limited to 'src/core/loader')
| -rw-r--r-- | src/core/loader/deconstructed_rom_directory.cpp | 42 | ||||
| -rw-r--r-- | src/core/loader/deconstructed_rom_directory.h | 8 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 13 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 29 | ||||
| -rw-r--r-- | src/core/loader/nca.cpp | 8 | ||||
| -rw-r--r-- | src/core/loader/nca.h | 1 | ||||
| -rw-r--r-- | src/core/loader/nro.cpp | 5 | ||||
| -rw-r--r-- | src/core/loader/nro.h | 1 | ||||
| -rw-r--r-- | src/core/loader/nsp.cpp | 20 | ||||
| -rw-r--r-- | src/core/loader/xci.cpp | 18 |
10 files changed, 101 insertions, 44 deletions
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 1ae4bb656..2b8f78136 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/file_sys/content_archive.h" | 10 | #include "core/file_sys/content_archive.h" |
| 11 | #include "core/file_sys/control_metadata.h" | 11 | #include "core/file_sys/control_metadata.h" |
| 12 | #include "core/file_sys/patch_manager.h" | ||
| 12 | #include "core/file_sys/romfs_factory.h" | 13 | #include "core/file_sys/romfs_factory.h" |
| 13 | #include "core/gdbstub/gdbstub.h" | 14 | #include "core/gdbstub/gdbstub.h" |
| 14 | #include "core/hle/kernel/kernel.h" | 15 | #include "core/hle/kernel/kernel.h" |
| @@ -21,10 +22,19 @@ | |||
| 21 | 22 | ||
| 22 | namespace Loader { | 23 | namespace Loader { |
| 23 | 24 | ||
| 24 | AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_) | 25 | AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, |
| 25 | : AppLoader(std::move(file_)) { | 26 | bool override_update) |
| 27 | : AppLoader(std::move(file_)), override_update(override_update) { | ||
| 26 | const auto dir = file->GetContainingDirectory(); | 28 | const auto dir = file->GetContainingDirectory(); |
| 27 | 29 | ||
| 30 | // Title ID | ||
| 31 | const auto npdm = dir->GetFile("main.npdm"); | ||
| 32 | if (npdm != nullptr) { | ||
| 33 | const auto res = metadata.Load(npdm); | ||
| 34 | if (res == ResultStatus::Success) | ||
| 35 | title_id = metadata.GetTitleID(); | ||
| 36 | } | ||
| 37 | |||
| 28 | // Icon | 38 | // Icon |
| 29 | FileSys::VirtualFile icon_file = nullptr; | 39 | FileSys::VirtualFile icon_file = nullptr; |
| 30 | for (const auto& language : FileSys::LANGUAGE_NAMES) { | 40 | for (const auto& language : FileSys::LANGUAGE_NAMES) { |
| @@ -66,8 +76,9 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys | |||
| 66 | } | 76 | } |
| 67 | 77 | ||
| 68 | AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory( | 78 | AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory( |
| 69 | FileSys::VirtualDir directory) | 79 | FileSys::VirtualDir directory, bool override_update) |
| 70 | : AppLoader(directory->GetFile("main")), dir(std::move(directory)) {} | 80 | : AppLoader(directory->GetFile("main")), dir(std::move(directory)), |
| 81 | override_update(override_update) {} | ||
| 71 | 82 | ||
| 72 | FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { | 83 | FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { |
| 73 | if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { | 84 | if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { |
| @@ -89,7 +100,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( | |||
| 89 | dir = file->GetContainingDirectory(); | 100 | dir = file->GetContainingDirectory(); |
| 90 | } | 101 | } |
| 91 | 102 | ||
| 92 | const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); | 103 | // Read meta to determine title ID |
| 104 | FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); | ||
| 93 | if (npdm == nullptr) | 105 | if (npdm == nullptr) |
| 94 | return ResultStatus::ErrorMissingNPDM; | 106 | return ResultStatus::ErrorMissingNPDM; |
| 95 | 107 | ||
| @@ -97,6 +109,21 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( | |||
| 97 | if (result != ResultStatus::Success) { | 109 | if (result != ResultStatus::Success) { |
| 98 | return result; | 110 | return result; |
| 99 | } | 111 | } |
| 112 | |||
| 113 | if (override_update) { | ||
| 114 | const FileSys::PatchManager patch_manager(metadata.GetTitleID()); | ||
| 115 | dir = patch_manager.PatchExeFS(dir); | ||
| 116 | } | ||
| 117 | |||
| 118 | // Reread in case PatchExeFS affected the main.npdm | ||
| 119 | npdm = dir->GetFile("main.npdm"); | ||
| 120 | if (npdm == nullptr) | ||
| 121 | return ResultStatus::ErrorMissingNPDM; | ||
| 122 | |||
| 123 | ResultStatus result2 = metadata.Load(npdm); | ||
| 124 | if (result2 != ResultStatus::Success) { | ||
| 125 | return result2; | ||
| 126 | } | ||
| 100 | metadata.Print(); | 127 | metadata.Print(); |
| 101 | 128 | ||
| 102 | const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; | 129 | const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; |
| @@ -119,7 +146,6 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( | |||
| 119 | } | 146 | } |
| 120 | 147 | ||
| 121 | auto& kernel = Core::System::GetInstance().Kernel(); | 148 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 122 | title_id = metadata.GetTitleID(); | ||
| 123 | process->program_id = metadata.GetTitleID(); | 149 | process->program_id = metadata.GetTitleID(); |
| 124 | process->svc_access_mask.set(); | 150 | process->svc_access_mask.set(); |
| 125 | process->resource_limit = | 151 | process->resource_limit = |
| @@ -170,4 +196,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) | |||
| 170 | return ResultStatus::Success; | 196 | return ResultStatus::Success; |
| 171 | } | 197 | } |
| 172 | 198 | ||
| 199 | bool AppLoader_DeconstructedRomDirectory::IsRomFSUpdatable() const { | ||
| 200 | return false; | ||
| 201 | } | ||
| 202 | |||
| 173 | } // namespace Loader | 203 | } // namespace Loader |
diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index b20804f75..8a0dc1b1e 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h | |||
| @@ -20,10 +20,12 @@ namespace Loader { | |||
| 20 | */ | 20 | */ |
| 21 | class AppLoader_DeconstructedRomDirectory final : public AppLoader { | 21 | class AppLoader_DeconstructedRomDirectory final : public AppLoader { |
| 22 | public: | 22 | public: |
| 23 | explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file); | 23 | explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file, |
| 24 | bool override_update = false); | ||
| 24 | 25 | ||
| 25 | // Overload to accept exefs directory. Must contain 'main' and 'main.npdm' | 26 | // Overload to accept exefs directory. Must contain 'main' and 'main.npdm' |
| 26 | explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory); | 27 | explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory, |
| 28 | bool override_update = false); | ||
| 27 | 29 | ||
| 28 | /** | 30 | /** |
| 29 | * Returns the type of the file | 31 | * Returns the type of the file |
| @@ -42,6 +44,7 @@ public: | |||
| 42 | ResultStatus ReadIcon(std::vector<u8>& buffer) override; | 44 | ResultStatus ReadIcon(std::vector<u8>& buffer) override; |
| 43 | ResultStatus ReadProgramId(u64& out_program_id) override; | 45 | ResultStatus ReadProgramId(u64& out_program_id) override; |
| 44 | ResultStatus ReadTitle(std::string& title) override; | 46 | ResultStatus ReadTitle(std::string& title) override; |
| 47 | bool IsRomFSUpdatable() const override; | ||
| 45 | 48 | ||
| 46 | private: | 49 | private: |
| 47 | FileSys::ProgramMetadata metadata; | 50 | FileSys::ProgramMetadata metadata; |
| @@ -51,6 +54,7 @@ private: | |||
| 51 | std::vector<u8> icon_data; | 54 | std::vector<u8> icon_data; |
| 52 | std::string name; | 55 | std::string name; |
| 53 | u64 title_id{}; | 56 | u64 title_id{}; |
| 57 | bool override_update; | ||
| 54 | }; | 58 | }; |
| 55 | 59 | ||
| 56 | } // namespace Loader | 60 | } // namespace Loader |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 446adf557..fa43a2650 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -93,7 +93,7 @@ std::string GetFileTypeString(FileType type) { | |||
| 93 | return "unknown"; | 93 | return "unknown"; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | constexpr std::array<const char*, 50> RESULT_MESSAGES{ | 96 | constexpr std::array<const char*, 58> RESULT_MESSAGES{ |
| 97 | "The operation completed successfully.", | 97 | "The operation completed successfully.", |
| 98 | "The loader requested to load is already loaded.", | 98 | "The loader requested to load is already loaded.", |
| 99 | "The operation is not implemented.", | 99 | "The operation is not implemented.", |
| @@ -143,7 +143,16 @@ constexpr std::array<const char*, 50> RESULT_MESSAGES{ | |||
| 143 | "The AES Key Generation Source could not be found.", | 143 | "The AES Key Generation Source could not be found.", |
| 144 | "The SD Save Key Source could not be found.", | 144 | "The SD Save Key Source could not be found.", |
| 145 | "The SD NCA Key Source could not be found.", | 145 | "The SD NCA Key Source could not be found.", |
| 146 | "The NSP file is missing a Program-type NCA."}; | 146 | "The NSP file is missing a Program-type NCA.", |
| 147 | "The BKTR-type NCA has a bad BKTR header.", | ||
| 148 | "The BKTR Subsection entry is not located immediately after the Relocation entry.", | ||
| 149 | "The BKTR Subsection entry is not at the end of the media block.", | ||
| 150 | "The BKTR-type NCA has a bad Relocation block.", | ||
| 151 | "The BKTR-type NCA has a bad Subsection block.", | ||
| 152 | "The BKTR-type NCA has a bad Relocation bucket.", | ||
| 153 | "The BKTR-type NCA has a bad Subsection bucket.", | ||
| 154 | "The BKTR-type NCA is missing the base RomFS.", | ||
| 155 | }; | ||
| 147 | 156 | ||
| 148 | std::ostream& operator<<(std::ostream& os, ResultStatus status) { | 157 | std::ostream& operator<<(std::ostream& os, ResultStatus status) { |
| 149 | os << RESULT_MESSAGES.at(static_cast<size_t>(status)); | 158 | os << RESULT_MESSAGES.at(static_cast<size_t>(status)); |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index be66b2257..843c4bb91 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -107,6 +107,14 @@ enum class ResultStatus : u16 { | |||
| 107 | ErrorMissingSDSaveKeySource, | 107 | ErrorMissingSDSaveKeySource, |
| 108 | ErrorMissingSDNCAKeySource, | 108 | ErrorMissingSDNCAKeySource, |
| 109 | ErrorNSPMissingProgramNCA, | 109 | ErrorNSPMissingProgramNCA, |
| 110 | ErrorBadBKTRHeader, | ||
| 111 | ErrorBKTRSubsectionNotAfterRelocation, | ||
| 112 | ErrorBKTRSubsectionNotAtEnd, | ||
| 113 | ErrorBadRelocationBlock, | ||
| 114 | ErrorBadSubsectionBlock, | ||
| 115 | ErrorBadRelocationBuckets, | ||
| 116 | ErrorBadSubsectionBuckets, | ||
| 117 | ErrorMissingBKTRBaseRomFS, | ||
| 110 | }; | 118 | }; |
| 111 | 119 | ||
| 112 | std::ostream& operator<<(std::ostream& os, ResultStatus status); | 120 | std::ostream& operator<<(std::ostream& os, ResultStatus status); |
| @@ -197,13 +205,22 @@ public: | |||
| 197 | } | 205 | } |
| 198 | 206 | ||
| 199 | /** | 207 | /** |
| 200 | * Get the update RomFS of the application | 208 | * Get whether or not updates can be applied to the RomFS. |
| 201 | * Since the RomFS can be huge, we return a file reference instead of copying to a buffer | 209 | * By default, this is true, however for formats where it cannot be guaranteed that the RomFS is |
| 202 | * @param file The file containing the RomFS | 210 | * the base game it should be set to false. |
| 203 | * @return ResultStatus result of function | 211 | * @return bool whether or not updatable. |
| 204 | */ | 212 | */ |
| 205 | virtual ResultStatus ReadUpdateRomFS(FileSys::VirtualFile& file) { | 213 | virtual bool IsRomFSUpdatable() const { |
| 206 | return ResultStatus::ErrorNotImplemented; | 214 | return true; |
| 215 | } | ||
| 216 | |||
| 217 | /** | ||
| 218 | * Gets the difference between the start of the IVFC header and the start of level 6 (RomFS) | ||
| 219 | * data. Needed for bktr patching. | ||
| 220 | * @return IVFC offset for romfs. | ||
| 221 | */ | ||
| 222 | virtual u64 ReadRomFSIVFCOffset() const { | ||
| 223 | return 0; | ||
| 207 | } | 224 | } |
| 208 | 225 | ||
| 209 | /** | 226 | /** |
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index c036a8a1c..6aaffae59 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp | |||
| @@ -48,7 +48,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) { | |||
| 48 | if (exefs == nullptr) | 48 | if (exefs == nullptr) |
| 49 | return ResultStatus::ErrorNoExeFS; | 49 | return ResultStatus::ErrorNoExeFS; |
| 50 | 50 | ||
| 51 | directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs); | 51 | directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs, true); |
| 52 | 52 | ||
| 53 | const auto load_result = directory_loader->Load(process); | 53 | const auto load_result = directory_loader->Load(process); |
| 54 | if (load_result != ResultStatus::Success) | 54 | if (load_result != ResultStatus::Success) |
| @@ -71,6 +71,12 @@ ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { | |||
| 71 | return ResultStatus::Success; | 71 | return ResultStatus::Success; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | u64 AppLoader_NCA::ReadRomFSIVFCOffset() const { | ||
| 75 | if (nca == nullptr) | ||
| 76 | return 0; | ||
| 77 | return nca->GetBaseIVFCOffset(); | ||
| 78 | } | ||
| 79 | |||
| 74 | ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { | 80 | ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { |
| 75 | if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) | 81 | if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) |
| 76 | return ResultStatus::ErrorNotInitialized; | 82 | return ResultStatus::ErrorNotInitialized; |
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index 326f84857..10be197c4 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h | |||
| @@ -37,6 +37,7 @@ public: | |||
| 37 | ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; | 37 | ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; |
| 38 | 38 | ||
| 39 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | 39 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; |
| 40 | u64 ReadRomFSIVFCOffset() const override; | ||
| 40 | ResultStatus ReadProgramId(u64& out_program_id) override; | 41 | ResultStatus ReadProgramId(u64& out_program_id) override; |
| 41 | 42 | ||
| 42 | private: | 43 | private: |
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 77026b850..bb89a9da3 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp | |||
| @@ -232,4 +232,9 @@ ResultStatus AppLoader_NRO::ReadTitle(std::string& title) { | |||
| 232 | title = nacp->GetApplicationName(); | 232 | title = nacp->GetApplicationName(); |
| 233 | return ResultStatus::Success; | 233 | return ResultStatus::Success; |
| 234 | } | 234 | } |
| 235 | |||
| 236 | bool AppLoader_NRO::IsRomFSUpdatable() const { | ||
| 237 | return false; | ||
| 238 | } | ||
| 239 | |||
| 235 | } // namespace Loader | 240 | } // namespace Loader |
diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index bb01c9e25..96d2de305 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h | |||
| @@ -39,6 +39,7 @@ public: | |||
| 39 | ResultStatus ReadProgramId(u64& out_program_id) override; | 39 | ResultStatus ReadProgramId(u64& out_program_id) override; |
| 40 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | 40 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; |
| 41 | ResultStatus ReadTitle(std::string& title) override; | 41 | ResultStatus ReadTitle(std::string& title) override; |
| 42 | bool IsRomFSUpdatable() const override; | ||
| 42 | 43 | ||
| 43 | private: | 44 | private: |
| 44 | bool LoadNro(FileSys::VirtualFile file, VAddr load_base); | 45 | bool LoadNro(FileSys::VirtualFile file, VAddr load_base); |
diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 7c06239f2..291a9876d 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | #include "core/file_sys/content_archive.h" | 9 | #include "core/file_sys/content_archive.h" |
| 10 | #include "core/file_sys/control_metadata.h" | 10 | #include "core/file_sys/control_metadata.h" |
| 11 | #include "core/file_sys/nca_metadata.h" | 11 | #include "core/file_sys/nca_metadata.h" |
| 12 | #include "core/file_sys/patch_manager.h" | ||
| 13 | #include "core/file_sys/registered_cache.h" | ||
| 12 | #include "core/file_sys/romfs.h" | 14 | #include "core/file_sys/romfs.h" |
| 13 | #include "core/file_sys/submission_package.h" | 15 | #include "core/file_sys/submission_package.h" |
| 14 | #include "core/hle/kernel/process.h" | 16 | #include "core/hle/kernel/process.h" |
| @@ -28,24 +30,12 @@ AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file) | |||
| 28 | return; | 30 | return; |
| 29 | 31 | ||
| 30 | const auto control_nca = | 32 | const auto control_nca = |
| 31 | nsp->GetNCA(nsp->GetFirstTitleID(), FileSys::ContentRecordType::Control); | 33 | nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control); |
| 32 | if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) | 34 | if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) |
| 33 | return; | 35 | return; |
| 34 | 36 | ||
| 35 | const auto romfs = FileSys::ExtractRomFS(control_nca->GetRomFS()); | 37 | std::tie(nacp_file, icon_file) = |
| 36 | if (romfs == nullptr) | 38 | FileSys::PatchManager(nsp->GetProgramTitleID()).ParseControlNCA(control_nca); |
| 37 | return; | ||
| 38 | |||
| 39 | for (const auto& language : FileSys::LANGUAGE_NAMES) { | ||
| 40 | icon_file = romfs->GetFile("icon_" + std::string(language) + ".dat"); | ||
| 41 | if (icon_file != nullptr) | ||
| 42 | break; | ||
| 43 | } | ||
| 44 | |||
| 45 | const auto nacp_raw = romfs->GetFile("control.nacp"); | ||
| 46 | if (nacp_raw == nullptr) | ||
| 47 | return; | ||
| 48 | nacp_file = std::make_shared<FileSys::NACP>(nacp_raw); | ||
| 49 | } | 39 | } |
| 50 | 40 | ||
| 51 | AppLoader_NSP::~AppLoader_NSP() = default; | 41 | AppLoader_NSP::~AppLoader_NSP() = default; |
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 75b998faa..16509229f 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp | |||
| @@ -8,7 +8,9 @@ | |||
| 8 | #include "core/file_sys/card_image.h" | 8 | #include "core/file_sys/card_image.h" |
| 9 | #include "core/file_sys/content_archive.h" | 9 | #include "core/file_sys/content_archive.h" |
| 10 | #include "core/file_sys/control_metadata.h" | 10 | #include "core/file_sys/control_metadata.h" |
| 11 | #include "core/file_sys/patch_manager.h" | ||
| 11 | #include "core/file_sys/romfs.h" | 12 | #include "core/file_sys/romfs.h" |
| 13 | #include "core/file_sys/submission_package.h" | ||
| 12 | #include "core/hle/kernel/process.h" | 14 | #include "core/hle/kernel/process.h" |
| 13 | #include "core/loader/nca.h" | 15 | #include "core/loader/nca.h" |
| 14 | #include "core/loader/xci.h" | 16 | #include "core/loader/xci.h" |
| @@ -20,21 +22,13 @@ AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file) | |||
| 20 | nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { | 22 | nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { |
| 21 | if (xci->GetStatus() != ResultStatus::Success) | 23 | if (xci->GetStatus() != ResultStatus::Success) |
| 22 | return; | 24 | return; |
| 25 | |||
| 23 | const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); | 26 | const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); |
| 24 | if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) | 27 | if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) |
| 25 | return; | 28 | return; |
| 26 | const auto romfs = FileSys::ExtractRomFS(control_nca->GetRomFS()); | 29 | |
| 27 | if (romfs == nullptr) | 30 | std::tie(nacp_file, icon_file) = |
| 28 | return; | 31 | FileSys::PatchManager(xci->GetProgramTitleID()).ParseControlNCA(control_nca); |
| 29 | for (const auto& language : FileSys::LANGUAGE_NAMES) { | ||
| 30 | icon_file = romfs->GetFile("icon_" + std::string(language) + ".dat"); | ||
| 31 | if (icon_file != nullptr) | ||
| 32 | break; | ||
| 33 | } | ||
| 34 | const auto nacp_raw = romfs->GetFile("control.nacp"); | ||
| 35 | if (nacp_raw == nullptr) | ||
| 36 | return; | ||
| 37 | nacp_file = std::make_shared<FileSys::NACP>(nacp_raw); | ||
| 38 | } | 32 | } |
| 39 | 33 | ||
| 40 | AppLoader_XCI::~AppLoader_XCI() = default; | 34 | AppLoader_XCI::~AppLoader_XCI() = default; |