Преглед изворни кода

Merge pull request #1423 from DarkLordZach/romfs-file-exts

 fsmitm_romfsbuild: Add support for stubbing and IPS patches in LFS
bunnei пре 7 година
родитељ
комит
561d79e034

+ 22 - 4
src/core/file_sys/fsmitm_romfsbuild.cpp

@@ -26,6 +26,7 @@
 #include "common/alignment.h"
 #include "common/alignment.h"
 #include "common/assert.h"
 #include "common/assert.h"
 #include "core/file_sys/fsmitm_romfsbuild.h"
 #include "core/file_sys/fsmitm_romfsbuild.h"
+#include "core/file_sys/ips_layer.h"
 #include "core/file_sys/vfs.h"
 #include "core/file_sys/vfs.h"
 #include "core/file_sys/vfs_vector.h"
 #include "core/file_sys/vfs_vector.h"
 
 
@@ -123,7 +124,7 @@ static u64 romfs_get_hash_table_count(u64 num_entries) {
     return count;
     return count;
 }
 }
 
 
-void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs,
+void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs, VirtualDir ext,
                                        std::shared_ptr<RomFSBuildDirectoryContext> parent) {
                                        std::shared_ptr<RomFSBuildDirectoryContext> parent) {
     std::vector<std::shared_ptr<RomFSBuildDirectoryContext>> child_dirs;
     std::vector<std::shared_ptr<RomFSBuildDirectoryContext>> child_dirs;
 
 
@@ -144,6 +145,9 @@ void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs,
             child->path_len = child->cur_path_ofs + static_cast<u32>(kv.first.size());
             child->path_len = child->cur_path_ofs + static_cast<u32>(kv.first.size());
             child->path = parent->path + "/" + kv.first;
             child->path = parent->path + "/" + kv.first;
 
 
+            if (ext != nullptr && ext->GetFileRelative(child->path + ".stub") != nullptr)
+                continue;
+
             // Sanity check on path_len
             // Sanity check on path_len
             ASSERT(child->path_len < FS_MAX_PATH);
             ASSERT(child->path_len < FS_MAX_PATH);
 
 
@@ -157,11 +161,24 @@ void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs,
             child->path_len = child->cur_path_ofs + static_cast<u32>(kv.first.size());
             child->path_len = child->cur_path_ofs + static_cast<u32>(kv.first.size());
             child->path = parent->path + "/" + kv.first;
             child->path = parent->path + "/" + kv.first;
 
 
+            if (ext != nullptr && ext->GetFileRelative(child->path + ".stub") != nullptr)
+                continue;
+
             // Sanity check on path_len
             // Sanity check on path_len
             ASSERT(child->path_len < FS_MAX_PATH);
             ASSERT(child->path_len < FS_MAX_PATH);
 
 
             child->source = root_romfs->GetFileRelative(child->path);
             child->source = root_romfs->GetFileRelative(child->path);
 
 
+            if (ext != nullptr) {
+                const auto ips = ext->GetFileRelative(child->path + ".ips");
+
+                if (ips != nullptr) {
+                    auto patched = PatchIPS(child->source, ips);
+                    if (patched != nullptr)
+                        child->source = std::move(patched);
+                }
+            }
+
             child->size = child->source->GetSize();
             child->size = child->source->GetSize();
 
 
             AddFile(parent, child);
             AddFile(parent, child);
@@ -169,7 +186,7 @@ void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs,
     }
     }
 
 
     for (auto& child : child_dirs) {
     for (auto& child : child_dirs) {
-        this->VisitDirectory(root_romfs, child);
+        this->VisitDirectory(root_romfs, ext, child);
     }
     }
 }
 }
 
 
@@ -208,14 +225,15 @@ bool RomFSBuildContext::AddFile(std::shared_ptr<RomFSBuildDirectoryContext> pare
     return true;
     return true;
 }
 }
 
 
-RomFSBuildContext::RomFSBuildContext(VirtualDir base_) : base(std::move(base_)) {
+RomFSBuildContext::RomFSBuildContext(VirtualDir base_, VirtualDir ext_)
+    : base(std::move(base_)), ext(std::move(ext_)) {
     root = std::make_shared<RomFSBuildDirectoryContext>();
     root = std::make_shared<RomFSBuildDirectoryContext>();
     root->path = "\0";
     root->path = "\0";
     directories.emplace(root->path, root);
     directories.emplace(root->path, root);
     num_dirs = 1;
     num_dirs = 1;
     dir_table_size = 0x18;
     dir_table_size = 0x18;
 
 
-    VisitDirectory(base, root);
+    VisitDirectory(base, ext, root);
 }
 }
 
 
 RomFSBuildContext::~RomFSBuildContext() = default;
 RomFSBuildContext::~RomFSBuildContext() = default;

+ 4 - 2
src/core/file_sys/fsmitm_romfsbuild.h

