summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-09-03 18:57:52 -0400
committerGravatar Zach Hilman2018-09-04 16:25:10 -0400
commit23a16c1720ee522f6ac7d1f426a2d4a918ce41c9 (patch)
tree43a69cb7046a768760e5ae20eddfe3b53d3ca7f8 /src/core
parentnsp: Fix error masking issue with XCI files (diff)
downloadyuzu-23a16c1720ee522f6ac7d1f426a2d4a918ce41c9.tar.gz
yuzu-23a16c1720ee522f6ac7d1f426a2d4a918ce41c9.tar.xz
yuzu-23a16c1720ee522f6ac7d1f426a2d4a918ce41c9.zip
patch_manager: Centralize Control-type NCA parsing
Diffstat (limited to 'src/core')
-rw-r--r--src/core/file_sys/patch_manager.cpp75
-rw-r--r--src/core/file_sys/patch_manager.h13
-rw-r--r--src/core/loader/nsp.cpp20
-rw-r--r--src/core/loader/xci.cpp21
4 files changed, 74 insertions, 55 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index b6e25f7eb..fa2fbe5e1 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/file_sys/control_metadata.h"
5#include "core/file_sys/patch_manager.h" 6#include "core/file_sys/patch_manager.h"
6#include "core/file_sys/registered_cache.h" 7#include "core/file_sys/registered_cache.h"
7#include "core/hle/service/filesystem/filesystem.h" 8#include "core/hle/service/filesystem/filesystem.h"
@@ -87,29 +88,63 @@ std::map<PatchType, std::string> PatchManager::GetPatchVersionNames() const {
87 const auto installed = Service::FileSystem::GetUnionContents(); 88 const auto installed = Service::FileSystem::GetUnionContents();
88 89
89 const auto update_tid = GetUpdateTitleID(title_id); 90 const auto update_tid = GetUpdateTitleID(title_id);
90 const auto update_control = installed->GetEntry(title_id, ContentRecordType::Control); 91 PatchManager update{update_tid};
91 if (update_control != nullptr) { 92 auto [nacp, discard_icon_file] = update.GetControlMetadata();
92 do { 93
93 const auto romfs = 94 if (nacp != nullptr) {
94 PatchRomFS(update_control->GetRomFS(), update_control->GetBaseIVFCOffset(), 95 out[PatchType::Update] = nacp->GetVersionString();
95 FileSys::ContentRecordType::Control); 96 } else {
96 if (romfs == nullptr) 97 if (installed->HasEntry(update_tid, ContentRecordType::Program)) {
97 break; 98 const auto meta_ver = installed->GetEntryVersion(update_tid);
98 99 if (meta_ver == boost::none || meta_ver.get() == 0) {
99 const auto control_dir = FileSys::ExtractRomFS(romfs); 100 out[PatchType::Update] = "";
100 if (control_dir == nullptr) 101 } else {
101 break; 102 out[PatchType::Update] =
102 103 FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements);
103 const auto nacp_file = control_dir->GetFile("control.nacp"); 104 }
104 if (nacp_file == nullptr) 105 }
105 break;
106
107 FileSys::NACP nacp(nacp_file);
108 out[PatchType::Update] = nacp.GetVersionString();
109 } while (false);
110 } 106 }
111 107
112 return out; 108 return out;
113} 109}
114 110
111std::pair<std::shared_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const {
112 const auto& installed{Service::FileSystem::GetUnionContents()};
113
114 const auto base_control_nca = installed->GetEntry(title_id, ContentRecordType::Control);
115 if (base_control_nca == nullptr)
116 return {};
117
118 return ParseControlNCA(base_control_nca);
119}
120
121std::pair<std::shared_ptr<NACP>, VirtualFile> PatchManager::ParseControlNCA(
122 const std::shared_ptr<NCA>& nca) const {
123 const auto base_romfs = nca->GetRomFS();
124 if (base_romfs == nullptr)
125 return {};
126
127 const auto romfs = PatchRomFS(base_romfs, nca->GetBaseIVFCOffset(), ContentRecordType::Control);
128 if (romfs == nullptr)
129 return {};
130
131 const auto extracted = ExtractRomFS(romfs);
132 if (extracted == nullptr)
133 return {};
134
135 auto nacp_file = extracted->GetFile("control.nacp");
136 if (nacp_file == nullptr)
137 nacp_file = extracted->GetFile("Control.nacp");
138
139 const auto nacp = nacp_file == nullptr ? nullptr : std::make_shared<NACP>(nacp_file);
140
141 VirtualFile icon_file;
142 for (const auto& language : FileSys::LANGUAGE_NAMES) {
143 icon_file = extracted->GetFile("icon_" + std::string(language) + ".dat");
144 if (icon_file != nullptr)
145 break;
146 }
147
148 return {nacp, icon_file};
149}
115} // namespace FileSys 150} // namespace FileSys
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h
index b6bf86222..c2626bc6c 100644
--- a/src/core/file_sys/patch_manager.h
+++ b/src/core/file_sys/patch_manager.h
@@ -7,13 +7,14 @@
7#include <map> 7#include <map>
8#include <string> 8#include <string>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/file_sys/nca_metadata.h"
11#include "core/file_sys/romfs_factory.h"
10#include "core/file_sys/vfs.h" 12#include "core/file_sys/vfs.h"
11#include "nca_metadata.h"
12#include "romfs_factory.h"
13 13
14namespace FileSys { 14namespace FileSys {
15 15
16class NCA; 16class NCA;
17class NACP;
17 18
18enum class TitleVersionFormat : u8 { 19enum class TitleVersionFormat : u8 {
19 ThreeElements, ///< vX.Y.Z 20 ThreeElements, ///< vX.Y.Z
@@ -47,6 +48,14 @@ public:
47 // i.e. Update v80 will return {Update, 80} 48 // i.e. Update v80 will return {Update, 80}
48 std::map<PatchType, std::string> GetPatchVersionNames() const; 49 std::map<PatchType, std::string> GetPatchVersionNames() const;
49 50
51 // Given title_id of the program, attempts to get the control data of the update and parse it,
52 // falling back to the base control data.
53 std::pair<std::shared_ptr<NACP>, VirtualFile> GetControlMetadata() const;
54
55 // Version of GetControlMetadata that takes an arbitrary NCA
56 std::pair<std::shared_ptr<NACP>, VirtualFile> ParseControlNCA(
57 const std::shared_ptr<NCA>& nca) const;
58
50private: 59private:
51 u64 title_id; 60 u64 title_id;
52}; 61};
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
51AppLoader_NSP::~AppLoader_NSP() = default; 41AppLoader_NSP::~AppLoader_NSP() = default;
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
index b01d51abb..16509229f 100644
--- a/src/core/loader/xci.cpp
+++ b/src/core/loader/xci.cpp
@@ -10,6 +10,7 @@
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/patch_manager.h"
12#include "core/file_sys/romfs.h" 12#include "core/file_sys/romfs.h"
13#include "core/file_sys/submission_package.h"
13#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
14#include "core/loader/nca.h" 15#include "core/loader/nca.h"
15#include "core/loader/xci.h" 16#include "core/loader/xci.h"
@@ -23,27 +24,11 @@ AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
23 return; 24 return;
24 25
25 const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); 26 const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
26
27 if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) 27 if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success)
28 return; 28 return;
29 29
30 auto romfs_raw = control_nca->GetRomFS(); 30 std::tie(nacp_file, icon_file) =
31 FileSys::PatchManager patch{xci->GetNCAByType(FileSys::NCAContentType::Program)->GetTitleId()}; 31 FileSys::PatchManager(xci->GetProgramTitleID()).ParseControlNCA(control_nca);
32 romfs_raw = patch.PatchRomFS(romfs_raw, control_nca->GetBaseIVFCOffset(),
33 FileSys::ContentRecordType::Control);
34
35 const auto romfs = FileSys::ExtractRomFS(romfs_raw);
36 if (romfs == nullptr)
37 return;
38 for (const auto& language : FileSys::LANGUAGE_NAMES) {
39 icon_file = romfs->GetFile("icon_" + std::string(language) + ".dat");
40 if (icon_file != nullptr)
41 break;
42 }
43 const auto nacp_raw = romfs->GetFile("control.nacp");
44 if (nacp_raw == nullptr)
45 return;
46 nacp_file = std::make_shared<FileSys::NACP>(nacp_raw);
47} 32}
48 33
49AppLoader_XCI::~AppLoader_XCI() = default; 34AppLoader_XCI::~AppLoader_XCI() = default;