From d79d4fd764c194e6c8c4d57ed0fd308e401c2f6e Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 25 Sep 2018 09:19:42 -0400 Subject: patch_manager: Add support for packed updates Will prefer any installed update over the packed version. --- src/core/file_sys/patch_manager.cpp | 15 ++++++++++++--- src/core/file_sys/patch_manager.h | 3 ++- src/core/file_sys/romfs_factory.cpp | 4 +++- src/core/file_sys/romfs_factory.h | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 539698f6e..b43880e92 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -184,8 +184,8 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t romfs = std::move(packed); } -VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, - ContentRecordType type) const { +VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type, + VirtualFile update_raw) const { LOG_INFO(Loader, "Patching RomFS for title_id={:016X}, type={:02X}", title_id, static_cast(type)); @@ -205,6 +205,13 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0))); romfs = new_nca->GetRomFS(); } + } else if (update_raw != nullptr) { + const auto new_nca = std::make_shared(update, romfs, ivfc_offset); + if (new_nca->GetStatus() == Loader::ResultStatus::Success && + new_nca->GetRomFS() != nullptr) { + LOG_INFO(Loader, " RomFS: Update (XCI) applied successfully"); + romfs = new_nca->GetRomFS(); + } } // LayeredFS @@ -224,7 +231,7 @@ static bool IsDirValidAndNonEmpty(const VirtualDir& dir) { return dir != nullptr && (!dir->GetFiles().empty() || !dir->GetSubdirectories().empty()); } -std::map> PatchManager::GetPatchVersionNames() const { +std::map PatchManager::GetPatchVersionNames(VirtualFile update_raw) const { std::map> out; const auto installed = Service::FileSystem::GetUnionContents(); @@ -245,6 +252,8 @@ std::map> PatchManager::GetPatchVersionNam "Update", FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements)); } + } else if (update_raw != nullptr) { + out[PatchType::Update] = "XCI"; } } diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index 6a864ec43..e87ce54e5 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -46,7 +46,8 @@ public: // - Game Updates // - LayeredFS VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, - ContentRecordType type = ContentRecordType::Program) const; + ContentRecordType type = ContentRecordType::Program, + VirtualFile update_raw = nullptr) const; // Returns a vector of pairs between patch names and patch versions. // i.e. Update 3.2.2 will return {"Update", "3.2.2"} diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index 4994c2532..a0ee16895 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -24,6 +24,7 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) { LOG_ERROR(Service_FS, "Unable to read RomFS!"); } + app_loader.ReadUpdateRaw(update_raw); updatable = app_loader.IsRomFSUpdatable(); ivfc_offset = app_loader.ReadRomFSIVFCOffset(); } @@ -35,7 +36,8 @@ ResultVal RomFSFactory::OpenCurrentProcess() { return MakeResult(file); const PatchManager patch_manager(Core::CurrentProcess()->GetTitleID()); - return MakeResult(patch_manager.PatchRomFS(file, ivfc_offset)); + return MakeResult( + patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw)); } ResultVal RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) { diff --git a/src/core/file_sys/romfs_factory.h b/src/core/file_sys/romfs_factory.h index 2cace8180..1cd4cedf1 100644 --- a/src/core/file_sys/romfs_factory.h +++ b/src/core/file_sys/romfs_factory.h @@ -37,6 +37,7 @@ public: private: VirtualFile file; + VirtualFile update_raw; bool updatable; u64 ivfc_offset; }; -- cgit v1.2.3 From 5acaeb04c4f4ebdffda37717347f6a0c82a71aa4 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 25 Sep 2018 14:07:13 -0400 Subject: patch_manager: Add support for NSP packed updates Reads as Update (NSP) in add-ons --- src/core/file_sys/patch_manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index b43880e92..3fc44fb5c 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -209,7 +209,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content const auto new_nca = std::make_shared(update, romfs, ivfc_offset); if (new_nca->GetStatus() == Loader::ResultStatus::Success && new_nca->GetRomFS() != nullptr) { - LOG_INFO(Loader, " RomFS: Update (XCI) applied successfully"); + LOG_INFO(Loader, " RomFS: Update (PACKED) applied successfully"); romfs = new_nca->GetRomFS(); } } @@ -253,7 +253,7 @@ std::map PatchManager::GetPatchVersionNames(VirtualFile FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements)); } } else if (update_raw != nullptr) { - out[PatchType::Update] = "XCI"; + out[PatchType::Update] = "PACKED"; } } -- cgit v1.2.3 From 38c2ac95af814e21e65e2785b276c4f64bfead71 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 5 Oct 2018 08:53:45 -0400 Subject: romfs_factory: Extract packed update setter to new function --- src/core/file_sys/patch_manager.cpp | 7 ++++--- src/core/file_sys/patch_manager.h | 3 ++- src/core/file_sys/romfs_factory.cpp | 5 ++++- src/core/file_sys/romfs_factory.h | 1 + src/core/file_sys/submission_package.cpp | 5 ++++- 5 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 3fc44fb5c..1ac00ebb0 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -206,7 +206,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content romfs = new_nca->GetRomFS(); } } else if (update_raw != nullptr) { - const auto new_nca = std::make_shared(update, romfs, ivfc_offset); + const auto new_nca = std::make_shared(update_raw, romfs, ivfc_offset); if (new_nca->GetStatus() == Loader::ResultStatus::Success && new_nca->GetRomFS() != nullptr) { LOG_INFO(Loader, " RomFS: Update (PACKED) applied successfully"); @@ -231,7 +231,8 @@ static bool IsDirValidAndNonEmpty(const VirtualDir& dir) { return dir != nullptr && (!dir->GetFiles().empty() || !dir->GetSubdirectories().empty()); } -std::map PatchManager::GetPatchVersionNames(VirtualFile update_raw) const { +std::map> PatchManager::GetPatchVersionNames( + VirtualFile update_raw) const { std::map> out; const auto installed = Service::FileSystem::GetUnionContents(); @@ -253,7 +254,7 @@ std::map PatchManager::GetPatchVersionNames(VirtualFile FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements)); } } else if (update_raw != nullptr) { - out[PatchType::Update] = "PACKED"; + out.insert_or_assign("Update", "PACKED"); } } diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index e87ce54e5..2ae9322a1 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -51,7 +51,8 @@ public: // Returns a vector of pairs between patch names and patch versions. // i.e. Update 3.2.2 will return {"Update", "3.2.2"} - std::map> GetPatchVersionNames() const; + std::map> GetPatchVersionNames( + VirtualFile update_raw = nullptr) 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. diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index a0ee16895..0b645b106 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -24,13 +24,16 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) { LOG_ERROR(Service_FS, "Unable to read RomFS!"); } - app_loader.ReadUpdateRaw(update_raw); updatable = app_loader.IsRomFSUpdatable(); ivfc_offset = app_loader.ReadRomFSIVFCOffset(); } RomFSFactory::~RomFSFactory() = default; +void RomFSFactory::SetPackedUpdate(VirtualFile update_raw) { + this->update_raw = std::move(update_raw); +} + ResultVal RomFSFactory::OpenCurrentProcess() { if (!updatable) return MakeResult(file); diff --git a/src/core/file_sys/romfs_factory.h b/src/core/file_sys/romfs_factory.h index 1cd4cedf1..7724c0b23 100644 --- a/src/core/file_sys/romfs_factory.h +++ b/src/core/file_sys/romfs_factory.h @@ -32,6 +32,7 @@ public: explicit RomFSFactory(Loader::AppLoader& app_loader); ~RomFSFactory(); + void SetPackedUpdate(VirtualFile update_raw); ResultVal OpenCurrentProcess(); ResultVal Open(u64 title_id, StorageId storage, ContentRecordType type); diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index 09bf077cd..ab5dc900c 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -259,8 +259,11 @@ void NSP::ReadNCAs(const std::vector& files) { auto next_nca = std::make_shared(next_file); if (next_nca->GetType() == NCAContentType::Program) program_status[cnmt.GetTitleID()] = next_nca->GetStatus(); - if (next_nca->GetStatus() == Loader::ResultStatus::Success) + if (next_nca->GetStatus() == Loader::ResultStatus::Success || + (next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS && + (cnmt.GetTitleID() & 0x800) != 0)) { ncas_title[rec.type] = std::move(next_nca); + } } break; -- cgit v1.2.3