@@ -40,7 +40,7 @@ struct RomFSFileEntry;
 
 
 class RomFSBuildContext {
 class RomFSBuildContext {
 public:
 public:
-    explicit RomFSBuildContext(VirtualDir base);
+    explicit RomFSBuildContext(VirtualDir base, VirtualDir ext = nullptr);
     ~RomFSBuildContext();
     ~RomFSBuildContext();
 
 
     // This finalizes the context.
     // This finalizes the context.
@@ -48,6 +48,7 @@ public:
 
 
 private:
 private:
     VirtualDir base;
     VirtualDir base;
+    VirtualDir ext;
     std::shared_ptr<RomFSBuildDirectoryContext> root;
     std::shared_ptr<RomFSBuildDirectoryContext> root;
     std::map<std::string, std::shared_ptr<RomFSBuildDirectoryContext>, std::less<>> directories;
     std::map<std::string, std::shared_ptr<RomFSBuildDirectoryContext>, std::less<>> directories;
     std::map<std::string, std::shared_ptr<RomFSBuildFileContext>, std::less<>> files;
     std::map<std::string, std::shared_ptr<RomFSBuildFileContext>, std::less<>> files;
@@ -59,7 +60,8 @@ private:
     u64 file_hash_table_size = 0;
     u64 file_hash_table_size = 0;
     u64 file_partition_size = 0;
     u64 file_partition_size = 0;
 
 
-    void VisitDirectory(VirtualDir filesys, std::shared_ptr<RomFSBuildDirectoryContext> parent);
+    void VisitDirectory(VirtualDir filesys, VirtualDir ext,
+                        std::shared_ptr<RomFSBuildDirectoryContext> parent);
 
 
     bool AddDirectory(std::shared_ptr<RomFSBuildDirectoryContext> parent_dir_ctx,
     bool AddDirectory(std::shared_ptr<RomFSBuildDirectoryContext> parent_dir_ctx,
                       std::shared_ptr<RomFSBuildDirectoryContext> dir_ctx);
                       std::shared_ptr<RomFSBuildDirectoryContext> dir_ctx);

+ 9 - 1
src/core/file_sys/patch_manager.cpp

@@ -182,11 +182,17 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
               [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); });
               [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); });
 
 
     std::vector<VirtualDir> layers;
     std::vector<VirtualDir> layers;
+    std::vector<VirtualDir> layers_ext;
     layers.reserve(patch_dirs.size() + 1);
     layers.reserve(patch_dirs.size() + 1);
+    layers_ext.reserve(patch_dirs.size() + 1);
     for (const auto& subdir : patch_dirs) {
     for (const auto& subdir : patch_dirs) {
         auto romfs_dir = subdir->GetSubdirectory("romfs");
         auto romfs_dir = subdir->GetSubdirectory("romfs");
         if (romfs_dir != nullptr)
         if (romfs_dir != nullptr)
             layers.push_back(std::move(romfs_dir));
             layers.push_back(std::move(romfs_dir));
+
+        auto ext_dir = subdir->GetSubdirectory("romfs_ext");
+        if (ext_dir != nullptr)
+            layers_ext.push_back(std::move(ext_dir));
     }
     }
     layers.push_back(std::move(extracted));
     layers.push_back(std::move(extracted));
 
 
@@ -195,7 +201,9 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
         return;
         return;
     }
     }
 
 
-    auto packed = CreateRomFS(std::move(layered));
+    auto layered_ext = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers_ext));
+
+    auto packed = CreateRomFS(std::move(layered), std::move(layered_ext));
     if (packed == nullptr) {
     if (packed == nullptr) {
         return;
         return;
     }
     }

+ 2 - 2
src/core/file_sys/romfs.cpp

@@ -129,11 +129,11 @@ VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) {
     return out;
     return out;
 }
 }
 
 
-VirtualFile CreateRomFS(VirtualDir dir) {
+VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) {
     if (dir == nullptr)
     if (dir == nullptr)
         return nullptr;
         return nullptr;
 
 
-    RomFSBuildContext ctx{dir};
+    RomFSBuildContext ctx{dir, ext};
     return ConcatenatedVfsFile::MakeConcatenatedFile(0, ctx.Build(), dir->GetName());
     return ConcatenatedVfsFile::MakeConcatenatedFile(0, ctx.Build(), dir->GetName());
 }
 }
 
 

+ 1 - 1
src/core/file_sys/romfs.h

@@ -44,6 +44,6 @@ VirtualDir ExtractRomFS(VirtualFile file,
 
 
 // Converts a VFS filesystem into a RomFS binary
 // Converts a VFS filesystem into a RomFS binary
 // Returns nullptr on failure
 // Returns nullptr on failure
-VirtualFile CreateRomFS(VirtualDir dir);
+VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext = nullptr);
 
 
 } // namespace FileSys
 } // namespace FileSys