rosalina: implement dirty hb chainload
This commit is contained in:
@@ -33,4 +33,5 @@
|
||||
#define HBLDR_DEFAULT_3DSX_TID 0x000400000D921E00ULL
|
||||
#define HBLDR_3DSX_TID (*(vu64 *)0x1FF81100)
|
||||
|
||||
void HBLDR_RestartHbApplication(void *p);
|
||||
void HBLDR_HandleCommands(void *ctx);
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
#include <3ds/services/pmapp.h>
|
||||
#include <3ds/services/pmdbg.h>
|
||||
|
||||
Result PMDBG_GetCurrentAppTitleIdAndPid(u64 *outTitleId, u32 *outPid);
|
||||
/// Custom launch flags for PM launch commands.
|
||||
enum {
|
||||
PMLAUNCHFLAGEXT_FAKE_DEPENDENCY_LOADING = BIT(24),
|
||||
};
|
||||
|
||||
Result PMDBG_GetCurrentAppInfo(FS_ProgramInfo *outProgramInfo, u32 *outPid, u32 *outLaunchFlags);
|
||||
Result PMDBG_DebugNextApplicationByForce(bool debug);
|
||||
Result PMDBG_LaunchTitleDebug(Handle *outDebug, const FS_ProgramInfo *programInfo, u32 launchFlags);
|
||||
Result PMDBG_PrepareToChainloadHomebrew(u64 titleId);
|
||||
|
||||
@@ -178,6 +178,31 @@ static u16 *u16_strncpy(u16 *dest, const u16 *src, u32 size)
|
||||
return dest;
|
||||
}
|
||||
|
||||
void HBLDR_RestartHbApplication(void *p)
|
||||
{
|
||||
(void)p;
|
||||
// Don't crash if we fail
|
||||
|
||||
FS_ProgramInfo programInfo;
|
||||
u32 pid;
|
||||
u32 launchFlags;
|
||||
|
||||
Result res = PMDBG_GetCurrentAppInfo(&programInfo, &pid, &launchFlags);
|
||||
if (R_FAILED(res)) return;
|
||||
res = PMDBG_PrepareToChainloadHomebrew(programInfo.programId);
|
||||
if (R_FAILED(res)) return;
|
||||
res = PMAPP_TerminateCurrentApplication(3 * 1000 * 1000 *1000LL); // 3s, like what NS uses
|
||||
if (R_FAILED(res)) return;
|
||||
if (R_SUCCEEDED(res))
|
||||
{
|
||||
do
|
||||
{
|
||||
svcSleepThread(100 * 1000 * 1000LL);
|
||||
res = PMAPP_LaunchTitle(&programInfo, PMLAUNCHFLAGEXT_FAKE_DEPENDENCY_LOADING | launchFlags);
|
||||
} while (res == (Result)0xC8A05BF0);
|
||||
}
|
||||
}
|
||||
|
||||
void HBLDR_HandleCommands(void *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
|
||||
@@ -135,7 +135,7 @@ void initSystem(void)
|
||||
if (R_FAILED(stealFsReg()) || R_FAILED(fsRegSetupPermissions()) || R_FAILED(fsInit()))
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
|
||||
if (R_FAILED(pmDbgInit()))
|
||||
if (R_FAILED(pmAppInit()) || R_FAILED(pmDbgInit()))
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
|
||||
// **** DO NOT init services that don't come from KIPs here ****
|
||||
@@ -192,6 +192,12 @@ static void handleNextApplicationDebuggedByForce(u32 notificationId)
|
||||
TaskRunner_RunTask(debuggerFetchAndSetNextApplicationDebugHandleTask, NULL, 0);
|
||||
}
|
||||
|
||||
static void handleRestartHbAppNotification(u32 notificationId)
|
||||
{
|
||||
(void)notificationId;
|
||||
TaskRunner_RunTask(HBLDR_RestartHbApplication, NULL, 0);
|
||||
}
|
||||
|
||||
static const ServiceManagerServiceEntry services[] = {
|
||||
{ "hb:ldr", 2, HBLDR_HandleCommands, true },
|
||||
{ NULL },
|
||||
@@ -202,6 +208,7 @@ static const ServiceManagerNotificationEntry notifications[] = {
|
||||
//{ 0x103 , relinquishConnectionSessions }, // Sleep mode entry <=== causes issues
|
||||
{ 0x1000, handleNextApplicationDebuggedByForce },
|
||||
{ 0x2000, relinquishConnectionSessions },
|
||||
{ 0x3000, handleRestartHbAppNotification },
|
||||
{ 0x000, NULL },
|
||||
};
|
||||
|
||||
|
||||
@@ -1860,12 +1860,16 @@ static void Cheat_LoadCheatsIntoMemory(u64 titleId)
|
||||
|
||||
static u32 Cheat_GetCurrentProcessAndTitleId(u64* titleId)
|
||||
{
|
||||
FS_ProgramInfo programInfo;
|
||||
u32 pid;
|
||||
Result res = PMDBG_GetCurrentAppTitleIdAndPid(titleId, &pid);
|
||||
u32 launchFlags;
|
||||
Result res = PMDBG_GetCurrentAppInfo(&programInfo, &pid, &launchFlags);
|
||||
if (R_FAILED(res)) {
|
||||
*titleId = 0;
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
*titleId = programInfo.programId;
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,16 +52,17 @@ Menu miscellaneousMenu = {
|
||||
void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void)
|
||||
{
|
||||
Result res;
|
||||
u64 titleId = 0;
|
||||
char failureReason[64];
|
||||
|
||||
if(HBLDR_3DSX_TID == HBLDR_DEFAULT_3DSX_TID)
|
||||
{
|
||||
FS_ProgramInfo progInfo;
|
||||
u32 pid;
|
||||
res = PMDBG_GetCurrentAppTitleIdAndPid(&titleId, &pid);
|
||||
u32 launchFlags;
|
||||
res = PMDBG_GetCurrentAppInfo(&progInfo, &pid, &launchFlags);
|
||||
if(R_SUCCEEDED(res))
|
||||
{
|
||||
HBLDR_3DSX_TID = titleId;
|
||||
HBLDR_3DSX_TID = progInfo.programId;
|
||||
miscellaneousMenu.items[0].title = "Switch the hb. title to hblauncher_loader";
|
||||
}
|
||||
else
|
||||
|
||||
@@ -10,15 +10,16 @@
|
||||
#include <3ds/services/pmdbg.h>
|
||||
#include <3ds/ipc.h>
|
||||
|
||||
Result PMDBG_GetCurrentAppTitleIdAndPid(u64 *outTitleId, u32 *outPid)
|
||||
Result PMDBG_GetCurrentAppInfo(FS_ProgramInfo *outProgramInfo, u32 *outPid, u32 *outLaunchFlags)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
cmdbuf[0] = IPC_MakeHeader(0x100, 0, 0);
|
||||
if(R_FAILED(ret = svcSendSyncRequest(*pmDbgGetSessionHandle()))) return ret;
|
||||
|
||||
memcpy(outTitleId, cmdbuf + 2, 8);
|
||||
*outPid = cmdbuf[4];
|
||||
memcpy(outProgramInfo, cmdbuf + 2, sizeof(FS_ProgramInfo));
|
||||
*outPid = cmdbuf[6];
|
||||
*outLaunchFlags = cmdbuf[7];
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
@@ -47,3 +48,16 @@ Result PMDBG_LaunchTitleDebug(Handle *outDebug, const FS_ProgramInfo *programInf
|
||||
*outDebug = cmdbuf[3];
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMDBG_PrepareToChainloadHomebrew(u64 titleId)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x103, 2, 0);
|
||||
memcpy(&cmdbuf[1], &titleId, 8);
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(*pmDbgGetSessionHandle()))) return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user