From 33431cb93908daf66ad134826640e60907a78e92 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sun, 26 Apr 2020 20:33:24 +0100 Subject: [PATCH] pm/kext: make pm terminate Rosalina, removing the need for a dodgy kext hook --- k11_extension/include/ipc.h | 1 - k11_extension/source/ipc.c | 42 ---------------------- k11_extension/source/svc/SendSyncRequest.c | 19 +--------- sysmodules/pm/source/termination.c | 28 ++++++++++----- 4 files changed, 21 insertions(+), 69 deletions(-) diff --git a/k11_extension/include/ipc.h b/k11_extension/include/ipc.h index 57b6fcb..2ca055a 100644 --- a/k11_extension/include/ipc.h +++ b/k11_extension/include/ipc.h @@ -57,5 +57,4 @@ void SessionInfo_Add(KSession *session, const char *name); void SessionInfo_Remove(KSession *session); bool doLangEmu(Result *res, u32 *cmdbuf); -Result doPublishToProcessHook(Handle handle, u32 *cmdbuf); bool doErrfThrowHook(u32 *cmdbuf); diff --git a/k11_extension/source/ipc.c b/k11_extension/source/ipc.c index 11c02b9..5dfeb63 100644 --- a/k11_extension/source/ipc.c +++ b/k11_extension/source/ipc.c @@ -235,48 +235,6 @@ bool doLangEmu(Result *res, u32 *cmdbuf) return skip; } -Result doPublishToProcessHook(Handle handle, u32 *cmdbuf) -{ - Result res = 0; - u32 pid; - bool terminateRosalina = cmdbuf[1] == 0x100 && cmdbuf[2] == 0; // cmdbuf[2] to check for well-formed requests - u32 savedCmdbuf[4]; - memcpy(savedCmdbuf, cmdbuf, 16); - - if(!terminateRosalina || GetProcessId(&pid, cmdbuf[3]) != 0) - terminateRosalina = false; - else - { - KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess); - KProcess *process = KProcessHandleTable__ToKProcess(handleTable, cmdbuf[3]); - if((strcmp(codeSetOfProcess(process)->processName, "socket") == 0 && (rosalinaState & 2)) || - strcmp(codeSetOfProcess(process)->processName, "pxi") == 0) - terminateRosalina = true; - else - terminateRosalina = false; - ((KAutoObject *)process)->vtable->DecrementReferenceCount((KAutoObject *)process); - } - - if(terminateRosalina && nbSection0Modules == 6) - { - Handle rosalinaProcessHandle; - res = OpenProcess(&rosalinaProcessHandle, 5); - if(res == 0) - { - cmdbuf[0] = cmdbuf[0]; - cmdbuf[1] = 0x100; - cmdbuf[2] = 0; - cmdbuf[3] = rosalinaProcessHandle; - - res = SendSyncRequest(handle); - CloseHandle(rosalinaProcessHandle); - memcpy(cmdbuf, savedCmdbuf, 16); - } - } - - return SendSyncRequest(handle); -} - bool doErrfThrowHook(u32 *cmdbuf) { // If fatalErrorInfo->type is "card removed" or "logged", returning from ERRF:Throw is a no-op diff --git a/k11_extension/source/svc/SendSyncRequest.c b/k11_extension/source/svc/SendSyncRequest.c index dc0f9ef..74762f3 100644 --- a/k11_extension/source/svc/SendSyncRequest.c +++ b/k11_extension/source/svc/SendSyncRequest.c @@ -47,12 +47,7 @@ Result SendSyncRequestHook(Handle handle) case 0x10042: { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); - if(info != NULL && kernelVersion >= SYSTEM_VERSION(2, 39, 4) && strcmp(info->name, "srv:pm") == 0) - { - res = doPublishToProcessHook(handle, cmdbuf); - skip = true; - } - else if(info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce) + if(info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce) { cmdbuf[0] = 0x10040; cmdbuf[1] = 0; @@ -154,18 +149,6 @@ Result SendSyncRequestHook(Handle handle) break; } - case 0x4010042: - { - SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); - if(info != NULL && kernelVersion < SYSTEM_VERSION(2, 39, 4) && strcmp(info->name, "srv:pm") == 0) - { - res = doPublishToProcessHook(handle, cmdbuf); - skip = true; - } - - break; - } - case 0x4010082: { SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); diff --git a/sysmodules/pm/source/termination.c b/sysmodules/pm/source/termination.c index 6b9d027..993f9ce 100644 --- a/sysmodules/pm/source/termination.c +++ b/sysmodules/pm/source/termination.c @@ -65,6 +65,16 @@ static Result terminateProcessImpl(ProcessData *process, ExHeader_Info *exheader } } +static void terminateProcessByIdChecked(u32 pid) +{ + ProcessData *process = ProcessList_FindProcessById(&g_manager.processList, pid); + if (process != NULL) { + ProcessData_SendTerminationNotification(process); + } else { + panic(0LL); + } +} + static Result commitPendingTerminations(s64 timeout) { // Wait for all of the processes that have received notification 0x100 to terminate @@ -247,6 +257,8 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout) u64 dependencies[48]; u32 numDeps = 0; + s64 numKips = 0; + svcGetSystemInfo(&numKips, 26, 0); ExHeader_Info *exheaderInfo = ExHeaderInfoHeap_New(); @@ -269,6 +281,7 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout) } ProcessList_Lock(&g_manager.processList); + // Send notification 0x100 to the currently running application if (g_manager.runningApplicationData != NULL) { g_manager.runningApplicationData->flags &= ~PROCESSFLAG_DEPENDENCIES_LOADED; @@ -302,20 +315,19 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout) commitPendingTerminations(timeoutTicks >= 0 ? ticksToNs(timeoutTicks) : 0LL); g_manager.waitingForTermination = false; - // Now, send termination notification to PXI (PID 4) + // Now, send termination notification to PXI (PID 4). Also do the same for Rosalina. assertSuccess(svcClearEvent(g_manager.allNotifiedTerminationEvent)); g_manager.waitingForTermination = true; - ProcessList_Lock(&g_manager.processList); - process = ProcessList_FindProcessById(&g_manager.processList, 4); - if (process != NULL) { - ProcessData_SendTerminationNotification(process); - } else { - panic(0LL); + + if (numKips >= 6) { + terminateProcessByIdChecked(5); // Rosalina } + terminateProcessByIdChecked(4); // PXI + ProcessList_Unlock(&g_manager.processList); - // Allow 1.5 extra seconds for PXI (approx 402167783 ticks) + // Allow 1.5 extra seconds for PXI and Rosalina (approx 402167783 ticks) timeoutTicks = dstTimePoint - svcGetSystemTick(); commitPendingTerminations(1500 * 1000 * 1000LL + (timeoutTicks >= 0 ? ticksToNs(timeoutTicks) : 0LL)); g_manager.waitingForTermination = false;