From 95aa48d0865d4e56dbcc3e232c04ed73f56b86c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 25 Feb 2017 01:09:45 +0100 Subject: [PATCH] IOS/ES: Implement AddTMD --- Source/Core/Core/IOS/ES/ES.cpp | 42 ++++++++++++++++++++++++++++------ Source/Core/Core/IOS/ES/ES.h | 1 + 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index dc18a84cb7..95599c6a3e 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -260,6 +260,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request) { case IOCTL_ES_ADDTICKET: return AddTicket(request); + case IOCTL_ES_ADDTMD: + return AddTMD(request); case IOCTL_ES_ADDTITLESTART: return AddTitleStart(request); case IOCTL_ES_ADDCONTENTSTART: @@ -370,6 +372,37 @@ IPCCommandResult ES::AddTicket(const IOCtlVRequest& request) return GetDefaultReply(IPC_SUCCESS); } +// TODO: write this to /tmp (or /import?) first, as title imports can be cancelled. +static bool WriteTMD(const IOS::ES::TMDReader& tmd) +{ + const std::string tmd_path = Common::GetTMDFileName(tmd.GetTitleId(), Common::FROM_SESSION_ROOT); + File::CreateFullPath(tmd_path); + + File::IOFile fp(tmd_path, "wb"); + return fp.WriteBytes(tmd.GetRawTMD().data(), tmd.GetRawTMD().size()); +} + +IPCCommandResult ES::AddTMD(const IOCtlVRequest& request) +{ + // This may appear to be very similar to AddTitleStart, but AddTitleStart takes + // three additional vectors and may do some additional processing -- so let's keep these separate. + + if (!request.HasNumberOfValidVectors(1, 0)) + return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT); + + std::vector tmd(request.in_vectors[0].size); + Memory::CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size); + + m_addtitle_tmd.SetBytes(tmd); + if (!m_addtitle_tmd.IsValid()) + return GetDefaultReply(ES_INVALID_TMD); + + if (!WriteTMD(m_addtitle_tmd)) + return GetDefaultReply(ES_WRITE_FAILURE); + + return GetDefaultReply(IPC_SUCCESS); +} + IPCCommandResult ES::AddTitleStart(const IOCtlVRequest& request) { _dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 4, @@ -386,13 +419,8 @@ IPCCommandResult ES::AddTitleStart(const IOCtlVRequest& request) return GetDefaultReply(ES_INVALID_TMD); } - // Write the TMD to title storage. - std::string tmd_path = - Common::GetTMDFileName(m_addtitle_tmd.GetTitleId(), Common::FROM_SESSION_ROOT); - File::CreateFullPath(tmd_path); - - File::IOFile fp(tmd_path, "wb"); - fp.WriteBytes(tmd.data(), tmd.size()); + if (!WriteTMD(m_addtitle_tmd)) + return GetDefaultReply(ES_WRITE_FAILURE); return GetDefaultReply(IPC_SUCCESS); } diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index 8c3326413b..30348749d5 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -153,6 +153,7 @@ private: }; IPCCommandResult AddTicket(const IOCtlVRequest& request); + IPCCommandResult AddTMD(const IOCtlVRequest& request); IPCCommandResult AddTitleStart(const IOCtlVRequest& request); IPCCommandResult AddContentStart(const IOCtlVRequest& request); IPCCommandResult AddContentData(const IOCtlVRequest& request);