mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-11-24 14:02:47 +00:00
registered_cache: Add support for removing folder ncas
This commit is contained in:
parent
b317942131
commit
2ec852dd9f
|
@ -547,56 +547,6 @@ InstallResult RegisteredCache::InstallEntry(const XCI& xci, bool overwrite_if_ex
|
||||||
return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy);
|
return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegisteredCache::RemoveExistingEntry(u64 title_id) {
|
|
||||||
const auto delete_nca = [this](const NcaID& id) {
|
|
||||||
const auto path = GetRelativePathFromNcaID(id, false, true, false);
|
|
||||||
|
|
||||||
if (dir->GetFileRelative(path) == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Core::Crypto::SHA256Hash hash{};
|
|
||||||
mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0);
|
|
||||||
const auto dirname = fmt::format("000000{:02X}", hash[0]);
|
|
||||||
|
|
||||||
const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname);
|
|
||||||
|
|
||||||
const auto res = dir2->DeleteFile(fmt::format("{}.nca", Common::HexToString(id, false)));
|
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
// If an entry exists in the registered cache, remove it
|
|
||||||
if (HasEntry(title_id, ContentRecordType::Meta)) {
|
|
||||||
LOG_INFO(Loader,
|
|
||||||
"Previously installed entry (v{}) for title_id={:016X} detected! "
|
|
||||||
"Attempting to remove...",
|
|
||||||
GetEntryVersion(title_id).value_or(0), title_id);
|
|
||||||
// Get all the ncas associated with the current CNMT and delete them
|
|
||||||
const auto meta_old_id =
|
|
||||||
GetNcaIDFromMetadata(title_id, ContentRecordType::Meta).value_or(NcaID{});
|
|
||||||
const auto program_id =
|
|
||||||
GetNcaIDFromMetadata(title_id, ContentRecordType::Program).value_or(NcaID{});
|
|
||||||
const auto data_id =
|
|
||||||
GetNcaIDFromMetadata(title_id, ContentRecordType::Data).value_or(NcaID{});
|
|
||||||
const auto control_id =
|
|
||||||
GetNcaIDFromMetadata(title_id, ContentRecordType::Control).value_or(NcaID{});
|
|
||||||
const auto html_id =
|
|
||||||
GetNcaIDFromMetadata(title_id, ContentRecordType::HtmlDocument).value_or(NcaID{});
|
|
||||||
const auto legal_id =
|
|
||||||
GetNcaIDFromMetadata(title_id, ContentRecordType::LegalInformation).value_or(NcaID{});
|
|
||||||
|
|
||||||
delete_nca(meta_old_id);
|
|
||||||
delete_nca(program_id);
|
|
||||||
delete_nca(data_id);
|
|
||||||
delete_nca(control_id);
|
|
||||||
delete_nca(html_id);
|
|
||||||
delete_nca(legal_id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists,
|
InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists,
|
||||||
const VfsCopyFunction& copy) {
|
const VfsCopyFunction& copy) {
|
||||||
const auto ncas = nsp.GetNCAsCollapsed();
|
const auto ncas = nsp.GetNCAsCollapsed();
|
||||||
|
@ -692,6 +642,57 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
|
||||||
return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id);
|
return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
|
||||||
|
const auto delete_nca = [this](const NcaID& id) {
|
||||||
|
const auto path = GetRelativePathFromNcaID(id, false, true, false);
|
||||||
|
|
||||||
|
const bool isFile = dir->GetFileRelative(path) != nullptr;
|
||||||
|
const bool isDir = dir->GetDirectoryRelative(path) != nullptr;
|
||||||
|
|
||||||
|
if (isFile) {
|
||||||
|
return dir->DeleteFile(path);
|
||||||
|
} else if (isDir) {
|
||||||
|
return dir->DeleteSubdirectoryRecursive(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// If an entry exists in the registered cache, remove it
|
||||||
|
if (HasEntry(title_id, ContentRecordType::Meta)) {
|
||||||
|
LOG_INFO(Loader,
|
||||||
|
"Previously installed entry (v{}) for title_id={:016X} detected! "
|
||||||
|
"Attempting to remove...",
|
||||||
|
GetEntryVersion(title_id).value_or(0), title_id);
|
||||||
|
|
||||||
|
// Get all the ncas associated with the current CNMT and delete them
|
||||||
|
const auto meta_old_id =
|
||||||
|
GetNcaIDFromMetadata(title_id, ContentRecordType::Meta).value_or(NcaID{});
|
||||||
|
const auto program_id =
|
||||||
|
GetNcaIDFromMetadata(title_id, ContentRecordType::Program).value_or(NcaID{});
|
||||||
|
const auto data_id =
|
||||||
|
GetNcaIDFromMetadata(title_id, ContentRecordType::Data).value_or(NcaID{});
|
||||||
|
const auto control_id =
|
||||||
|
GetNcaIDFromMetadata(title_id, ContentRecordType::Control).value_or(NcaID{});
|
||||||
|
const auto html_id =
|
||||||
|
GetNcaIDFromMetadata(title_id, ContentRecordType::HtmlDocument).value_or(NcaID{});
|
||||||
|
const auto legal_id =
|
||||||
|
GetNcaIDFromMetadata(title_id, ContentRecordType::LegalInformation).value_or(NcaID{});
|
||||||
|
|
||||||
|
const auto deleted_meta = delete_nca(meta_old_id);
|
||||||
|
const auto deleted_program = delete_nca(program_id);
|
||||||
|
const auto deleted_data = delete_nca(data_id);
|
||||||
|
const auto deleted_control = delete_nca(control_id);
|
||||||
|
const auto deleted_html = delete_nca(html_id);
|
||||||
|
const auto deleted_legal = delete_nca(legal_id);
|
||||||
|
|
||||||
|
return deleted_meta && (deleted_meta || deleted_program || deleted_data ||
|
||||||
|
deleted_control || deleted_html || deleted_legal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,
|
InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,
|
||||||
bool overwrite_if_exists,
|
bool overwrite_if_exists,
|
||||||
std::optional<NcaID> override_id) {
|
std::optional<NcaID> override_id) {
|
||||||
|
|
|
@ -155,9 +155,6 @@ public:
|
||||||
std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
|
std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
|
||||||
std::optional<u64> title_id = {}) const override;
|
std::optional<u64> title_id = {}) const override;
|
||||||
|
|
||||||
// Removes an existing entry based on title id
|
|
||||||
bool RemoveExistingEntry(u64 title_id);
|
|
||||||
|
|
||||||
// Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
|
// Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
|
||||||
// there is a meta NCA and all of them are accessible.
|
// there is a meta NCA and all of them are accessible.
|
||||||
InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false,
|
InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false,
|
||||||
|
@ -172,6 +169,9 @@ public:
|
||||||
InstallResult InstallEntry(const NCA& nca, TitleType type, bool overwrite_if_exists = false,
|
InstallResult InstallEntry(const NCA& nca, TitleType type, bool overwrite_if_exists = false,
|
||||||
const VfsCopyFunction& copy = &VfsRawCopy);
|
const VfsCopyFunction& copy = &VfsRawCopy);
|
||||||
|
|
||||||
|
// Removes an existing entry based on title id
|
||||||
|
bool RemoveExistingEntry(u64 title_id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void IterateAllMetadata(std::vector<T>& out,
|
void IterateAllMetadata(std::vector<T>& out,
|
||||||
|
|
Loading…
Reference in a new issue