Merge pull request #4743 from lioncash/es

ES: Separate IOCtlV code out into constituent functions
This commit is contained in:
Mat M 2017-01-28 15:33:34 -05:00 committed by GitHub
commit 66160c2781
2 changed files with 1044 additions and 930 deletions

View File

@ -249,15 +249,101 @@ u32 ES::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index)
IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
{
DEBUG_LOG(IOS_ES, "%s (0x%x)", GetDeviceName().c_str(), request.request);
// Clear the IO buffers. Note that this is unsafe for other ioctlvs.
for (const auto& io_vector : request.io_vectors)
{
if (!request.HasInputVectorWithAddress(io_vector.address))
Memory::Memset(io_vector.address, 0, io_vector.size);
}
switch (request.request)
{
case IOCTL_ES_ADDTICKET:
return AddTicket(request);
case IOCTL_ES_ADDTITLESTART:
return AddTitleStart(request);
case IOCTL_ES_ADDCONTENTSTART:
return AddContentStart(request);
case IOCTL_ES_ADDCONTENTDATA:
return AddContentData(request);
case IOCTL_ES_ADDCONTENTFINISH:
return AddContentFinish(request);
case IOCTL_ES_ADDTITLEFINISH:
return AddTitleFinish(request);
case IOCTL_ES_GETDEVICEID:
return ESGetDeviceID(request);
case IOCTL_ES_GETTITLECONTENTSCNT:
return GetTitleContentsCount(request);
case IOCTL_ES_GETTITLECONTENTS:
return GetTitleContents(request);
case IOCTL_ES_OPENTITLECONTENT:
return OpenTitleContent(request);
case IOCTL_ES_OPENCONTENT:
return OpenContent(request);
case IOCTL_ES_READCONTENT:
return ReadContent(request);
case IOCTL_ES_CLOSECONTENT:
return CloseContent(request);
case IOCTL_ES_SEEKCONTENT:
return SeekContent(request);
case IOCTL_ES_GETTITLEDIR:
return GetTitleDirectory(request);
case IOCTL_ES_GETTITLEID:
return GetTitleID(request);
case IOCTL_ES_SETUID:
return SetUID(request);
case IOCTL_ES_GETTITLECNT:
return GetTitleCount(request);
case IOCTL_ES_GETTITLES:
return GetTitles(request);
case IOCTL_ES_GETVIEWCNT:
return GetViewCount(request);
case IOCTL_ES_GETVIEWS:
return GetViews(request);
case IOCTL_ES_GETTMDVIEWCNT:
return GetTMDViewCount(request);
case IOCTL_ES_GETTMDVIEWS:
return GetTMDViews(request);
case IOCTL_ES_GETCONSUMPTION:
return GetConsumption(request);
case IOCTL_ES_DELETETICKET:
return DeleteTicket(request);
case IOCTL_ES_DELETETITLECONTENT:
return DeleteTitleContent(request);
case IOCTL_ES_GETSTOREDTMDSIZE:
return GetStoredTMDSize(request);
case IOCTL_ES_GETSTOREDTMD:
return GetStoredTMD(request);
case IOCTL_ES_ENCRYPT:
return Encrypt(request);
case IOCTL_ES_DECRYPT:
return Decrypt(request);
case IOCTL_ES_LAUNCH:
return Launch(request);
case IOCTL_ES_CHECKKOREAREGION:
return CheckKoreaRegion(request);
case IOCTL_ES_GETDEVICECERT:
return GetDeviceCertificate(request);
case IOCTL_ES_SIGN:
return Sign(request);
case IOCTL_ES_GETBOOT2VERSION:
return GetBoot2Version(request);
// Unsupported functions
case IOCTL_ES_DIGETTICKETVIEW:
return DIGetTicketView(request);
case IOCTL_ES_GETOWNEDTITLECNT:
return GetOwnedTitleCount(request);
default:
request.DumpUnknown(GetDeviceName(), LogTypes::IOS);
break;
}
return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult ES::AddTicket(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 3,
"IOCTL_ES_ADDTICKET wrong number of inputs");
@ -266,10 +352,11 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
std::vector<u8> ticket(request.in_vectors[0].size);
Memory::CopyFromEmu(ticket.data(), request.in_vectors[0].address, request.in_vectors[0].size);
DiscIO::AddTicket(ticket);
break;
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_ADDTITLESTART:
IPCCommandResult ES::AddTitleStart(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 4,
"IOCTL_ES_ADDTITLESTART wrong number of inputs");
@ -292,10 +379,11 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
File::IOFile fp(tmd_path, "wb");
fp.WriteBytes(tmd.data(), tmd.size());
break;
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_ADDCONTENTSTART:
IPCCommandResult ES::AddContentStart(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 2,
"IOCTL_ES_ADDCONTENTSTART wrong number of inputs");
@ -332,7 +420,7 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(content_fd);
}
case IOCTL_ES_ADDCONTENTDATA:
IPCCommandResult ES::AddContentData(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 2,
"IOCTL_ES_ADDCONTENTDATA wrong number of inputs");
@ -345,10 +433,10 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
u8* data_start = Memory::GetPointer(request.in_vectors[1].address);
u8* data_end = data_start + request.in_vectors[1].size;
m_addtitle_content_buffer.insert(m_addtitle_content_buffer.end(), data_start, data_end);
break;
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_ADDCONTENTFINISH:
IPCCommandResult ES::AddContentFinish(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 1,
"IOCTL_ES_ADDCONTENTFINISH wrong number of inputs");
@ -389,16 +477,16 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
fp.WriteBytes(decrypted_data.data(), decrypted_data.size());
m_addtitle_content_id = 0xFFFFFFFF;
break;
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_ADDTITLEFINISH:
IPCCommandResult ES::AddTitleFinish(const IOCtlVRequest& request)
{
INFO_LOG(IOS_ES, "IOCTL_ES_ADDTITLEFINISH");
break;
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_GETDEVICEID:
IPCCommandResult ES::ESGetDeviceID(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETDEVICEID no io vectors");
@ -408,7 +496,7 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_GETTITLECONTENTSCNT:
IPCCommandResult ES::GetTitleContentsCount(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 1);
_dbg_assert_(IOS_ES, request.io_vectors.size() == 1);
@ -438,9 +526,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(return_value);
}
break;
case IOCTL_ES_GETTITLECONTENTS:
IPCCommandResult ES::GetTitleContents(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 2,
"IOCTL_ES_GETTITLECONTENTS bad in buffer");
@ -470,9 +557,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(return_value);
}
break;
case IOCTL_ES_OPENTITLECONTENT:
IPCCommandResult ES::OpenTitleContent(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 3);
_dbg_assert_(IOS_ES, request.io_vectors.size() == 0);
@ -487,9 +573,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(CFD);
}
break;
case IOCTL_ES_OPENCONTENT:
IPCCommandResult ES::OpenContent(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 1);
_dbg_assert_(IOS_ES, request.io_vectors.size() == 0);
@ -500,9 +585,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(CFD);
}
break;
case IOCTL_ES_READCONTENT:
IPCCommandResult ES::ReadContent(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 1);
_dbg_assert_(IOS_ES, request.io_vectors.size() == 1);
@ -547,14 +631,13 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
}
DEBUG_LOG(IOS_ES,
"IOCTL_ES_READCONTENT: CFD %x, Address 0x%x, Size %i -> stream pos %i (Index %i)",
CFD, Addr, Size, rContent.m_Position, rContent.m_Index);
"IOCTL_ES_READCONTENT: CFD %x, Address 0x%x, Size %i -> stream pos %i (Index %i)", CFD,
Addr, Size, rContent.m_Position, rContent.m_Index);
return GetDefaultReply(Size);
}
break;
case IOCTL_ES_CLOSECONTENT:
IPCCommandResult ES::CloseContent(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 1);
_dbg_assert_(IOS_ES, request.io_vectors.size() == 0);
@ -581,9 +664,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_SEEKCONTENT:
IPCCommandResult ES::SeekContent(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 3);
_dbg_assert_(IOS_ES, request.io_vectors.size() == 0);
@ -619,9 +701,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(rContent.m_Position);
}
break;
case IOCTL_ES_GETTITLEDIR:
IPCCommandResult ES::GetTitleDirectory(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 1);
_dbg_assert_(IOS_ES, request.io_vectors.size() == 1);
@ -632,34 +713,34 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
sprintf(Path, "/title/%08x/%08x/data", (u32)(TitleID >> 32), (u32)TitleID);
INFO_LOG(IOS_ES, "IOCTL_ES_GETTITLEDIR: %s", Path);
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_GETTITLEID:
IPCCommandResult ES::GetTitleID(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 0);
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLEID no out buffer");
Memory::Write_U64(m_TitleID, request.io_vectors[0].address);
INFO_LOG(IOS_ES, "IOCTL_ES_GETTITLEID: %08x/%08x", (u32)(m_TitleID >> 32), (u32)m_TitleID);
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_SETUID:
IPCCommandResult ES::SetUID(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 1, "IOCTL_ES_SETUID no in buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 0,
"IOCTL_ES_SETUID has a payload, it shouldn't");
// TODO: fs permissions based on this
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
INFO_LOG(IOS_ES, "IOCTL_ES_SETUID titleID: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID);
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_GETTITLECNT:
IPCCommandResult ES::GetTitleCount(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 0,
"IOCTL_ES_GETTITLECNT has an in buffer");
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 0, "IOCTL_ES_GETTITLECNT has an in buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1,
"IOCTL_ES_GETTITLECNT has no out buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors[0].size == 4,
@ -671,13 +752,11 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_GETTITLES:
IPCCommandResult ES::GetTitles(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 1, "IOCTL_ES_GETTITLES has an in buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1,
"IOCTL_ES_GETTITLES has no out buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTITLES has no out buffer");
u32 MaxCount = Memory::Read_U32(request.in_vectors[0].address);
u32 Count = 0;
@ -694,9 +773,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
INFO_LOG(IOS_ES, "IOCTL_ES_GETTITLES: Number of titles returned %i", Count);
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_GETVIEWCNT:
IPCCommandResult ES::GetViewCount(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 1, "IOCTL_ES_GETVIEWCNT no in buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETVIEWCNT no out buffer");
@ -744,9 +822,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
Memory::Write_U32(ViewCount, request.io_vectors[0].address);
return GetDefaultReply(retVal);
}
break;
case IOCTL_ES_GETVIEWS:
IPCCommandResult ES::GetViews(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 2, "IOCTL_ES_GETVIEWS no in buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETVIEWS no out buffer");
@ -811,18 +888,16 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
}
}
INFO_LOG(IOS_ES, "IOCTL_ES_GETVIEWS for titleID: %08x/%08x (MaxViews = %i)",
(u32)(TitleID >> 32), (u32)TitleID, maxViews);
INFO_LOG(IOS_ES, "IOCTL_ES_GETVIEWS for titleID: %08x/%08x (MaxViews = %i)", (u32)(TitleID >> 32),
(u32)TitleID, maxViews);
return GetDefaultReply(retVal);
}
break;
case IOCTL_ES_GETTMDVIEWCNT:
IPCCommandResult ES::GetTMDViewCount(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 1, "IOCTL_ES_GETTMDVIEWCNT no in buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1,
"IOCTL_ES_GETTMDVIEWCNT no out buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTMDVIEWCNT no out buffer");
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
@ -834,22 +909,19 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
TMDViewCnt += DiscIO::CNANDContentLoader::TMD_VIEW_SIZE;
TMDViewCnt += 2; // title version
TMDViewCnt += 2; // num entries
TMDViewCnt +=
(u32)Loader.GetContentSize() * (4 + 2 + 2 + 8); // content id, index, type, size
TMDViewCnt += (u32)Loader.GetContentSize() * (4 + 2 + 2 + 8); // content id, index, type, size
}
Memory::Write_U32(TMDViewCnt, request.io_vectors[0].address);
INFO_LOG(IOS_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x (view size %i)",
(u32)(TitleID >> 32), (u32)TitleID, TMDViewCnt);
INFO_LOG(IOS_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32),
(u32)TitleID, TMDViewCnt);
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_GETTMDVIEWS:
IPCCommandResult ES::GetTMDViews(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 2, "IOCTL_ES_GETTMDVIEWCNT no in buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1,
"IOCTL_ES_GETTMDVIEWCNT no out buffer");
_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETTMDVIEWCNT no out buffer");
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address);
@ -887,44 +959,50 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
_dbg_assert_(IOS_ES, (Address - request.io_vectors[0].address) == request.io_vectors[0].size);
}
INFO_LOG(IOS_ES, "IOCTL_ES_GETTMDVIEWS: title: %08x/%08x (buffer size: %i)",
(u32)(TitleID >> 32), (u32)TitleID, MaxCount);
INFO_LOG(IOS_ES, "IOCTL_ES_GETTMDVIEWS: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32),
(u32)TitleID, MaxCount);
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_GETCONSUMPTION: // This is at least what crediar's ES module does
IPCCommandResult ES::GetConsumption(const IOCtlVRequest& request)
{
// This is at least what crediar's ES module does
Memory::Write_U32(0, request.io_vectors[1].address);
INFO_LOG(IOS_ES, "IOCTL_ES_GETCONSUMPTION");
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_DELETETICKET:
IPCCommandResult ES::DeleteTicket(const IOCtlVRequest& request)
{
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
INFO_LOG(IOS_ES, "IOCTL_ES_DELETETICKET: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID);
// Presumably return -1017 when delete fails
if (!File::Delete(Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT)))
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_DELETETITLECONTENT:
IPCCommandResult ES::DeleteTitleContent(const IOCtlVRequest& request)
{
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
INFO_LOG(IOS_ES, "IOCTL_ES_DELETETITLECONTENT: title: %08x/%08x", (u32)(TitleID >> 32),
(u32)TitleID);
// Presumably return -1017 when title not installed TODO verify
if (!DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID, Common::FROM_SESSION_ROOT))
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_GETSTOREDTMDSIZE:
IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() == 1,
"IOCTL_ES_GETSTOREDTMDSIZE no in buffer");
// _dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_ES_GETSTOREDTMDSIZE
// no out buffer");
// _dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1,
// "IOCTL_ES_ES_GETSTOREDTMDSIZE no out buffer");
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID);
@ -936,22 +1014,24 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
TMDCnt += DiscIO::CNANDContentLoader::TMD_HEADER_SIZE;
TMDCnt += (u32)Loader.GetContentSize() * DiscIO::CNANDContentLoader::CONTENT_HEADER_SIZE;
}
if (request.io_vectors.size())
Memory::Write_U32(TMDCnt, request.io_vectors[0].address);
INFO_LOG(IOS_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)",
(u32)(TitleID >> 32), (u32)TitleID, TMDCnt);
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_GETSTOREDTMD:
IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request)
{
_dbg_assert_msg_(IOS_ES, request.in_vectors.size() > 0, "IOCTL_ES_GETSTOREDTMD no in buffer");
// requires 1 inbuffer and no outbuffer, presumably outbuffer required when second inbuffer is
// used for maxcount (allocated mem?)
// called with 1 inbuffer after deleting a titleid
//_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1, "IOCTL_ES_GETSTOREDTMD no out
// buffer");
//_dbg_assert_msg_(IOS_ES, request.io_vectors.size() == 1,
// "IOCTL_ES_GETSTOREDTMD no out buffer");
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
u32 MaxCount = 0;
@ -969,8 +1049,7 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
{
u32 Address = request.io_vectors[0].address;
Memory::CopyToEmu(Address, Loader.GetTMDHeader(),
DiscIO::CNANDContentLoader::TMD_HEADER_SIZE);
Memory::CopyToEmu(Address, Loader.GetTMDHeader(), DiscIO::CNANDContentLoader::TMD_HEADER_SIZE);
Address += DiscIO::CNANDContentLoader::TMD_HEADER_SIZE;
const std::vector<DiscIO::SNANDContent>& rContent = Loader.GetContent();
@ -988,9 +1067,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
(u32)(TitleID >> 32), (u32)TitleID, MaxCount);
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_ENCRYPT:
IPCCommandResult ES::Encrypt(const IOCtlVRequest& request)
{
u32 keyIndex = Memory::Read_U32(request.in_vectors[0].address);
u8* IV = Memory::GetPointer(request.in_vectors[1].address);
@ -1006,10 +1084,10 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
_dbg_assert_msg_(IOS_ES, keyIndex == 6,
"IOCTL_ES_ENCRYPT: Key type is not SD, data will be crap");
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_DECRYPT:
IPCCommandResult ES::Decrypt(const IOCtlVRequest& request)
{
u32 keyIndex = Memory::Read_U32(request.in_vectors[0].address);
u8* IV = Memory::GetPointer(request.in_vectors[1].address);
@ -1022,10 +1100,10 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
_dbg_assert_msg_(IOS_ES, keyIndex == 6,
"IOCTL_ES_DECRYPT: Key type is not SD, data will be crap");
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_LAUNCH:
IPCCommandResult ES::Launch(const IOCtlVRequest& request)
{
_dbg_assert_(IOS_ES, request.in_vectors.size() == 2);
bool bSuccess = false;
@ -1150,28 +1228,30 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
EnqueueCommandAcknowledgement(request.address, 0);
return GetNoReply();
}
break;
case IOCTL_ES_CHECKKOREAREGION: // note by DacoTaco : name is unknown, i just tried to name it
// SOMETHING
IPCCommandResult ES::CheckKoreaRegion(const IOCtlVRequest& request)
{
// note by DacoTaco : name is unknown, I just tried to name it SOMETHING.
// IOS70 has this to let system menu 4.2 check if the console is region changed. it returns
// -1017
// if the IOS didn't find the Korean keys and 0 if it does. 0 leads to a error 003
INFO_LOG(IOS_ES, "IOCTL_ES_CHECKKOREAREGION: Title checked for Korean keys.");
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
}
case IOCTL_ES_GETDEVICECERT: // (Input: none, Output: 384 bytes)
IPCCommandResult ES::GetDeviceCertificate(const IOCtlVRequest& request)
{
// (Input: none, Output: 384 bytes)
INFO_LOG(IOS_ES, "IOCTL_ES_GETDEVICECERT");
_dbg_assert_(IOS_ES, request.io_vectors.size() == 1);
u8* destination = Memory::GetPointer(request.io_vectors[0].address);
EcWii& ec = EcWii::GetInstance();
get_ng_cert(destination, ec.getNgId(), ec.getNgKeyId(), ec.getNgPriv(), ec.getNgSig());
return GetDefaultReply(IPC_SUCCESS);
}
break;
case IOCTL_ES_SIGN:
IPCCommandResult ES::Sign(const IOCtlVRequest& request)
{
INFO_LOG(IOS_ES, "IOCTL_ES_SIGN");
u8* ap_cert_out = Memory::GetPointer(request.io_vectors[1].address);
@ -1182,34 +1262,30 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
EcWii& ec = EcWii::GetInstance();
get_ap_sig_and_cert(sig_out, ap_cert_out, m_TitleID, data, data_size, ec.getNgPriv(),
ec.getNgId());
}
break;
case IOCTL_ES_GETBOOT2VERSION:
return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult ES::GetBoot2Version(const IOCtlVRequest& request)
{
INFO_LOG(IOS_ES, "IOCTL_ES_GETBOOT2VERSION");
Memory::Write_U32(
4, request.io_vectors[0].address); // as of 26/02/2012, this was latest bootmii version
// as of 26/02/2012, this was latest bootmii version
Memory::Write_U32(4, request.io_vectors[0].address);
return GetDefaultReply(IPC_SUCCESS);
}
break;
// ===============================================================================================
// unsupported functions
// ===============================================================================================
case IOCTL_ES_DIGETTICKETVIEW: // (Input: none, Output: 216 bytes) bug crediar :D
IPCCommandResult ES::DIGetTicketView(const IOCtlVRequest& request)
{
// (Input: none, Output: 216 bytes) bug crediar :D
WARN_LOG(IOS_ES, "IOCTL_ES_DIGETTICKETVIEW: this looks really wrong...");
break;
return GetDefaultReply(IPC_SUCCESS);
}
case IOCTL_ES_GETOWNEDTITLECNT:
IPCCommandResult ES::GetOwnedTitleCount(const IOCtlVRequest& request)
{
INFO_LOG(IOS_ES, "IOCTL_ES_GETOWNEDTITLECNT");
Memory::Write_U32(0, request.io_vectors[0].address);
break;
default:
request.DumpUnknown(GetDeviceName(), LogTypes::IOS);
}
return GetDefaultReply(IPC_SUCCESS);
}

View File

@ -138,21 +138,6 @@ private:
u32 m_Size;
};
typedef std::map<u32, SContentAccess> CContentAccessMap;
CContentAccessMap m_ContentAccessMap;
std::vector<u64> m_TitleIDs;
u64 m_TitleID = -1;
u32 m_AccessIdentID = 0x6000000;
// For title installation (ioctls IOCTL_ES_ADDTITLE*).
TMDReader m_addtitle_tmd;
u32 m_addtitle_content_id = 0xFFFFFFFF;
std::vector<u8> m_addtitle_content_buffer;
const DiscIO::CNANDContentLoader& AccessContentDevice(u64 title_id);
u32 OpenTitleContent(u32 CFD, u64 TitleID, u16 Index);
struct ecc_cert_t
{
u32 sig_type;
@ -165,6 +150,59 @@ private:
u8 ecc_pubkey[0x3c];
u8 padding[0x3c];
};
IPCCommandResult AddTicket(const IOCtlVRequest& request);
IPCCommandResult AddTitleStart(const IOCtlVRequest& request);
IPCCommandResult AddContentStart(const IOCtlVRequest& request);
IPCCommandResult AddContentData(const IOCtlVRequest& request);
IPCCommandResult AddContentFinish(const IOCtlVRequest& request);
IPCCommandResult AddTitleFinish(const IOCtlVRequest& request);
IPCCommandResult ESGetDeviceID(const IOCtlVRequest& request);
IPCCommandResult GetTitleContentsCount(const IOCtlVRequest& request);
IPCCommandResult GetTitleContents(const IOCtlVRequest& request);
IPCCommandResult OpenTitleContent(const IOCtlVRequest& request);
IPCCommandResult OpenContent(const IOCtlVRequest& request);
IPCCommandResult ReadContent(const IOCtlVRequest& request);
IPCCommandResult CloseContent(const IOCtlVRequest& request);
IPCCommandResult SeekContent(const IOCtlVRequest& request);
IPCCommandResult GetTitleDirectory(const IOCtlVRequest& request);
IPCCommandResult GetTitleID(const IOCtlVRequest& request);
IPCCommandResult SetUID(const IOCtlVRequest& request);
IPCCommandResult GetTitleCount(const IOCtlVRequest& request);
IPCCommandResult GetTitles(const IOCtlVRequest& request);
IPCCommandResult GetViewCount(const IOCtlVRequest& request);
IPCCommandResult GetViews(const IOCtlVRequest& request);
IPCCommandResult GetTMDViewCount(const IOCtlVRequest& request);
IPCCommandResult GetTMDViews(const IOCtlVRequest& request);
IPCCommandResult GetConsumption(const IOCtlVRequest& request);
IPCCommandResult DeleteTicket(const IOCtlVRequest& request);
IPCCommandResult DeleteTitleContent(const IOCtlVRequest& request);
IPCCommandResult GetStoredTMDSize(const IOCtlVRequest& request);
IPCCommandResult GetStoredTMD(const IOCtlVRequest& request);
IPCCommandResult Encrypt(const IOCtlVRequest& request);
IPCCommandResult Decrypt(const IOCtlVRequest& request);
IPCCommandResult Launch(const IOCtlVRequest& request);
IPCCommandResult CheckKoreaRegion(const IOCtlVRequest& request);
IPCCommandResult GetDeviceCertificate(const IOCtlVRequest& request);
IPCCommandResult Sign(const IOCtlVRequest& request);
IPCCommandResult GetBoot2Version(const IOCtlVRequest& request);
IPCCommandResult DIGetTicketView(const IOCtlVRequest& request);
IPCCommandResult GetOwnedTitleCount(const IOCtlVRequest& request);
const DiscIO::CNANDContentLoader& AccessContentDevice(u64 title_id);
u32 OpenTitleContent(u32 CFD, u64 TitleID, u16 Index);
using CContentAccessMap = std::map<u32, SContentAccess>;
CContentAccessMap m_ContentAccessMap;
std::vector<u64> m_TitleIDs;
u64 m_TitleID = -1;
u32 m_AccessIdentID = 0x6000000;
// For title installation (ioctls IOCTL_ES_ADDTITLE*).
TMDReader m_addtitle_tmd;
u32 m_addtitle_content_id = 0xFFFFFFFF;
std::vector<u8> m_addtitle_content_buffer;
};
} // namespace Device
} // namespace HLE