diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 665126c1c..aaadb7463 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 GetNCAFromXCIForID(std::shared_ptr xci, const N return iter == xci->GetNCAs().end() ? nullptr : *iter; } -bool RegisteredCache::InstallEntry(std::shared_ptr xci) { +bool RegisteredCache::InstallEntry(std::shared_ptr xci, const VfsCopyFunction& copy) { const auto& ncas = xci->GetNCAs(); const auto& meta_iter = std::find_if(ncas.begin(), ncas.end(), [](std::shared_ptr nca) { return nca->GetType() == NCAContentType::Meta; @@ -350,7 +350,7 @@ bool RegisteredCache::InstallEntry(std::shared_ptr 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) { 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) { return true; } -bool RegisteredCache::InstallEntry(std::shared_ptr nca, TitleType type) { +bool RegisteredCache::InstallEntry(std::shared_ptr 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, 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, boost::optional override_id) { +bool RegisteredCache::RawInstallNCA(std::shared_ptr nca, const VfsCopyFunction& copy, + boost::optional override_id) { const auto in = nca->GetBaseFile(); Core::Crypto::SHA256Hash hash{}; @@ -414,7 +416,7 @@ bool RegisteredCache::RawInstallNCA(std::shared_ptr nca, boost::optionalCreateFileRelative(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 baaed02dd..f2b07eec8 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; using RegisteredCacheParsingFunction = std::function; +using VfsCopyFunction = std::function; 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); + bool InstallEntry(std::shared_ptr 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, TitleType type); + bool InstallEntry(std::shared_ptr nca, TitleType type, + const VfsCopyFunction& copy = &VfsRawCopy); private: template @@ -95,7 +97,8 @@ private: boost::optional 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, boost::optional override_id = boost::none); + bool RawInstallNCA(std::shared_ptr nca, const VfsCopyFunction& copy, + boost::optional override_id = boost::none); bool RawInstallYuzuMeta(const CNMT& cnmt); VirtualDir dir;