rosalina & pm: properly shutdown when debugger, input redir (but not both) and force connection are enabled
This commit is contained in:
parent
8c54613e44
commit
44cd3928fb
@ -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;
|
||||
|
@ -36,4 +36,5 @@ extern int inputRedirectionStartResult;
|
||||
|
||||
MyThread *inputRedirectionCreateThread(void);
|
||||
void inputRedirectionThreadMain(void);
|
||||
Result InputRedirection_Disable(s64 timeout);
|
||||
Result InputRedirection_DoOrUndoPatches(void);
|
||||
|
@ -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);
|
||||
|
@ -18,13 +18,10 @@
|
||||
#include <errno.h>
|
||||
|
||||
#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);
|
||||
|
@ -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;
|
||||
|
@ -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 },
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -13,6 +13,14 @@
|
||||
#include <3ds/result.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
|
@ -301,6 +301,7 @@ void server_kill_connections(struct sock_server *serv)
|
||||
socClose(fds[i].fd);
|
||||
fds[i].fd = -1;
|
||||
|
||||
if(serv->ctx_ptrs[i] != NULL)
|
||||
serv->ctx_ptrs[i]->should_close = true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user