Fix srv:pm handling for pre-7.x system versions (#365)
This commit is contained in:
parent
e1ddc74c1c
commit
532fbef44f
@ -4,12 +4,18 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/// Initializes srv:pm.
|
||||
/// Initializes srv:pm and the service API.
|
||||
Result srvPmInit(void);
|
||||
|
||||
/// Exits srv:pm.
|
||||
/// Exits srv:pm and the service API.
|
||||
void srvPmExit(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the current srv:pm session handle.
|
||||
* @return The current srv:pm session handle.
|
||||
*/
|
||||
Handle *srvPmGetSessionHandle(void);
|
||||
|
||||
/**
|
||||
* @brief Publishes a notification to a process.
|
||||
* @param notificationId ID of the notification.
|
||||
@ -25,15 +31,15 @@ Result SRVPM_PublishToAll(u32 notificationId);
|
||||
|
||||
/**
|
||||
* @brief Registers a process with SRV.
|
||||
* @param procid ID of the process.
|
||||
* @param pid ID of the process.
|
||||
* @param count Number of services within the service access control data.
|
||||
* @param serviceaccesscontrol Service Access Control list.
|
||||
* @param serviceAccessControlList Service Access Control list.
|
||||
*/
|
||||
Result SRVPM_RegisterProcess(u32 procid, u32 count, void* serviceaccesscontrol);
|
||||
Result SRVPM_RegisterProcess(u32 pid, u32 count, char (*serviceAccessControlList)[8]);
|
||||
|
||||
/**
|
||||
* @brief Unregisters a process with SRV.
|
||||
* @param procid ID of the process.
|
||||
* @param pid ID of the process.
|
||||
*/
|
||||
Result SRVPM_UnregisterProcess(u32 procid);
|
||||
Result SRVPM_UnregisterProcess(u32 pid);
|
||||
|
||||
|
@ -6,27 +6,58 @@
|
||||
#include <3ds/synchronization.h>
|
||||
#include <3ds/services/srvpm.h>
|
||||
#include <3ds/ipc.h>
|
||||
#include <3ds/os.h>
|
||||
|
||||
#define IS_PRE_7X (osGetFirmVersion() >= SYSTEM_VERSION(2, 39, 4))
|
||||
|
||||
static Handle srvPmHandle;
|
||||
static int srvPmRefCount;
|
||||
|
||||
Result srvPmInit(void)
|
||||
{
|
||||
Result res = 0;
|
||||
|
||||
if (!IS_PRE_7X) res = srvInit();
|
||||
if (R_FAILED(res)) return res;
|
||||
|
||||
if (AtomicPostIncrement(&srvPmRefCount)) return 0;
|
||||
Result res = srvGetServiceHandle(&srvPmHandle, "srv:pm");
|
||||
if (R_FAILED(res)) AtomicDecrement(&srvPmRefCount);
|
||||
|
||||
if (!IS_PRE_7X)
|
||||
res = srvGetServiceHandleDirect(&srvPmHandle, "srv:pm");
|
||||
else
|
||||
{
|
||||
res = svcConnectToPort(&srvPmHandle, "srv:pm");
|
||||
if (R_SUCCEEDED(res)) res = srvInit();
|
||||
}
|
||||
|
||||
if (R_FAILED(res)) srvPmExit();
|
||||
return res;
|
||||
}
|
||||
|
||||
void srvPmExit(void)
|
||||
{
|
||||
if (*srvGetSessionHandle() != 0) srvExit();
|
||||
if (AtomicDecrement(&srvPmRefCount)) return;
|
||||
svcCloseHandle(srvPmHandle);
|
||||
}
|
||||
|
||||
Result SRVPM_PublishToProcess(u32 notificationId, Handle process)
|
||||
Handle *srvPmGetSessionHandle(void)
|
||||
{
|
||||
return &srvPmHandle;
|
||||
}
|
||||
|
||||
static Result srvPmSendCommand(u32* cmdbuf)
|
||||
{
|
||||
Result rc = 0;
|
||||
if (IS_PRE_7X) cmdbuf[0] |= 0x04000000;
|
||||
rc = svcSendSyncRequest(srvPmHandle);
|
||||
if (R_SUCCEEDED(rc)) rc = cmdbuf[1];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result SRVPM_PublishToProcess(u32 notificationId, Handle process)
|
||||
{
|
||||
u32* cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042
|
||||
@ -34,50 +65,39 @@ Result SRVPM_PublishToProcess(u32 notificationId, Handle process)
|
||||
cmdbuf[2] = IPC_Desc_SharedHandles(1);
|
||||
cmdbuf[3] = process;
|
||||
|
||||
if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle)))return rc;
|
||||
|
||||
return cmdbuf[1];
|
||||
return srvPmSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
Result SRVPM_PublishToAll(u32 notificationId)
|
||||
{
|
||||
Result rc = 0;
|
||||
u32* cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x2,1,0); // 0x20040
|
||||
cmdbuf[1] = notificationId;
|
||||
|
||||
if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle)))return rc;
|
||||
|
||||
return cmdbuf[1];
|
||||
return srvPmSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
Result SRVPM_RegisterProcess(u32 procid, u32 count, void* serviceaccesscontrol)
|
||||
Result SRVPM_RegisterProcess(u32 pid, u32 count, char (*serviceAccessControlList)[8])
|
||||
{
|
||||
Result rc = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x3,2,2); // 0x30082
|
||||
cmdbuf[1] = procid;
|
||||
cmdbuf[1] = pid;
|
||||
cmdbuf[2] = count;
|
||||
cmdbuf[3] = IPC_Desc_StaticBuffer(count*4,0);
|
||||
cmdbuf[4] = (u32)serviceaccesscontrol;
|
||||
cmdbuf[3] = IPC_Desc_StaticBuffer(count*8,0);
|
||||
cmdbuf[4] = (u32)serviceAccessControlList;
|
||||
|
||||
if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle))) return rc;
|
||||
|
||||
return cmdbuf[1];
|
||||
return srvPmSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
Result SRVPM_UnregisterProcess(u32 procid)
|
||||
Result SRVPM_UnregisterProcess(u32 pid)
|
||||
{
|
||||
Result rc = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x4,1,0); // 0x40040
|
||||
cmdbuf[1] = procid;
|
||||
cmdbuf[1] = pid;
|
||||
|
||||
if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle))) return rc;
|
||||
|
||||
return cmdbuf[1];
|
||||
return srvPmSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,9 @@
|
||||
#include <3ds/synchronization.h>
|
||||
#include <3ds/env.h>
|
||||
|
||||
#include <3ds/os.h>
|
||||
#include <3ds/services/srvpm.h>
|
||||
|
||||
static Handle srvHandle;
|
||||
static int srvRefCount;
|
||||
|
||||
@ -20,6 +23,9 @@ Result srvInit(void)
|
||||
|
||||
if (AtomicPostIncrement(&srvRefCount)) return 0;
|
||||
|
||||
if(osGetFirmVersion() < SYSTEM_VERSION(2, 39, 4) && *srvPmGetSessionHandle() != 0)
|
||||
rc = svcDuplicateHandle(&srvHandle, *srvPmGetSessionHandle()); // Prior to system version 7.0 srv:pm was a superset of srv:
|
||||
else
|
||||
rc = svcConnectToPort(&srvHandle, "srv:");
|
||||
if (R_FAILED(rc)) goto end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user