From 17d8e25cbfd0c8937c8791bc1941af85f9541666 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 20 Nov 2018 17:49:09 -0500 Subject: settings: Add option to dump ExeFS of games upon launch When enabled, all exefs(es) will be copied to yuzu/dump//exefs. --- src/core/file_sys/patch_manager.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (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 8d062eb3e..f56b1c773 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -57,6 +57,15 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { if (exefs == nullptr) return exefs; + if (Settings::values.dump_exefs) { + LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id); + const auto dump_dir = Service::FileSystem::GetModificationDumpRoot(title_id); + if (dump_dir != nullptr) { + const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs"); + VfsRawCopyD(exefs, exefs_dir); + } + } + const auto installed = Service::FileSystem::GetUnionContents(); // Game Updates -- cgit v1.2.3 From da6d4cde567695d22fefc152d2d913f54e5ece68 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 20 Nov 2018 17:51:00 -0500 Subject: patch_manager: Apply LayeredExeFS patches This will scan the /exefs dir for all files and then layer those on top of the game's exefs and use this as the new exefs. This allows for overriding of the compressed NSOs or adding new files. This does use the same dir as IPS/IPSwitch patch, but since the loader will not look for those they are ignored. --- src/core/file_sys/patch_manager.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (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 f56b1c773..ccc4f3061 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -79,6 +79,31 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { exefs = update->GetExeFS(); } + // LayeredExeFS + const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (load_dir != nullptr && load_dir->GetSize() > 0) { + + 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) { + auto exefs_dir = subdir->GetSubdirectory("exefs"); + if (exefs_dir != nullptr) + layers.push_back(std::move(exefs_dir)); + } + layers.push_back(exefs); + + auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers)); + if (layered != nullptr) { + LOG_INFO(Loader, " ExeFS: LayeredExeFS patches applied successfully"); + exefs = std::move(layered); + } + } + return exefs; } -- cgit v1.2.3 From 54e74b3572d3f61fdbaf4f2ddb8b54e2c06a5ab8 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 20 Nov 2018 19:22:26 -0500 Subject: patch_manager: Show LayeredExeFS patch in add-ons column The decision was made to name them LayeredExeFS instead of just LayeredFS to differentiate from normal RomFS-based mods. The name may be long/unweildy, but conveys the meaning well. --- src/core/file_sys/patch_manager.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 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 ccc4f3061..e8df08724 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -26,6 +26,11 @@ namespace FileSys { constexpr u64 SINGLE_BYTE_MODULUS = 0x100; constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000; +constexpr std::array EXEFS_FILE_NAMES{ + "main", "main.npdm", "rtld", "sdk", "subsdk0", "subsdk1", "subsdk2", + "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", "subsdk8", "subsdk9", +}; + struct NSOBuildHeader { u32_le magic; INSERT_PADDING_BYTES(0x3C); @@ -82,7 +87,6 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { // LayeredExeFS const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); if (load_dir != nullptr && load_dir->GetSize() > 0) { - auto patch_dirs = load_dir->GetSubdirectories(); std::sort( patch_dirs.begin(), patch_dirs.end(), @@ -348,18 +352,25 @@ std::map> PatchManager::GetPatchVersionNam if (IsDirValidAndNonEmpty(exefs_dir)) { bool ips = false; bool ipswitch = false; + bool layeredfs = false; for (const auto& file : exefs_dir->GetFiles()) { - if (file->GetExtension() == "ips") + if (file->GetExtension() == "ips") { ips = true; - else if (file->GetExtension() == "pchtxt") + } else if (file->GetExtension() == "pchtxt") { ipswitch = true; + } else if (std::find(EXEFS_FILE_NAMES.begin(), EXEFS_FILE_NAMES.end(), + file->GetName()) != EXEFS_FILE_NAMES.end()) { + layeredfs = true; + } } if (ips) AppendCommaIfNotEmpty(types, "IPS"); if (ipswitch) AppendCommaIfNotEmpty(types, "IPSwitch"); + if (layeredfs) + AppendCommaIfNotEmpty(types, "LayeredExeFS"); } if (IsDirValidAndNonEmpty(mod->GetSubdirectory("romfs"))) AppendCommaIfNotEmpty(types, "LayeredFS"); -- cgit v1.2.3