ES: Fix content check in ImportTitleDone

ImportTitleDone only checks if all required contents have been imported
for system titles.

This fixes the system menu not being able to recreate title directories
to copy a save back to the NAND by using title import functionality.
This commit is contained in:
Léo Lam 2018-05-16 13:26:38 +02:00
parent 473cbfa951
commit f82e2f0b92

View File

@ -430,20 +430,12 @@ IPCCommandResult ES::ImportContentEnd(Context& context, const IOCtlVRequest& req
return GetDefaultReply(ImportContentEnd(context, content_fd)); return GetDefaultReply(ImportContentEnd(context, content_fd));
} }
ReturnCode ES::ImportTitleDone(Context& context) static bool HasAllRequiredContents(IOS::HLE::Kernel& ios, const IOS::ES::TMDReader& tmd)
{ {
if (!context.title_import_export.valid || context.title_import_export.content.valid) const u64 title_id = tmd.GetTitleId();
{ const std::vector<IOS::ES::Content> contents = tmd.GetContents();
ERROR_LOG(IOS_ES, "ImportTitleDone: No title import, or a content import is still in progress"); const IOS::ES::SharedContentMap shared_content_map{ios.GetFS()};
return ES_EINVAL; return std::all_of(contents.cbegin(), contents.cend(), [&](const IOS::ES::Content& content) {
}
// Make sure all listed, non-optional contents have been imported.
const u64 title_id = context.title_import_export.tmd.GetTitleId();
const std::vector<IOS::ES::Content> contents = context.title_import_export.tmd.GetContents();
const IOS::ES::SharedContentMap shared_content_map{m_ios.GetFS()};
const bool has_all_required_contents =
std::all_of(contents.cbegin(), contents.cend(), [&](const IOS::ES::Content& content) {
if (content.IsOptional()) if (content.IsOptional())
return true; return true;
@ -452,11 +444,24 @@ ReturnCode ES::ImportTitleDone(Context& context)
// Note: the import hasn't been finalised yet, so the whole title directory // Note: the import hasn't been finalised yet, so the whole title directory
// is still in /import, not /title. // is still in /import, not /title.
const std::string path = Common::GetImportTitlePath(title_id) + const std::string path =
StringFromFormat("/content/%08x.app", content.id); Common::GetImportTitlePath(title_id) + StringFromFormat("/content/%08x.app", content.id);
return m_ios.GetFS()->GetMetadata(PID_KERNEL, PID_KERNEL, path).Succeeded(); return ios.GetFS()->GetMetadata(PID_KERNEL, PID_KERNEL, path).Succeeded();
}); });
if (!has_all_required_contents) }
ReturnCode ES::ImportTitleDone(Context& context)
{
if (!context.title_import_export.valid || context.title_import_export.content.valid)
{
ERROR_LOG(IOS_ES, "ImportTitleDone: No title import, or a content import is still in progress");
return ES_EINVAL;
}
// For system titles, make sure all listed, non-optional contents have been imported.
const u64 title_id = context.title_import_export.tmd.GetTitleId();
if (title_id - 0x100000001LL <= 0x100 &&
!HasAllRequiredContents(m_ios, context.title_import_export.tmd))
{ {
ERROR_LOG(IOS_ES, "ImportTitleDone: Some required contents are missing"); ERROR_LOG(IOS_ES, "ImportTitleDone: Some required contents are missing");
return ES_EINVAL; return ES_EINVAL;