pm/kext: make pm terminate Rosalina, removing the need for a dodgy kext hook
This commit is contained in:
parent
e677e0142c
commit
33431cb939
@ -57,5 +57,4 @@ void SessionInfo_Add(KSession *session, const char *name);
|
|||||||
void SessionInfo_Remove(KSession *session);
|
void SessionInfo_Remove(KSession *session);
|
||||||
|
|
||||||
bool doLangEmu(Result *res, u32 *cmdbuf);
|
bool doLangEmu(Result *res, u32 *cmdbuf);
|
||||||
Result doPublishToProcessHook(Handle handle, u32 *cmdbuf);
|
|
||||||
bool doErrfThrowHook(u32 *cmdbuf);
|
bool doErrfThrowHook(u32 *cmdbuf);
|
||||||
|
@ -235,48 +235,6 @@ bool doLangEmu(Result *res, u32 *cmdbuf)
|
|||||||
return skip;
|
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)
|
bool doErrfThrowHook(u32 *cmdbuf)
|
||||||
{
|
{
|
||||||
// If fatalErrorInfo->type is "card removed" or "logged", returning from ERRF:Throw is a no-op
|
// If fatalErrorInfo->type is "card removed" or "logged", returning from ERRF:Throw is a no-op
|
||||||
|
@ -47,12 +47,7 @@ Result SendSyncRequestHook(Handle handle)
|
|||||||
case 0x10042:
|
case 0x10042:
|
||||||
{
|
{
|
||||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||||
if(info != NULL && kernelVersion >= SYSTEM_VERSION(2, 39, 4) && strcmp(info->name, "srv:pm") == 0)
|
if(info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce)
|
||||||
{
|
|
||||||
res = doPublishToProcessHook(handle, cmdbuf);
|
|
||||||
skip = true;
|
|
||||||
}
|
|
||||||
else if(info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce)
|
|
||||||
{
|
{
|
||||||
cmdbuf[0] = 0x10040;
|
cmdbuf[0] = 0x10040;
|
||||||
cmdbuf[1] = 0;
|
cmdbuf[1] = 0;
|
||||||
@ -154,18 +149,6 @@ Result SendSyncRequestHook(Handle handle)
|
|||||||
break;
|
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:
|
case 0x4010082:
|
||||||
{
|
{
|
||||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||||
|
@ -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)
|
static Result commitPendingTerminations(s64 timeout)
|
||||||
{
|
{
|
||||||
// Wait for all of the processes that have received notification 0x100 to terminate
|
// 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];
|
u64 dependencies[48];
|
||||||
u32 numDeps = 0;
|
u32 numDeps = 0;
|
||||||
|
s64 numKips = 0;
|
||||||
|
svcGetSystemInfo(&numKips, 26, 0);
|
||||||
|
|
||||||
ExHeader_Info *exheaderInfo = ExHeaderInfoHeap_New();
|
ExHeader_Info *exheaderInfo = ExHeaderInfoHeap_New();
|
||||||
|
|
||||||
@ -269,6 +281,7 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProcessList_Lock(&g_manager.processList);
|
ProcessList_Lock(&g_manager.processList);
|
||||||
|
|
||||||
// Send notification 0x100 to the currently running application
|
// Send notification 0x100 to the currently running application
|
||||||
if (g_manager.runningApplicationData != NULL) {
|
if (g_manager.runningApplicationData != NULL) {
|
||||||
g_manager.runningApplicationData->flags &= ~PROCESSFLAG_DEPENDENCIES_LOADED;
|
g_manager.runningApplicationData->flags &= ~PROCESSFLAG_DEPENDENCIES_LOADED;
|
||||||
@ -302,20 +315,19 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout)
|
|||||||
commitPendingTerminations(timeoutTicks >= 0 ? ticksToNs(timeoutTicks) : 0LL);
|
commitPendingTerminations(timeoutTicks >= 0 ? ticksToNs(timeoutTicks) : 0LL);
|
||||||
g_manager.waitingForTermination = false;
|
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));
|
assertSuccess(svcClearEvent(g_manager.allNotifiedTerminationEvent));
|
||||||
g_manager.waitingForTermination = true;
|
g_manager.waitingForTermination = true;
|
||||||
|
|
||||||
ProcessList_Lock(&g_manager.processList);
|
ProcessList_Lock(&g_manager.processList);
|
||||||
process = ProcessList_FindProcessById(&g_manager.processList, 4);
|
|
||||||
if (process != NULL) {
|
if (numKips >= 6) {
|
||||||
ProcessData_SendTerminationNotification(process);
|
terminateProcessByIdChecked(5); // Rosalina
|
||||||
} else {
|
|
||||||
panic(0LL);
|
|
||||||
}
|
}
|
||||||
|
terminateProcessByIdChecked(4); // PXI
|
||||||
|
|
||||||
ProcessList_Unlock(&g_manager.processList);
|
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();
|
timeoutTicks = dstTimePoint - svcGetSystemTick();
|
||||||
commitPendingTerminations(1500 * 1000 * 1000LL + (timeoutTicks >= 0 ? ticksToNs(timeoutTicks) : 0LL));
|
commitPendingTerminations(1500 * 1000 * 1000LL + (timeoutTicks >= 0 ? ticksToNs(timeoutTicks) : 0LL));
|
||||||
g_manager.waitingForTermination = false;
|
g_manager.waitingForTermination = false;
|
||||||
|
Reference in New Issue
Block a user