registered_cache: create fake CNMT entries for program updates of multiprogram applications (#11319)

This commit is contained in:
liamwhite 2023-08-25 18:00:15 -04:00 committed by GitHub
parent 18ad55be0b
commit b923f5aa7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -606,9 +606,9 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
const auto result = RemoveExistingEntry(title_id); const auto result = RemoveExistingEntry(title_id);
// Install Metadata File // Install Metadata File
const auto res = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data); const auto meta_result = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data);
if (res != InstallResult::Success) { if (meta_result != InstallResult::Success) {
return res; return meta_result;
} }
// Install all the other NCAs // Install all the other NCAs
@ -621,9 +621,19 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
if (nca == nullptr) { if (nca == nullptr) {
return InstallResult::ErrorCopyFailed; return InstallResult::ErrorCopyFailed;
} }
const auto res2 = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id); if (nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS &&
if (res2 != InstallResult::Success) { nca->GetTitleId() != title_id) {
return res2; // Create fake cnmt for patch to multiprogram application
const auto sub_nca_result =
InstallEntry(*nca, TitleType::Update, overwrite_if_exists, copy);
if (sub_nca_result != InstallResult::Success) {
return sub_nca_result;
}
continue;
}
const auto nca_result = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id);
if (nca_result != InstallResult::Success) {
return nca_result;
} }
} }
@ -663,6 +673,8 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
} }
bool RegisteredCache::RemoveExistingEntry(u64 title_id) const { bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
bool removed_data = false;
const auto delete_nca = [this](const NcaID& id) { const auto delete_nca = [this](const NcaID& id) {
const auto path = GetRelativePathFromNcaID(id, false, true, false); const auto path = GetRelativePathFromNcaID(id, false, true, false);
@ -706,11 +718,18 @@ bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
const auto deleted_html = delete_nca(html_id); const auto deleted_html = delete_nca(html_id);
const auto deleted_legal = delete_nca(legal_id); const auto deleted_legal = delete_nca(legal_id);
return deleted_meta && (deleted_meta || deleted_program || deleted_data || removed_data |= (deleted_meta || deleted_program || deleted_data || deleted_control ||
deleted_control || deleted_html || deleted_legal); deleted_html || deleted_legal);
} }
return false; // If patch entries for any program exist in yuzu meta, remove them
for (u8 i = 0; i < 0x10; i++) {
const auto meta_dir = dir->CreateDirectoryRelative("yuzu_meta");
const auto filename = GetCNMTName(TitleType::Update, title_id + i);
removed_data |= meta_dir->DeleteFile(filename);
}
return removed_data;
} }
InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy, InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,