diff --git a/sysmodules/pm/source/termination.c b/sysmodules/pm/source/termination.c index 98d34aa..73d0d6d 100644 --- a/sysmodules/pm/source/termination.c +++ b/sysmodules/pm/source/termination.c @@ -311,6 +311,11 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout) ProcessList_Lock(&g_manager.processList); + // Send custom notification to at least Rosalina to make it relinquish some non-KIP services handles, stop the debugger, etc. + if (numKips >= 6) { + notifySubscribers(0x1001); + } + // Send notification 0x100 to the currently running application if (g_manager.runningApplicationData != NULL) { g_manager.runningApplicationData->flags &= ~PROCESSFLAG_DEPENDENCIES_LOADED; diff --git a/sysmodules/rosalina/include/input_redirection.h b/sysmodules/rosalina/include/input_redirection.h index e33e436..253c2bf 100644 --- a/sysmodules/rosalina/include/input_redirection.h +++ b/sysmodules/rosalina/include/input_redirection.h @@ -36,4 +36,5 @@ extern int inputRedirectionStartResult; MyThread *inputRedirectionCreateThread(void); void inputRedirectionThreadMain(void); +Result InputRedirection_Disable(s64 timeout); Result InputRedirection_DoOrUndoPatches(void); diff --git a/sysmodules/rosalina/include/menus/debugger.h b/sysmodules/rosalina/include/menus/debugger.h index 55e4c67..4dec5fe 100644 --- a/sysmodules/rosalina/include/menus/debugger.h +++ b/sysmodules/rosalina/include/menus/debugger.h @@ -32,6 +32,8 @@ extern Menu debuggerMenu; void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata); +Result debuggerDisable(s64 timeout); + void DebuggerMenu_EnableDebugger(void); void DebuggerMenu_DisableDebugger(void); void DebuggerMenu_DebugNextApplicationByForce(void); diff --git a/sysmodules/rosalina/include/minisoc.h b/sysmodules/rosalina/include/minisoc.h index efa564a..6040bc8 100644 --- a/sysmodules/rosalina/include/minisoc.h +++ b/sysmodules/rosalina/include/minisoc.h @@ -18,13 +18,10 @@ #include #define SYNC_ERROR ENODEV - -extern Handle SOCU_handle; -extern Handle socMemhandle; - extern bool miniSocEnabled; -Result miniSocInit(); +Result miniSocInit(void); +Result miniSocExitDirect(void); Result miniSocExit(void); s32 _net_convert_error(s32 sock_retval); diff --git a/sysmodules/rosalina/source/input_redirection.c b/sysmodules/rosalina/source/input_redirection.c index 77cf736..852b4c4 100644 --- a/sysmodules/rosalina/source/input_redirection.c +++ b/sysmodules/rosalina/source/input_redirection.c @@ -159,14 +159,30 @@ void inputRedirectionThreadMain(void) linger.l_linger = 0; socSetsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(struct linger)); - socClose(sock); + miniSocExit(); } void hidCodePatchFunc(void); void irCodePatchFunc(void); +Result InputRedirection_Disable(s64 timeout) +{ + if(!inputRedirectionEnabled) + return 0; + + Result res = InputRedirection_DoOrUndoPatches(); + if(R_FAILED(res)) + return res; + + inputRedirectionEnabled = false; + res = MyThread_Join(&inputRedirectionThread, timeout); + svcCloseHandle(inputRedirectionThreadStartedEvent); + + return res; +} + Result InputRedirection_DoOrUndoPatches(void) { s64 startAddress, textTotalRoundedSize, rodataTotalRoundedSize, dataTotalRoundedSize; diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 6a25c15..3e04dea 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -38,6 +38,9 @@ #include "menus/debugger.h" #include "menus/screen_filters.h" #include "menus/cheats.h" +#include "menus/sysconfig.h" +#include "input_redirection.h" +#include "minisoc.h" #include "task_runner.h" @@ -161,6 +164,26 @@ static void handleTermNotification(u32 notificationId) svcSignalEvent(terminationRequestEvent); } +static void relinquishConnectionSessions(u32 notificationId) +{ + (void)notificationId; + // Might be subject to a race condition, but heh. + + // Disable input redirection + InputRedirection_Disable(100 * 1000 * 1000LL); + + // Ask the debugger to terminate in approx 2 * 100ms + debuggerDisable(100 * 1000 * 1000LL); + + // Kill the ac session if needed + if(isConnectionForced) + { + acExit(); + isConnectionForced = false; + SysConfigMenu_UpdateStatus(true); + } +} + static void handleNextApplicationDebuggedByForce(u32 notificationId) { (void)notificationId; @@ -175,7 +198,9 @@ static const ServiceManagerServiceEntry services[] = { static const ServiceManagerNotificationEntry notifications[] = { { 0x100 , handleTermNotification }, + //{ 0x103 , relinquishConnectionSessions }, // Sleep mode entry <=== causes issues { 0x1000, handleNextApplicationDebuggedByForce }, + { 0x1001, relinquishConnectionSessions }, { 0x000, NULL }, }; diff --git a/sysmodules/rosalina/source/menus/debugger.c b/sysmodules/rosalina/source/menus/debugger.c index 9918618..016c9c7 100644 --- a/sysmodules/rosalina/source/menus/debugger.c +++ b/sysmodules/rosalina/source/menus/debugger.c @@ -84,6 +84,30 @@ void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata) GDB_UnlockAllContexts(&gdbServer); } +Result debuggerDisable(s64 timeout) +{ + Result res = 0; + bool initialized = gdbServer.referenceCount != 0; + if(initialized) + { + svcSignalEvent(gdbServer.super.shall_terminate_event); + server_kill_connections(&gdbServer.super); + + res = MyThread_Join(&debuggerDebugThread, timeout); + if(res == 0) + res = MyThread_Join(&debuggerSocketThread, timeout); + + Handle dummy = 0; + PMDBG_RunQueuedProcess(&dummy); + svcCloseHandle(dummy); + PMDBG_DebugNextApplicationByForce(false); + nextApplicationGdbCtx = NULL; + svcKernelSetState(0x10000, 2); + } + + return res; +} + void DebuggerMenu_EnableDebugger(void) { bool done = false, alreadyEnabled = gdbServer.super.running; @@ -144,27 +168,10 @@ void DebuggerMenu_EnableDebugger(void) void DebuggerMenu_DisableDebugger(void) { bool initialized = gdbServer.referenceCount != 0; - Result res = 0; + + Result res = initialized ? debuggerDisable(2 * 1000 * 1000 * 1000LL) : 0; char buf[65]; - if(initialized) - { - svcSignalEvent(gdbServer.super.shall_terminate_event); - server_kill_connections(&gdbServer.super); - //server_set_should_close_all(&gdbServer.super); - - res = MyThread_Join(&debuggerDebugThread, 2 * 1000 * 1000 * 1000LL); - if(res == 0) - res = MyThread_Join(&debuggerSocketThread, 2 * 1000 * 1000 * 1000LL); - - Handle dummy = 0; - PMDBG_RunQueuedProcess(&dummy); - svcCloseHandle(dummy); - PMDBG_DebugNextApplicationByForce(false); - nextApplicationGdbCtx = NULL; - svcKernelSetState(0x10000, 2); - } - if(res != 0) sprintf(buf, "Failed to disable debugger (0x%08lx).", (u32)res); diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index ad17960..45940e1 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -221,7 +221,6 @@ void MiscellaneousMenu_SaveSettings(void) void MiscellaneousMenu_InputRedirection(void) { - static MyThread *inputRedirectionThread = NULL; bool done = false; Result res; @@ -231,11 +230,7 @@ void MiscellaneousMenu_InputRedirection(void) if(wasEnabled) { - res = InputRedirection_DoOrUndoPatches(); - inputRedirectionEnabled = false; - res = MyThread_Join(inputRedirectionThread, 5 * 1000 * 1000 * 1000LL); - svcCloseHandle(inputRedirectionThreadStartedEvent); - + res = InputRedirection_Disable(5 * 1000 * 1000 * 1000LL); if(res != 0) sprintf(buf, "Failed to stop InputRedirection (0x%08lx).", (u32)res); else @@ -282,7 +277,7 @@ void MiscellaneousMenu_InputRedirection(void) res = svcCreateEvent(&inputRedirectionThreadStartedEvent, RESET_STICKY); if(R_SUCCEEDED(res)) { - inputRedirectionThread = inputRedirectionCreateThread(); + inputRedirectionCreateThread(); res = svcWaitSynchronization(inputRedirectionThreadStartedEvent, 10 * 1000 * 1000 * 1000LL); if(res == 0) res = (Result)inputRedirectionStartResult; diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index 8b23b07..e9d3d20 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -13,6 +13,14 @@ #include <3ds/result.h> #include +s32 miniSocRefCount = 0; +static u32 socContextAddr = 0x08000000; +static u32 socContextSize = 0x60000; +static Handle miniSocHandle; +static Handle miniSocMemHandle; + +bool miniSocEnabled = false; + s32 _net_convert_error(s32 sock_retval); static Result SOCU_Initialize(Handle memhandle, u32 memsize) @@ -26,7 +34,7 @@ static Result SOCU_Initialize(Handle memhandle, u32 memsize) cmdbuf[4] = IPC_Desc_SharedHandles(1); cmdbuf[5] = memhandle; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) return ret; @@ -40,22 +48,14 @@ static Result SOCU_Shutdown(void) cmdbuf[0] = IPC_MakeHeader(0x19,0,0); // 0x190000 - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) return ret; return cmdbuf[1]; } -static s32 miniSocRefCount = 0; -static u32 socContextAddr = 0x08000000; -static u32 socContextSize = 0x60000; -// SOCU_handle from ctrulib -// socMemhandle from ctrulib - -bool miniSocEnabled = false; - -Result miniSocInit() +Result miniSocInit(void) { if(AtomicPostIncrement(&miniSocRefCount)) return 0; @@ -72,7 +72,7 @@ Result miniSocInit() goto cleanup; } - ret = srvGetServiceHandle(&SOCU_handle, "soc:U"); + ret = srvGetServiceHandle(&miniSocHandle, "soc:U"); if(ret != 0) goto cleanup; ret = svcControlMemory(&tmp, socContextAddr, 0, socContextSize, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); @@ -80,12 +80,12 @@ Result miniSocInit() socContextAddr = tmp; - ret = svcCreateMemoryBlock(&socMemhandle, (u32)socContextAddr, socContextSize, 0, 3); + ret = svcCreateMemoryBlock(&miniSocMemHandle, (u32)socContextAddr, socContextSize, 0, 3); if(ret != 0) goto cleanup; - ret = SOCU_Initialize(socMemhandle, socContextSize); + ret = SOCU_Initialize(miniSocMemHandle, socContextSize); if(ret != 0) goto cleanup; svcKernelSetState(0x10000, 2); @@ -95,17 +95,17 @@ Result miniSocInit() cleanup: AtomicDecrement(&miniSocRefCount); - if(socMemhandle != 0) + if(miniSocMemHandle != 0) { - svcCloseHandle(socMemhandle); - socMemhandle = 0; + svcCloseHandle(miniSocMemHandle); + miniSocMemHandle = 0; } - if(SOCU_handle != 0) + if(miniSocHandle != 0) { SOCU_Shutdown(); - svcCloseHandle(SOCU_handle); - SOCU_handle = 0; + svcCloseHandle(miniSocHandle); + miniSocHandle = 0; } if(tmp != 0) @@ -114,21 +114,19 @@ cleanup: return ret; } -Result miniSocExit(void) +Result miniSocExitDirect(void) { - if(AtomicDecrement(&miniSocRefCount)) - return 0; - + //if (miniSocRefCount != 0) __builtin_trap(); Result ret = 0; u32 tmp; - svcCloseHandle(socMemhandle); - socMemhandle = 0; + svcCloseHandle(miniSocMemHandle); + miniSocMemHandle = 0; ret = SOCU_Shutdown(); - svcCloseHandle(SOCU_handle); - SOCU_handle = 0; + svcCloseHandle(miniSocHandle); + miniSocHandle = 0; svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE); if(ret == 0) @@ -139,6 +137,14 @@ Result miniSocExit(void) return ret; } +Result miniSocExit(void) +{ + if(!miniSocEnabled || AtomicDecrement(&miniSocRefCount)) + return 0; + + return miniSocExitDirect(); +} + int socSocket(int domain, int type, int protocol) { int ret = 0; @@ -164,7 +170,7 @@ int socSocket(int domain, int type, int protocol) cmdbuf[3] = protocol; cmdbuf[4] = IPC_Desc_CurProcessId(); - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { //errno = SYNC_ERROR; @@ -214,7 +220,7 @@ int socBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0); cmdbuf[6] = (u32)tmpaddr; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { //errno = SYNC_ERROR; return ret; @@ -242,7 +248,7 @@ int socListen(int sockfd, int max_connections) cmdbuf[2] = (u32)max_connections; cmdbuf[3] = IPC_Desc_CurProcessId(); - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { //errno = SYNC_ERROR; @@ -284,7 +290,7 @@ int socAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0); staticbufs[1] = (u32)tmpaddr; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); staticbufs[0] = saved_threadstorage[0]; staticbufs[1] = saved_threadstorage[1]; @@ -341,7 +347,7 @@ int socConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0); cmdbuf[6] = (u32)tmpaddr; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) return -1; ret = (int)cmdbuf[1]; @@ -384,7 +390,7 @@ int socPoll(struct pollfd *fds, nfds_t nfds, int timeout) staticbufs[0] = IPC_Desc_StaticBuffer(size,0); staticbufs[1] = (u32)fds; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); staticbufs[0] = saved_threadstorage[0]; staticbufs[1] = saved_threadstorage[1]; @@ -409,7 +415,7 @@ int socClose(int sockfd) cmdbuf[1] = (u32)sockfd; cmdbuf[2] = IPC_Desc_CurProcessId(); - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { //errno = SYNC_ERROR; return ret; @@ -441,7 +447,7 @@ int socSetsockopt(int sockfd, int level, int optname, const void *optval, sockle cmdbuf[7] = IPC_Desc_StaticBuffer(optlen,9); cmdbuf[8] = (u32)optval; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { return ret; } @@ -465,7 +471,7 @@ long socGethostid(void) cmdbuf[0] = IPC_MakeHeader(0x16,0,0); // 0x160000 - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { //errno = SYNC_ERROR; return -1; @@ -507,7 +513,7 @@ static ssize_t _socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struc staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0); staticbufs[1] = (u32)tmpaddr; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); staticbufs[0] = saved_threadstorage[0]; staticbufs[1] = saved_threadstorage[1]; @@ -566,7 +572,7 @@ static ssize_t _socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struc cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2; cmdbuf[0x10c>>2] = (u32)tmpaddr; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { //errno = SYNC_ERROR; return ret; @@ -632,7 +638,7 @@ static ssize_t _socuipc_cmd9(int sockfd, const void *buf, size_t len, int flags, cmdbuf[9] = IPC_Desc_Buffer(len,IPC_BUFFER_R); cmdbuf[10] = (u32)buf; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { //errno = SYNC_ERROR; return ret; @@ -686,7 +692,7 @@ static ssize_t _socuipc_cmda(int sockfd, const void *buf, size_t len, int flags, cmdbuf[9] = IPC_Desc_StaticBuffer(tmp_addrlen,1); cmdbuf[10] = (u32)tmpaddr; - ret = svcSendSyncRequest(SOCU_handle); + ret = svcSendSyncRequest(miniSocHandle); if(ret != 0) { //errno = SYNC_ERROR; return ret; diff --git a/sysmodules/rosalina/source/sock_util.c b/sysmodules/rosalina/source/sock_util.c index e0038f2..16485d4 100644 --- a/sysmodules/rosalina/source/sock_util.c +++ b/sysmodules/rosalina/source/sock_util.c @@ -301,7 +301,8 @@ void server_kill_connections(struct sock_server *serv) socClose(fds[i].fd); fds[i].fd = -1; - serv->ctx_ptrs[i]->should_close = true; + if(serv->ctx_ptrs[i] != NULL) + serv->ctx_ptrs[i]->should_close = true; } }