From 9e6f5b203ed6ce999f23d96978bbbc3a72ffeb57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 28 Jan 2017 22:13:01 +0100 Subject: [PATCH] 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.) --- Source/Core/Core/IOS/ES/ES.cpp | 76 ++++++++++++++++++++++------------ Source/Core/Core/IOS/ES/ES.h | 5 ++- 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index f956d0824a..2a7eb870b9 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -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. diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index 83acd77865..2fbce4d7f1 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -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);