diff --git a/sysmodules/rosalina/include/minisoc.h b/sysmodules/rosalina/include/minisoc.h index 6040bc8..9a97878 100644 --- a/sysmodules/rosalina/include/minisoc.h +++ b/sysmodules/rosalina/include/minisoc.h @@ -17,6 +17,8 @@ #define _REENT_ONLY #include +#define ROSALINA_PREVENT_DISCONNECT (*(volatile bool*)0x1FF81108) + #define SYNC_ERROR ENODEV extern bool miniSocEnabled; diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 297b8e4..9ef643b 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -140,7 +140,7 @@ static void handleSleepNotification(u32 notificationId) switch (notificationId) { case PTMNOTIFID_SLEEP_REQUESTED: - PTMSYSM_ReplyToSleepQuery(miniSocEnabled); // deny sleep request if we have network stuff running + PTMSYSM_ReplyToSleepQuery(ROSALINA_PREVENT_DISCONNECT); // deny sleep request if we have network stuff running break; case PTMNOTIFID_GOING_TO_SLEEP: case PTMNOTIFID_SLEEP_ALLOWED: diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index d52d48c..2cf5c68 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -91,6 +91,7 @@ Result miniSocInit(void) svcKernelSetState(0x10000, 2); miniSocEnabled = true; + ROSALINA_PREVENT_DISCONNECT = true; return 0; cleanup: @@ -134,6 +135,7 @@ Result miniSocExitDirect(void) { svcKernelSetState(0x10000, 2); miniSocEnabled = false; + ROSALINA_PREVENT_DISCONNECT = false; } return ret; } diff --git a/sysmodules/sm/source/common.h b/sysmodules/sm/source/common.h index 7ee7f6b..c750ece 100644 --- a/sysmodules/sm/source/common.h +++ b/sysmodules/sm/source/common.h @@ -17,6 +17,7 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for extern u32 nbSection0Modules; extern Handle resumeGetServiceHandleOrPortRegisteredSemaphore; +extern u32 ndmuServicePid; struct SessionDataList; diff --git a/sysmodules/sm/source/notifications.c b/sysmodules/sm/source/notifications.c index 84cd9ad..a9128c6 100644 --- a/sysmodules/sm/source/notifications.c +++ b/sysmodules/sm/source/notifications.c @@ -8,6 +8,23 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for #include "notifications.h" #include "processes.h" +// 0 by default +#define ROSALINA_PREVENT_DISCONNECT (*(volatile bool*)0x1FF81108) + +static bool isNotificationInhibited(const ProcessData *processData, u32 notificationId) +{ + u32 pid = processData->pid; + switch(notificationId) + { + // Shell opened, shell closed + case 0x213: + case 0x214: + return pid == ndmuServicePid && ROSALINA_PREVENT_DISCONNECT; + default: + return false; + } +} + static bool doPublishNotification(ProcessData *processData, u32 notificationId, u32 flags) { if((flags & 1) && processData->nbPendingNotifications != 0) // only send if not already pending @@ -118,7 +135,7 @@ Result PublishToSubscriber(u32 notificationId, u32 flags) { for(ProcessData *node = processDataInUseList.first; node != NULL; node = node->next) { - if(!node->notificationEnabled) + if(!node->notificationEnabled || isNotificationInhibited(node, notificationId)) continue; u16 i; @@ -138,7 +155,7 @@ Result PublishAndGetSubscriber(u32 *pidCount, u32 *pidList, u32 notificationId, u32 nb = 0; for(ProcessData *node = processDataInUseList.first; node != NULL; node = node->next) { - if(!node->notificationEnabled) + if(!node->notificationEnabled || isNotificationInhibited(node, notificationId)) continue; u16 i; diff --git a/sysmodules/sm/source/services.c b/sysmodules/sm/source/services.c index a81af7c..67274b4 100644 --- a/sysmodules/sm/source/services.c +++ b/sysmodules/sm/source/services.c @@ -13,6 +13,8 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for ServiceInfo servicesInfo[0xA0] = { 0 }; u32 nbServices = 0; // including "ports" registered with getPort +u32 ndmuServicePid = 3; // use our PID as default. + static Result checkServiceName(const char *name, s32 nameSize) { if(nameSize <= 0 || nameSize > 8) @@ -96,6 +98,9 @@ static Result doRegisterServiceOrPort(u32 pid, Handle *serverPort, Handle client if(!isNamedPort) *serverPort = portServer; + if(R_SUCCEEDED(res) && strcmp(name, "ndm:u") == 0) + ndmuServicePid = pid; + return res; }