Merge pull request #5016 from leoetlino/es-di-gettmd

IOS/ES: Implement ES_DIGetTMDView (and GetTMDViewSize)
This commit is contained in:
Matthew Parlane 2017-03-07 00:05:47 +13:00 committed by GitHub
commit 7d681f9c93
2 changed files with 104 additions and 5 deletions

View File

@ -397,10 +397,19 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetViewCount(request); return GetViewCount(request);
case IOCTL_ES_GETVIEWS: case IOCTL_ES_GETVIEWS:
return GetViews(request); return GetViews(request);
case IOCTL_ES_DIGETTICKETVIEW:
return DIGetTicketView(request);
case IOCTL_ES_GETTMDVIEWCNT: case IOCTL_ES_GETTMDVIEWCNT:
return GetTMDViewSize(request); return GetTMDViewSize(request);
case IOCTL_ES_GETTMDVIEWS: case IOCTL_ES_GETTMDVIEWS:
return GetTMDViews(request); return GetTMDViews(request);
case IOCTL_ES_DIGETTMDVIEWSIZE:
return DIGetTMDViewSize(request);
case IOCTL_ES_DIGETTMDVIEW:
return DIGetTMDView(request);
case IOCTL_ES_GETCONSUMPTION: case IOCTL_ES_GETCONSUMPTION:
return GetConsumption(request); return GetConsumption(request);
case IOCTL_ES_DELETETITLE: case IOCTL_ES_DELETETITLE:
@ -439,8 +448,6 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return Sign(request); return Sign(request);
case IOCTL_ES_GETBOOT2VERSION: case IOCTL_ES_GETBOOT2VERSION:
return GetBoot2Version(request); return GetBoot2Version(request);
case IOCTL_ES_DIGETTICKETVIEW:
return DIGetTicketView(request);
default: default:
request.DumpUnknown(GetDeviceName(), LogTypes::IOS_ES); request.DumpUnknown(GetDeviceName(), LogTypes::IOS_ES);
break; break;
@ -1104,6 +1111,93 @@ IPCCommandResult ES::GetTMDViews(const IOCtlVRequest& request)
return GetDefaultReply(IPC_SUCCESS); return GetDefaultReply(IPC_SUCCESS);
} }
IPCCommandResult ES::DIGetTMDViewSize(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(1, 1))
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
// Sanity check the TMD size.
if (request.in_vectors[0].size >= 4 * 1024 * 1024)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
if (request.io_vectors[0].size != sizeof(u32))
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
const bool has_tmd = request.in_vectors[0].size != 0;
size_t tmd_view_size = 0;
if (has_tmd)
{
std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());
const IOS::ES::TMDReader tmd{std::move(tmd_bytes)};
// Yes, this returns -1017, not ES_INVALID_TMD.
// IOS simply checks whether the TMD has all required content entries.
if (!tmd.IsValid())
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
tmd_view_size = tmd.GetRawView().size();
}
else
{
// If no TMD was passed in and no title is active, IOS returns -1017.
if (!s_title_context.active)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
tmd_view_size = s_title_context.tmd.GetRawView().size();
}
Memory::Write_U32(static_cast<u32>(tmd_view_size), request.io_vectors[0].address);
return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult ES::DIGetTMDView(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(2, 1))
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
// Sanity check the TMD size.
if (request.in_vectors[0].size >= 4 * 1024 * 1024)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
// Check whether the TMD view size is consistent.
if (request.in_vectors[1].size != sizeof(u32) ||
Memory::Read_U32(request.in_vectors[1].address) != request.io_vectors[0].size)
{
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
}
const bool has_tmd = request.in_vectors[0].size != 0;
std::vector<u8> tmd_view;
if (has_tmd)
{
std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());
const IOS::ES::TMDReader tmd{std::move(tmd_bytes)};
if (!tmd.IsValid())
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
tmd_view = tmd.GetRawView();
}
else
{
// If no TMD was passed in and no title is active, IOS returns -1017.
if (!s_title_context.active)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
tmd_view = s_title_context.tmd.GetRawView();
}
if (tmd_view.size() != request.io_vectors[0].size)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
Memory::CopyToEmu(request.io_vectors[0].address, tmd_view.data(), tmd_view.size());
return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult ES::GetConsumption(const IOCtlVRequest& request) IPCCommandResult ES::GetConsumption(const IOCtlVRequest& request)
{ {
if (!request.HasNumberOfValidVectors(1, 2)) if (!request.HasNumberOfValidVectors(1, 2))

View File

@ -77,8 +77,8 @@ private:
IOCTL_ES_GETCONSUMPTION = 0x16, IOCTL_ES_GETCONSUMPTION = 0x16,
IOCTL_ES_DELETETITLE = 0x17, IOCTL_ES_DELETETITLE = 0x17,
IOCTL_ES_DELETETICKET = 0x18, IOCTL_ES_DELETETICKET = 0x18,
// IOCTL_ES_DIGETTMDVIEWSIZE = 0x19, IOCTL_ES_DIGETTMDVIEWSIZE = 0x19,
// IOCTL_ES_DIGETTMDVIEW = 0x1A, IOCTL_ES_DIGETTMDVIEW = 0x1A,
IOCTL_ES_DIGETTICKETVIEW = 0x1B, IOCTL_ES_DIGETTICKETVIEW = 0x1B,
IOCTL_ES_DIVERIFY = 0x1C, IOCTL_ES_DIVERIFY = 0x1C,
IOCTL_ES_GETTITLEDIR = 0x1D, IOCTL_ES_GETTITLEDIR = 0x1D,
@ -177,8 +177,14 @@ private:
IPCCommandResult GetViewCount(const IOCtlVRequest& request); IPCCommandResult GetViewCount(const IOCtlVRequest& request);
IPCCommandResult GetViews(const IOCtlVRequest& request); IPCCommandResult GetViews(const IOCtlVRequest& request);
IPCCommandResult DIGetTicketView(const IOCtlVRequest& request);
IPCCommandResult GetTMDViewSize(const IOCtlVRequest& request); IPCCommandResult GetTMDViewSize(const IOCtlVRequest& request);
IPCCommandResult GetTMDViews(const IOCtlVRequest& request); IPCCommandResult GetTMDViews(const IOCtlVRequest& request);
IPCCommandResult DIGetTMDViewSize(const IOCtlVRequest& request);
IPCCommandResult DIGetTMDView(const IOCtlVRequest& request);
IPCCommandResult GetConsumption(const IOCtlVRequest& request); IPCCommandResult GetConsumption(const IOCtlVRequest& request);
IPCCommandResult DeleteTitle(const IOCtlVRequest& request); IPCCommandResult DeleteTitle(const IOCtlVRequest& request);
IPCCommandResult DeleteTicket(const IOCtlVRequest& request); IPCCommandResult DeleteTicket(const IOCtlVRequest& request);
@ -200,7 +206,6 @@ private:
IPCCommandResult GetDeviceCertificate(const IOCtlVRequest& request); IPCCommandResult GetDeviceCertificate(const IOCtlVRequest& request);
IPCCommandResult Sign(const IOCtlVRequest& request); IPCCommandResult Sign(const IOCtlVRequest& request);
IPCCommandResult GetBoot2Version(const IOCtlVRequest& request); IPCCommandResult GetBoot2Version(const IOCtlVRequest& request);
IPCCommandResult DIGetTicketView(const IOCtlVRequest& request);
static bool LaunchIOS(u64 ios_title_id); static bool LaunchIOS(u64 ios_title_id);
static bool LaunchPPCTitle(u64 title_id, bool skip_reload); static bool LaunchPPCTitle(u64 title_id, bool skip_reload);