IOS/ES: Properly handle missing TMD in GetStoredTMD

When the TMD doesn't exist on the NAND, IOS returns -106.

This commit also changes IsValid() to not check for the TMD validity,
since this is not always something we want. (IOS can have different
error codes when the TMD is missing, or even worse, simply assume
that the TMD is valid.)
This commit is contained in:
Léo Lam 2017-03-02 21:19:41 +01:00
parent b1ffbef5ce
commit 1525396ecf

View File

@ -231,6 +231,9 @@ bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload)
return false; return false;
} }
if (!content_loader.GetTMD().IsValid() || !content_loader.GetTicket().IsValid())
return false;
// Before launching a title, IOS first reads the TMD and reloads into the specified IOS version, // Before launching a title, IOS first reads the TMD and reloads into the specified IOS version,
// even when that version is already running. After it has reloaded, ES_Launch will be called // even when that version is already running. After it has reloaded, ES_Launch will be called
// again with the reload skipped, and the PPC will be bootstrapped then. // again with the reload skipped, and the PPC will be bootstrapped then.
@ -310,7 +313,7 @@ u32 ES::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index)
{ {
const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID);
if (!Loader.IsValid() || !Loader.GetTicket().IsValid()) if (!Loader.IsValid() || !Loader.GetTMD().IsValid() || !Loader.GetTicket().IsValid())
{ {
WARN_LOG(IOS_ES, "ES: loader not valid for %" PRIx64, TitleID); WARN_LOG(IOS_ES, "ES: loader not valid for %" PRIx64, TitleID);
return 0xffffffff; return 0xffffffff;
@ -660,7 +663,7 @@ IPCCommandResult ES::GetTitleContentsCount(const IOCtlVRequest& request)
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
const DiscIO::CNANDContentLoader& nand_content = AccessContentDevice(TitleID); const DiscIO::CNANDContentLoader& nand_content = AccessContentDevice(TitleID);
if (!nand_content.IsValid()) if (!nand_content.IsValid() || !nand_content.GetTMD().IsValid())
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
const u16 num_contents = nand_content.GetTMD().GetNumContents(); const u16 num_contents = nand_content.GetTMD().GetNumContents();
@ -684,7 +687,7 @@ IPCCommandResult ES::GetTitleContents(const IOCtlVRequest& request)
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID); const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID);
if (!rNANDContent.IsValid()) if (!rNANDContent.IsValid() || !rNANDContent.GetTMD().IsValid())
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
for (const auto& content : rNANDContent.GetTMD().GetContents()) for (const auto& content : rNANDContent.GetTMD().GetContents())
@ -1182,10 +1185,10 @@ IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID);
u32 tmd_size = 0; if (!Loader.IsValid() || !Loader.GetTMD().IsValid())
if (Loader.IsValid()) return GetDefaultReply(FS_ENOENT);
tmd_size = static_cast<u32>(Loader.GetTMD().GetRawTMD().size());
const u32 tmd_size = static_cast<u32>(Loader.GetTMD().GetRawTMD().size());
Memory::Write_U32(tmd_size, request.io_vectors[0].address); Memory::Write_U32(tmd_size, request.io_vectors[0].address);
INFO_LOG(IOS_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)", INFO_LOG(IOS_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)",
@ -1204,17 +1207,14 @@ IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request)
const u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address); const u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address);
const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID);
INFO_LOG(IOS_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x buffer size: %i", if (!Loader.IsValid() || !Loader.GetTMD().IsValid())
(u32)(TitleID >> 32), (u32)TitleID, MaxCount); return GetDefaultReply(FS_ENOENT);
if (Loader.IsValid()) const std::vector<u8> raw_tmd = Loader.GetTMD().GetRawTMD();
{ if (raw_tmd.size() != request.io_vectors[0].size)
const std::vector<u8> raw_tmd = Loader.GetTMD().GetRawTMD(); return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
if (raw_tmd.size() != request.io_vectors[0].size)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size()); Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size());
}
INFO_LOG(IOS_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)", INFO_LOG(IOS_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)",
(u32)(TitleID >> 32), (u32)TitleID, MaxCount); (u32)(TitleID >> 32), (u32)TitleID, MaxCount);