summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/file_sys/registered_cache.cpp101
-rw-r--r--src/core/file_sys/registered_cache.h6
2 files changed, 54 insertions, 53 deletions
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 37351c561..e94eed3b6 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -547,56 +547,6 @@ InstallResult RegisteredCache::InstallEntry(const XCI& xci, bool overwrite_if_ex
547 return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy); 547 return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy);
548} 548}
549 549
550bool RegisteredCache::RemoveExistingEntry(u64 title_id) {
551 const auto delete_nca = [this](const NcaID& id) {
552 const auto path = GetRelativePathFromNcaID(id, false, true, false);
553
554 if (dir->GetFileRelative(path) == nullptr) {
555 return false;
556 }
557
558 Core::Crypto::SHA256Hash hash{};
559 mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0);
560 const auto dirname = fmt::format("000000{:02X}", hash[0]);
561
562 const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname);
563
564 const auto res = dir2->DeleteFile(fmt::format("{}.nca", Common::HexToString(id, false)));
565
566 return res;
567 };
568
569 // If an entry exists in the registered cache, remove it
570 if (HasEntry(title_id, ContentRecordType::Meta)) {
571 LOG_INFO(Loader,
572 "Previously installed entry (v{}) for title_id={:016X} detected! "
573 "Attempting to remove...",
574 GetEntryVersion(title_id).value_or(0), title_id);
575 // Get all the ncas associated with the current CNMT and delete them
576 const auto meta_old_id =
577 GetNcaIDFromMetadata(title_id, ContentRecordType::Meta).value_or(NcaID{});
578 const auto program_id =
579 GetNcaIDFromMetadata(title_id, ContentRecordType::Program).value_or(NcaID{});
580 const auto data_id =
581 GetNcaIDFromMetadata(title_id, ContentRecordType::Data).value_or(NcaID{});
582 const auto control_id =
583 GetNcaIDFromMetadata(title_id, ContentRecordType::Control).value_or(NcaID{});
584 const auto html_id =
585 GetNcaIDFromMetadata(title_id, ContentRecordType::HtmlDocument).value_or(NcaID{});
586 const auto legal_id =
587 GetNcaIDFromMetadata(title_id, ContentRecordType::LegalInformation).value_or(NcaID{});
588
589 delete_nca(meta_old_id);
590 delete_nca(program_id);
591 delete_nca(data_id);
592 delete_nca(control_id);
593 delete_nca(html_id);
594 delete_nca(legal_id);
595 return true;
596 }
597 return false;
598}
599
600InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists, 550InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists,
601 const VfsCopyFunction& copy) { 551 const VfsCopyFunction& copy) {
602 const auto ncas = nsp.GetNCAsCollapsed(); 552 const auto ncas = nsp.GetNCAsCollapsed();
@@ -692,6 +642,57 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
692 return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id); 642 return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id);
693} 643}
694 644
645bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
646 const auto delete_nca = [this](const NcaID& id) {
647 const auto path = GetRelativePathFromNcaID(id, false, true, false);
648
649 const bool isFile = dir->GetFileRelative(path) != nullptr;
650 const bool isDir = dir->GetDirectoryRelative(path) != nullptr;
651
652 if (isFile) {
653 return dir->DeleteFile(path);
654 } else if (isDir) {
655 return dir->DeleteSubdirectoryRecursive(path);
656 }
657
658 return false;
659 };
660
661 // If an entry exists in the registered cache, remove it
662 if (HasEntry(title_id, ContentRecordType::Meta)) {
663 LOG_INFO(Loader,
664 "Previously installed entry (v{}) for title_id={:016X} detected! "
665 "Attempting to remove...",
666 GetEntryVersion(title_id).value_or(0), title_id);
667
668 // Get all the ncas associated with the current CNMT and delete them
669 const auto meta_old_id =
670 GetNcaIDFromMetadata(title_id, ContentRecordType::Meta).value_or(NcaID{});
671 const auto program_id =
672 GetNcaIDFromMetadata(title_id, ContentRecordType::Program).value_or(NcaID{});
673 const auto data_id =
674 GetNcaIDFromMetadata(title_id, ContentRecordType::Data).value_or(NcaID{});
675 const auto control_id =
676 GetNcaIDFromMetadata(title_id, ContentRecordType::Control).value_or(NcaID{});
677 const auto html_id =
678 GetNcaIDFromMetadata(title_id, ContentRecordType::HtmlDocument).value_or(NcaID{});
679 const auto legal_id =
680 GetNcaIDFromMetadata(title_id, ContentRecordType::LegalInformation).value_or(NcaID{});
681
682 const auto deleted_meta = delete_nca(meta_old_id);
683 const auto deleted_program = delete_nca(program_id);
684 const auto deleted_data = delete_nca(data_id);
685 const auto deleted_control = delete_nca(control_id);
686 const auto deleted_html = delete_nca(html_id);
687 const auto deleted_legal = delete_nca(legal_id);
688
689 return deleted_meta && (deleted_meta || deleted_program || deleted_data ||
690 deleted_control || deleted_html || deleted_legal);
691 }
692
693 return false;
694}
695
695InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy, 696InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,
696 bool overwrite_if_exists, 697 bool overwrite_if_exists,
697 std::optional<NcaID> override_id) { 698 std::optional<NcaID> override_id) {
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index 29cf0d40c..ec1d54f27 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -155,9 +155,6 @@ public:
155 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {}, 155 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
156 std::optional<u64> title_id = {}) const override; 156 std::optional<u64> title_id = {}) const override;
157 157
158 // Removes an existing entry based on title id
159 bool RemoveExistingEntry(u64 title_id);
160
161 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure 158 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
162 // there is a meta NCA and all of them are accessible. 159 // there is a meta NCA and all of them are accessible.
163 InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false, 160 InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false,
@@ -172,6 +169,9 @@ public:
172 InstallResult InstallEntry(const NCA& nca, TitleType type, bool overwrite_if_exists = false, 169 InstallResult InstallEntry(const NCA& nca, TitleType type, bool overwrite_if_exists = false,
173 const VfsCopyFunction& copy = &VfsRawCopy); 170 const VfsCopyFunction& copy = &VfsRawCopy);
174 171
172 // Removes an existing entry based on title id
173 bool RemoveExistingEntry(u64 title_id) const;
174
175private: 175private:
176 template <typename T> 176 template <typename T>
177 void IterateAllMetadata(std::vector<T>& out, 177 void IterateAllMetadata(std::vector<T>& out,