summaryrefslogtreecommitdiff
path: root/src/core/file_sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/patch_manager.cpp75
-rw-r--r--src/core/file_sys/patch_manager.h13
2 files changed, 66 insertions, 22 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};