IOS/ES: Implement ioctlv 0x25 (ES_LaunchBC)

This ioctlv is used to launch BC. Not sure if that's useful,
since only the system menu is known to launch BC and it does that
through a regular ES_LAUNCH; but let's implement it anyway.

(Implementation based on IOS59.)
This commit is contained in:
Léo Lam 2017-01-28 22:13:01 +01:00
parent ab38be1ee2
commit 9e6f5b203e
2 changed files with 53 additions and 28 deletions

View File

@ -317,6 +317,8 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
return Decrypt(request);
case IOCTL_ES_LAUNCH:
return Launch(request);
case IOCTL_ES_LAUNCHBC:
return LaunchBC(request);
case IOCTL_ES_CHECKKOREAREGION:
return CheckKoreaRegion(request);
case IOCTL_ES_GETDEVICECERT:
@ -1168,34 +1170,8 @@ IPCCommandResult ES::Launch(const IOCtlVRequest& request)
}
else
{
bool* wiiMoteConnected = new bool[MAX_BBMOTES];
if (!SConfig::GetInstance().m_bt_passthrough_enabled)
{
BluetoothEmu* s_Usb = GetUsbPointer();
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
}
Reload(ios_to_load);
ResetAfterLaunch(ios_to_load);
bReset = true;
if (!SConfig::GetInstance().m_bt_passthrough_enabled)
{
BluetoothEmu* s_Usb = GetUsbPointer();
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
{
if (wiiMoteConnected[i])
{
s_Usb->m_WiiMotes[i].Activate(false);
s_Usb->m_WiiMotes[i].Activate(true);
}
else
{
s_Usb->m_WiiMotes[i].Activate(false);
}
}
}
delete[] wiiMoteConnected;
SetDefaultContentFile(tContentFile);
}
@ -1223,6 +1199,52 @@ IPCCommandResult ES::Launch(const IOCtlVRequest& request)
return GetNoReply();
}
IPCCommandResult ES::LaunchBC(const IOCtlVRequest& request)
{
if (request.in_vectors.size() != 0 || request.io_vectors.size() != 0)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
// Here, IOS checks the clock speed and prevents ioctlv 0x25 from being used in GC mode.
// An alternative way to do this is to check whether the current active IOS is MIOS.
if (GetVersion() == 0x101)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
ResetAfterLaunch(0x00000001'00000100);
EnqueueCommandAcknowledgement(request.address, 0);
return GetNoReply();
}
void ES::ResetAfterLaunch(const u64 ios_to_load) const
{
bool* wiiMoteConnected = new bool[MAX_BBMOTES];
if (!SConfig::GetInstance().m_bt_passthrough_enabled)
{
BluetoothEmu* s_Usb = GetUsbPointer();
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
}
Reload(ios_to_load);
if (!SConfig::GetInstance().m_bt_passthrough_enabled)
{
BluetoothEmu* s_Usb = GetUsbPointer();
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
{
if (wiiMoteConnected[i])
{
s_Usb->m_WiiMotes[i].Activate(false);
s_Usb->m_WiiMotes[i].Activate(true);
}
else
{
s_Usb->m_WiiMotes[i].Activate(false);
}
}
}
delete[] wiiMoteConnected;
}
IPCCommandResult ES::CheckKoreaRegion(const IOCtlVRequest& request)
{
// note by DacoTaco : name is unknown, I just tried to name it SOMETHING.

View File

@ -90,7 +90,7 @@ private:
IOCTL_ES_DELETETITLECONTENT = 0x22,
IOCTL_ES_SEEKCONTENT = 0x23,
IOCTL_ES_OPENTITLECONTENT = 0x24,
// IOCTL_ES_LAUNCHBC = 0x25,
IOCTL_ES_LAUNCHBC = 0x25,
// IOCTL_ES_EXPORTTITLEINIT = 0x26,
// IOCTL_ES_EXPORTCONTENTBEGIN = 0x27,
// IOCTL_ES_EXPORTCONTENTDATA = 0x28,
@ -182,6 +182,7 @@ private:
IPCCommandResult Encrypt(const IOCtlVRequest& request);
IPCCommandResult Decrypt(const IOCtlVRequest& request);
IPCCommandResult Launch(const IOCtlVRequest& request);
IPCCommandResult LaunchBC(const IOCtlVRequest& request);
IPCCommandResult CheckKoreaRegion(const IOCtlVRequest& request);
IPCCommandResult GetDeviceCertificate(const IOCtlVRequest& request);
IPCCommandResult Sign(const IOCtlVRequest& request);
@ -189,6 +190,8 @@ private:
IPCCommandResult DIGetTicketView(const IOCtlVRequest& request);
IPCCommandResult GetOwnedTitleCount(const IOCtlVRequest& request);
void ResetAfterLaunch(u64 ios_to_load) const;
const DiscIO::CNANDContentLoader& AccessContentDevice(u64 title_id);
u32 OpenTitleContent(u32 CFD, u64 TitleID, u16 Index);