summaryrefslogtreecommitdiffstats
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 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/hle/service/filesystem/filesystem.h"
@@ -87,29 +88,63 @@ std::map<PatchType, std::string> PatchManager::GetPatchVersionNames() const {
const auto installed = Service::FileSystem::GetUnionContents();
const auto update_tid = GetUpdateTitleID(title_id);
- const auto update_control = installed->GetEntry(title_id, ContentRecordType::Control);
- if (update_control != nullptr) {
- do {
- const auto romfs =
- PatchRomFS(update_control->GetRomFS(), update_control->GetBaseIVFCOffset(),
- FileSys::ContentRecordType::Control);
- if (romfs == nullptr)
- break;
-
- const auto control_dir = FileSys::ExtractRomFS(romfs);
- if (control_dir == nullptr)
- break;
-
- const auto nacp_file = control_dir->GetFile("control.nacp");
- if (nacp_file == nullptr)
- break;
-
- FileSys::NACP nacp(nacp_file);
- out[PatchType::Update] = nacp.GetVersionString();
- } while (false);
+ PatchManager update{update_tid};
+ auto [nacp, discard_icon_file] = update.GetControlMetadata();
+
+ if (nacp != nullptr) {
+ out[PatchType::Update] = nacp->GetVersionString();
+ } else {
+ if (installed->HasEntry(update_tid, ContentRecordType::Program)) {
+ const auto meta_ver = installed->GetEntryVersion(update_tid);
+ if (meta_ver == boost::none || meta_ver.get() == 0) {
+ out[PatchType::Update] = "";
+ } else {
+ out[PatchType::Update] =
+ FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements);
+ }
+ }
}
return out;
}
+std::pair<std::shared_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const {
+ const auto& installed{Service::FileSystem::GetUnionContents()};
+
+ const auto base_control_nca = installed->GetEntry(title_id, ContentRecordType::Control);
+ if (base_control_nca == nullptr)
+ return {};
+
+ return ParseControlNCA(base_control_nca);
+}
+
+std::pair<std::shared_ptr<NACP>, VirtualFile> PatchManager::ParseControlNCA(
+ const std::shared_ptr<NCA>& nca) const {
+ const auto base_romfs = nca->GetRomFS();
+ if (base_romfs == nullptr)
+ return {};
+
+ const auto romfs = PatchRomFS(base_romfs, nca->GetBaseIVFCOffset(), ContentRecordType::Control);
+ if (romfs == nullptr)
+ return {};
+
+ const auto extracted = ExtractRomFS(romfs);
+ if (extracted == nullptr)
+ return {};
+
+ auto nacp_file = extracted->GetFile("control.nacp");
+ if (nacp_file == nullptr)
+ nacp_file = extracted->GetFile("Control.nacp");
+
+ const auto nacp = nacp_file == nullptr ? nullptr : std::make_shared<NACP>(nacp_file);
+
+ VirtualFile icon_file;
+ for (const auto& language : FileSys::LANGUAGE_NAMES) {
+ icon_file = extracted->GetFile("icon_" + std::string(language) + ".dat");
+ if (icon_file != nullptr)
+ break;
+ }
+
+ return {nacp, icon_file};
+}
} // 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 @@
#include <map>
#include <string>
#include "common/common_types.h"
+#include "core/file_sys/nca_metadata.h"
+#include "core/file_sys/romfs_factory.h"
#include "core/file_sys/vfs.h"
-#include "nca_metadata.h"
-#include "romfs_factory.h"
namespace FileSys {
class NCA;
+class NACP;
enum class TitleVersionFormat : u8 {
ThreeElements, ///< vX.Y.Z
@@ -47,6 +48,14 @@ public:
// i.e. Update v80 will return {Update, 80}
std::map<PatchType, std::string> GetPatchVersionNames() const;
+ // Given title_id of the program, attempts to get the control data of the update and parse it,
+ // falling back to the base control data.
+ std::pair<std::shared_ptr<NACP>, VirtualFile> GetControlMetadata() const;
+
+ // Version of GetControlMetadata that takes an arbitrary NCA
+ std::pair<std::shared_ptr<NACP>, VirtualFile> ParseControlNCA(
+ const std::shared_ptr<NCA>& nca) const;
+
private:
u64 title_id;
};