From 3b3c919e204a8fc5d2a4e7f372514f257acbe96e Mon Sep 17 00:00:00 2001
From: Zach Hilman <zachhilman@gmail.com>
Date: Fri, 10 Aug 2018 15:06:37 -0400
Subject: [PATCH] registration: Take RawCopy function as parameter Instead of
 defaulting to VfsRawCopy

---
 src/core/file_sys/registered_cache.cpp | 16 +++++++++-------
 src/core/file_sys/registered_cache.h   |  9 ++++++---
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 665126c1c4..aaadb7463f 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -335,7 +335,7 @@ static std::shared_ptr<NCA> GetNCAFromXCIForID(std::shared_ptr<XCI> xci, const N
     return iter == xci->GetNCAs().end() ? nullptr : *iter;
 }
 
-bool RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci) {
+bool RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci, const VfsCopyFunction& copy) {
     const auto& ncas = xci->GetNCAs();
     const auto& meta_iter = std::find_if(ncas.begin(), ncas.end(), [](std::shared_ptr<NCA> nca) {
         return nca->GetType() == NCAContentType::Meta;
@@ -350,7 +350,7 @@ bool RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci) {
     // Install Metadata File
     const auto meta_id_raw = (*meta_iter)->GetName().substr(0, 32);
     const auto meta_id = HexStringToArray<16>(meta_id_raw);
-    if (!RawInstallNCA(*meta_iter, meta_id))
+    if (!RawInstallNCA(*meta_iter, copy, meta_id))
         return false;
 
     // Install all the other NCAs
@@ -359,7 +359,7 @@ bool RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci) {
     const CNMT cnmt(cnmt_file);
     for (const auto& record : cnmt.GetContentRecords()) {
         const auto nca = GetNCAFromXCIForID(xci, record.nca_id);
-        if (nca == nullptr || !RawInstallNCA(nca, record.nca_id))
+        if (nca == nullptr || !RawInstallNCA(nca, copy, record.nca_id))
             return false;
     }
 
@@ -367,7 +367,8 @@ bool RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci) {
     return true;
 }
 
-bool RegisteredCache::InstallEntry(std::shared_ptr<NCA> nca, TitleType type) {
+bool RegisteredCache::InstallEntry(std::shared_ptr<NCA> nca, TitleType type,
+                                   const VfsCopyFunction& copy) {
     CNMTHeader header{
         nca->GetTitleId(), ///< Title ID
         0,                 ///< Ignore/Default title version
@@ -384,10 +385,11 @@ bool RegisteredCache::InstallEntry(std::shared_ptr<NCA> nca, TitleType type) {
     mbedtls_sha256(data.data(), data.size(), c_rec.hash.data(), 0);
     memcpy(&c_rec.nca_id, &c_rec.hash, 16);
     const CNMT new_cnmt(header, opt_header, {c_rec}, {});
-    return RawInstallYuzuMeta(new_cnmt) && RawInstallNCA(nca, c_rec.nca_id);
+    return RawInstallYuzuMeta(new_cnmt) && RawInstallNCA(nca, copy, c_rec.nca_id);
 }
 
-bool RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, boost::optional<NcaID> override_id) {
+bool RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy,
+                                    boost::optional<NcaID> override_id) {
     const auto in = nca->GetBaseFile();
     Core::Crypto::SHA256Hash hash{};
 
@@ -414,7 +416,7 @@ bool RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, boost::optional<Nc
     auto out = dir->CreateFileRelative(path);
     if (out == nullptr)
         return false;
-    return VfsRawCopy(in, out);
+    return copy(in, out);
 }
 
 bool RegisteredCache::RawInstallYuzuMeta(const CNMT& cnmt) {
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index baaed02dda..f2b07eec87 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -23,6 +23,7 @@ class CNMT;
 
 using NcaID = std::array<u8, 0x10>;
 using RegisteredCacheParsingFunction = std::function<VirtualFile(const VirtualFile&, const NcaID&)>;
+using VfsCopyFunction = std::function<bool(VirtualFile, VirtualFile)>;
 
 struct RegisteredCacheEntry {
     u64 title_id;
@@ -76,13 +77,14 @@ public:
 
     // Raw copies all the ncas from the xci to the csache. Does some quick checks to make sure there
     // is a meta NCA and all of them are accessible.
-    bool InstallEntry(std::shared_ptr<XCI> xci);
+    bool InstallEntry(std::shared_ptr<XCI> xci, const VfsCopyFunction& copy = &VfsRawCopy);
 
     // Due to the fact that we must use Meta-type NCAs to determine the existance of files, this
     // poses quite a challenge. Instead of creating a new meta NCA for this file, yuzu will create a
     // dir inside the NAND called 'yuzu_meta' and store the raw CNMT there.
     // TODO(DarkLordZach): Author real meta-type NCAs and install those.
-    bool InstallEntry(std::shared_ptr<NCA> nca, TitleType type);
+    bool InstallEntry(std::shared_ptr<NCA> nca, TitleType type,
+                      const VfsCopyFunction& copy = &VfsRawCopy);
 
 private:
     template <typename T>
@@ -95,7 +97,8 @@ private:
     boost::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const;
     VirtualFile GetFileAtID(NcaID id) const;
     VirtualFile OpenFileOrDirectoryConcat(const VirtualDir& dir, std::string_view path) const;
-    bool RawInstallNCA(std::shared_ptr<NCA> nca, boost::optional<NcaID> override_id = boost::none);
+    bool RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy,
+                       boost::optional<NcaID> override_id = boost::none);
     bool RawInstallYuzuMeta(const CNMT& cnmt);
 
     VirtualDir dir;