summaryrefslogtreecommitdiff
path: root/src/core/file_sys
diff options
context:
space:
mode:
authorGravatar bunnei2018-11-23 23:31:48 -0500
committerGravatar GitHub2018-11-23 23:31:48 -0500
commit67ff974387abed516bdadf780561a51562e77525 (patch)
treede6a480bda17727f5ba93f6740a00736c0629af2 /src/core/file_sys
parentMerge pull request #1769 from ReinUsesLisp/cc (diff)
parentpatch_manager: Show LayeredExeFS patch in add-ons column (diff)
downloadyuzu-67ff974387abed516bdadf780561a51562e77525.tar.gz
yuzu-67ff974387abed516bdadf780561a51562e77525.tar.xz
yuzu-67ff974387abed516bdadf780561a51562e77525.zip
Merge pull request #1747 from DarkLordZach/exefs-lfs
patch_manager: Add support for applying LayeredFS patches to ExeFS
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/patch_manager.cpp49
1 files changed, 47 insertions, 2 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index 8d062eb3e..e8df08724 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -26,6 +26,11 @@ namespace FileSys {
26constexpr u64 SINGLE_BYTE_MODULUS = 0x100; 26constexpr u64 SINGLE_BYTE_MODULUS = 0x100;
27constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000; 27constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
28 28
29constexpr std::array<const char*, 14> EXEFS_FILE_NAMES{
30 "main", "main.npdm", "rtld", "sdk", "subsdk0", "subsdk1", "subsdk2",
31 "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", "subsdk8", "subsdk9",
32};
33
29struct NSOBuildHeader { 34struct NSOBuildHeader {
30 u32_le magic; 35 u32_le magic;
31 INSERT_PADDING_BYTES(0x3C); 36 INSERT_PADDING_BYTES(0x3C);
@@ -57,6 +62,15 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
57 if (exefs == nullptr) 62 if (exefs == nullptr)
58 return exefs; 63 return exefs;
59 64
65 if (Settings::values.dump_exefs) {
66 LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id);
67 const auto dump_dir = Service::FileSystem::GetModificationDumpRoot(title_id);
68 if (dump_dir != nullptr) {
69 const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs");
70 VfsRawCopyD(exefs, exefs_dir);
71 }
72 }
73
60 const auto installed = Service::FileSystem::GetUnionContents(); 74 const auto installed = Service::FileSystem::GetUnionContents();
61 75
62 // Game Updates 76 // Game Updates
@@ -70,6 +84,30 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
70 exefs = update->GetExeFS(); 84 exefs = update->GetExeFS();
71 } 85 }
72 86
87 // LayeredExeFS
88 const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id);
89 if (load_dir != nullptr && load_dir->GetSize() > 0) {
90 auto patch_dirs = load_dir->GetSubdirectories();
91 std::sort(
92 patch_dirs.begin(), patch_dirs.end(),
93 [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); });
94
95 std::vector<VirtualDir> layers;
96 layers.reserve(patch_dirs.size() + 1);
97 for (const auto& subdir : patch_dirs) {
98 auto exefs_dir = subdir->GetSubdirectory("exefs");
99 if (exefs_dir != nullptr)
100 layers.push_back(std::move(exefs_dir));
101 }
102 layers.push_back(exefs);
103
104 auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers));
105 if (layered != nullptr) {
106 LOG_INFO(Loader, " ExeFS: LayeredExeFS patches applied successfully");
107 exefs = std::move(layered);
108 }
109 }
110
73 return exefs; 111 return exefs;
74} 112}
75 113
@@ -314,18 +352,25 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
314 if (IsDirValidAndNonEmpty(exefs_dir)) { 352 if (IsDirValidAndNonEmpty(exefs_dir)) {
315 bool ips = false; 353 bool ips = false;
316 bool ipswitch = false; 354 bool ipswitch = false;
355 bool layeredfs = false;
317 356
318 for (const auto& file : exefs_dir->GetFiles()) { 357 for (const auto& file : exefs_dir->GetFiles()) {
319 if (file->GetExtension() == "ips") 358 if (file->GetExtension() == "ips") {
320 ips = true; 359 ips = true;
321 else if (file->GetExtension() == "pchtxt") 360 } else if (file->GetExtension() == "pchtxt") {
322 ipswitch = true; 361 ipswitch = true;
362 } else if (std::find(EXEFS_FILE_NAMES.begin(), EXEFS_FILE_NAMES.end(),
363 file->GetName()) != EXEFS_FILE_NAMES.end()) {
364 layeredfs = true;
365 }
323 } 366 }
324 367
325 if (ips) 368 if (ips)
326 AppendCommaIfNotEmpty(types, "IPS"); 369 AppendCommaIfNotEmpty(types, "IPS");
327 if (ipswitch) 370 if (ipswitch)
328 AppendCommaIfNotEmpty(types, "IPSwitch"); 371 AppendCommaIfNotEmpty(types, "IPSwitch");
372 if (layeredfs)
373 AppendCommaIfNotEmpty(types, "LayeredExeFS");
329 } 374 }
330 if (IsDirValidAndNonEmpty(mod->GetSubdirectory("romfs"))) 375 if (IsDirValidAndNonEmpty(mod->GetSubdirectory("romfs")))
331 AppendCommaIfNotEmpty(types, "LayeredFS"); 376 AppendCommaIfNotEmpty(types, "LayeredFS");