Fix srv:pm handling for pre-7.x system versions
This commit is contained in:
parent
41c1fee88e
commit
3dee692c85
@ -4,12 +4,18 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/// Initializes srv:pm.
|
/// Initializes srv:pm and the service API.
|
||||||
Result srvPmInit(void);
|
Result srvPmInit(void);
|
||||||
|
|
||||||
/// Exits srv:pm.
|
/// Exits srv:pm and the service API.
|
||||||
void srvPmExit(void);
|
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.
|
* @brief Publishes a notification to a process.
|
||||||
* @param notificationId ID of the notification.
|
* @param notificationId ID of the notification.
|
||||||
@ -25,15 +31,15 @@ Result SRVPM_PublishToAll(u32 notificationId);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Registers a process with SRV.
|
* @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 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.
|
* @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/synchronization.h>
|
||||||
#include <3ds/services/srvpm.h>
|
#include <3ds/services/srvpm.h>
|
||||||
#include <3ds/ipc.h>
|
#include <3ds/ipc.h>
|
||||||
|
#include <3ds/os.h>
|
||||||
|
|
||||||
|
#define IS_PRE_7X (osGetFirmVersion() >= SYSTEM_VERSION(2, 39, 4))
|
||||||
|
|
||||||
static Handle srvPmHandle;
|
static Handle srvPmHandle;
|
||||||
static int srvPmRefCount;
|
static int srvPmRefCount;
|
||||||
|
|
||||||
Result srvPmInit(void)
|
Result srvPmInit(void)
|
||||||
{
|
{
|
||||||
|
Result res = 0;
|
||||||
|
|
||||||
|
if (!IS_PRE_7X) res = srvInit();
|
||||||
|
if (R_FAILED(res)) return res;
|
||||||
|
|
||||||
if (AtomicPostIncrement(&srvPmRefCount)) return 0;
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void srvPmExit(void)
|
void srvPmExit(void)
|
||||||
{
|
{
|
||||||
|
if (*srvGetSessionHandle() != 0) srvExit();
|
||||||
if (AtomicDecrement(&srvPmRefCount)) return;
|
if (AtomicDecrement(&srvPmRefCount)) return;
|
||||||
svcCloseHandle(srvPmHandle);
|
svcCloseHandle(srvPmHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SRVPM_PublishToProcess(u32 notificationId, Handle process)
|
Handle *srvPmGetSessionHandle(void)
|
||||||
|
{
|
||||||
|
return &srvPmHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result srvPmSendCommand(u32* cmdbuf)
|
||||||
{
|
{
|
||||||
Result rc = 0;
|
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();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042
|
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[2] = IPC_Desc_SharedHandles(1);
|
||||||
cmdbuf[3] = process;
|
cmdbuf[3] = process;
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle)))return rc;
|
return srvPmSendCommand(cmdbuf);
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SRVPM_PublishToAll(u32 notificationId)
|
Result SRVPM_PublishToAll(u32 notificationId)
|
||||||
{
|
{
|
||||||
Result rc = 0;
|
|
||||||
u32* cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x2,1,0); // 0x20040
|
cmdbuf[0] = IPC_MakeHeader(0x2,1,0); // 0x20040
|
||||||
cmdbuf[1] = notificationId;
|
cmdbuf[1] = notificationId;
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle)))return rc;
|
return srvPmSendCommand(cmdbuf);
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
u32 *cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x3,2,2); // 0x30082
|
cmdbuf[0] = IPC_MakeHeader(0x3,2,2); // 0x30082
|
||||||
cmdbuf[1] = procid;
|
cmdbuf[1] = pid;
|
||||||
cmdbuf[2] = count;
|
cmdbuf[2] = count;
|
||||||
cmdbuf[3] = IPC_Desc_StaticBuffer(count*4,0);
|
cmdbuf[3] = IPC_Desc_StaticBuffer(count*8,0);
|
||||||
cmdbuf[4] = (u32)serviceaccesscontrol;
|
cmdbuf[4] = (u32)serviceAccessControlList;
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle))) return rc;
|
return srvPmSendCommand(cmdbuf);
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SRVPM_UnregisterProcess(u32 procid)
|
Result SRVPM_UnregisterProcess(u32 pid)
|
||||||
{
|
{
|
||||||
Result rc = 0;
|
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32 *cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x4,1,0); // 0x40040
|
cmdbuf[0] = IPC_MakeHeader(0x4,1,0); // 0x40040
|
||||||
cmdbuf[1] = procid;
|
cmdbuf[1] = pid;
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle))) return rc;
|
return srvPmSendCommand(cmdbuf);
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
#include <3ds/synchronization.h>
|
#include <3ds/synchronization.h>
|
||||||
#include <3ds/env.h>
|
#include <3ds/env.h>
|
||||||
|
|
||||||
|
#include <3ds/os.h>
|
||||||
|
#include <3ds/services/srvpm.h>
|
||||||
|
|
||||||
static Handle srvHandle;
|
static Handle srvHandle;
|
||||||
static int srvRefCount;
|
static int srvRefCount;
|
||||||
|
|
||||||
@ -20,7 +23,10 @@ Result srvInit(void)
|
|||||||
|
|
||||||
if (AtomicPostIncrement(&srvRefCount)) return 0;
|
if (AtomicPostIncrement(&srvRefCount)) return 0;
|
||||||
|
|
||||||
rc = svcConnectToPort(&srvHandle, "srv:");
|
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;
|
if (R_FAILED(rc)) goto end;
|
||||||
|
|
||||||
rc = srvRegisterClient();
|
rc = srvRegisterClient();
|
||||||
|
Loading…
Reference in New Issue
Block a user