From 16188acb500cb238281dff28d944008ea56eb81b Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 19 Sep 2018 22:02:44 -0400 Subject: patch_manager: Add LayeredFS mods support --- src/core/file_sys/patch_manager.cpp | 43 ++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'src/core/file_sys/patch_manager.cpp') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index aebc69d52..74a0acf1a 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -11,6 +11,7 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs.h" +#include "core/file_sys/vfs_layered.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" @@ -31,8 +32,9 @@ std::string FormatTitleVersion(u32 version, TitleVersionFormat format) { return fmt::format("v{}.{}.{}", bytes[3], bytes[2], bytes[1]); } -constexpr std::array PATCH_TYPE_NAMES{ +constexpr std::array PATCH_TYPE_NAMES{ "Update", + "LayeredFS", }; std::string FormatPatchTypeName(PatchType type) { @@ -89,6 +91,41 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, } } + // LayeredFS + const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (type == ContentRecordType::Program && load_dir != nullptr && load_dir->GetSize() > 0) { + const auto extracted = ExtractRomFS(romfs); + + if (extracted != nullptr) { + auto patch_dirs = load_dir->GetSubdirectories(); + std::sort(patch_dirs.begin(), patch_dirs.end(), + [](const VirtualDir& l, const VirtualDir& r) { + return l->GetName() < r->GetName(); + }); + + std::vector layers; + layers.reserve(patch_dirs.size() + 1); + for (const auto& subdir : patch_dirs) { + const auto romfs_dir = subdir->GetSubdirectory("romfs"); + if (romfs_dir != nullptr) + layers.push_back(romfs_dir); + } + + layers.push_back(extracted); + + const auto layered = LayerDirectories(layers); + + if (layered != nullptr) { + const auto packed = CreateRomFS(layered); + + if (packed != nullptr) { + LOG_INFO(Loader, " RomFS: LayeredFS patches applied successfully"); + romfs = packed; + } + } + } + } + return romfs; } @@ -114,6 +151,10 @@ std::map PatchManager::GetPatchVersionNames() const { } } + const auto lfs_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (lfs_dir != nullptr && lfs_dir->GetSize() > 0) + out[PatchType::LayeredFS] = ""; + return out; } -- cgit v1.2.3 From b3c2ec362bbbdd89da9c0aa84b425717f5e3d351 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 21:50:16 -0400 Subject: fsmitm: Cleanup and modernize fsmitm port --- src/core/file_sys/patch_manager.cpp | 66 ++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'src/core/file_sys/patch_manager.cpp') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 74a0acf1a..af3f9a78f 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -68,33 +68,10 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { return exefs; } -VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, - ContentRecordType type) const { - LOG_INFO(Loader, "Patching RomFS for title_id={:016X}, type={:02X}", title_id, - static_cast(type)); - - if (romfs == nullptr) - return romfs; - - const auto installed = Service::FileSystem::GetUnionContents(); - - // Game Updates - const auto update_tid = GetUpdateTitleID(title_id); - const auto update = installed->GetEntryRaw(update_tid, type); - if (update != 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 ({}) applied successfully", - FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0))); - romfs = new_nca->GetRomFS(); - } - } - - // LayeredFS +static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) { const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); if (type == ContentRecordType::Program && load_dir != nullptr && load_dir->GetSize() > 0) { - const auto extracted = ExtractRomFS(romfs); + auto extracted = ExtractRomFS(romfs); if (extracted != nullptr) { auto patch_dirs = load_dir->GetSubdirectories(); @@ -106,25 +83,52 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, std::vector layers; layers.reserve(patch_dirs.size() + 1); for (const auto& subdir : patch_dirs) { - const auto romfs_dir = subdir->GetSubdirectory("romfs"); + auto romfs_dir = subdir->GetSubdirectory("romfs"); if (romfs_dir != nullptr) - layers.push_back(romfs_dir); + layers.push_back(std::move(romfs_dir)); } - layers.push_back(extracted); + layers.push_back(std::move(extracted)); const auto layered = LayerDirectories(layers); if (layered != nullptr) { - const auto packed = CreateRomFS(layered); + auto packed = CreateRomFS(layered); if (packed != nullptr) { LOG_INFO(Loader, " RomFS: LayeredFS patches applied successfully"); - romfs = packed; + romfs = std::move(packed); } } } } +} + +VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, + ContentRecordType type) const { + LOG_INFO(Loader, "Patching RomFS for title_id={:016X}, type={:02X}", title_id, + static_cast(type)); + + if (romfs == nullptr) + return romfs; + + const auto installed = Service::FileSystem::GetUnionContents(); + + // Game Updates + const auto update_tid = GetUpdateTitleID(title_id); + const auto update = installed->GetEntryRaw(update_tid, type); + if (update != 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 ({}) applied successfully", + FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0))); + romfs = new_nca->GetRomFS(); + } + } + + // LayeredFS + ApplyLayeredFS(romfs, title_id, type); return romfs; } @@ -153,7 +157,7 @@ std::map PatchManager::GetPatchVersionNames() const { const auto lfs_dir = Service::FileSystem::GetModificationLoadRoot(title_id); if (lfs_dir != nullptr && lfs_dir->GetSize() > 0) - out[PatchType::LayeredFS] = ""; + out.insert_or_assign(PatchType::LayeredFS, ""); return out; } -- cgit v1.2.3