diff options
| -rw-r--r-- | src/core/file_sys/registered_cache.cpp | 101 | ||||
| -rw-r--r-- | src/core/file_sys/registered_cache.h | 6 |
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 | ||
| 550 | bool 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 | |||
| 600 | InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists, | 550 | InstallResult 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 | ||
| 645 | bool 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 | |||
| 695 | InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy, | 696 | InstallResult 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 | |||
| 175 | private: | 175 | private: |
| 176 | template <typename T> | 176 | template <typename T> |
| 177 | void IterateAllMetadata(std::vector<T>& out, | 177 | void IterateAllMetadata(std::vector<T>& out, |