+++ /dev/null
-#include <3ds.h>
-#include <string.h>
-#include "srvsys.h"
-
-static Handle srvHandle;
-static int srvRefCount;
-static RecursiveLock initLock;
-static int initLockinit = 0;
-
-Result
-srvSysInit()
-{
- Result rc = 0;
-
- if (!initLockinit) {
- RecursiveLock_Init(&initLock);
- }
-
- RecursiveLock_Lock(&initLock);
-
- if (srvRefCount > 0) {
- RecursiveLock_Unlock(&initLock);
- return MAKERESULT(RL_INFO, RS_NOP, 25, RD_ALREADY_INITIALIZED);
- }
-
- while (1) {
- rc = svcConnectToPort(&srvHandle, "srv:");
- if (R_LEVEL(rc) != RL_PERMANENT || R_SUMMARY(rc) != RS_NOTFOUND || R_DESCRIPTION(rc) != RD_NOT_FOUND)
- break;
- svcSleepThread(500000);
- }
- if (R_SUCCEEDED(rc)) {
- rc = srvSysRegisterClient();
- srvRefCount++;
- }
-
- RecursiveLock_Unlock(&initLock);
- return rc;
-}
-
-Result
-srvSysRegisterClient(void)
-{
- Result rc = 0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0x1, 0, 2); // 0x10002
- cmdbuf[1] = IPC_Desc_CurProcessHandle();
-
- if (R_FAILED(rc = svcSendSyncRequest(srvHandle)))
- return rc;
-
- return cmdbuf[1];
-}
-
-Result
-srvSysExit()
-{
- Result rc;
- RecursiveLock_Lock(&initLock);
-
- if (srvRefCount > 1) {
- srvRefCount--;
- RecursiveLock_Unlock(&initLock);
- return MAKERESULT(RL_INFO, RS_NOP, 25, RD_BUSY);
- }
-
- if (srvHandle != 0)
- svcCloseHandle(srvHandle);
- else
- svcBreak(USERBREAK_ASSERT); // No logging available, sadly
-
- srvHandle = 0;
- srvRefCount--;
- RecursiveLock_Unlock(&initLock);
- return rc;
-}
-
-Result
-srvSysGetServiceHandle(Handle *out, const char *name)
-{
- Result rc = 0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0x5, 4, 0); // 0x50100
- strncpy((char *)&cmdbuf[1], name, 8);
- cmdbuf[3] = strlen(name);
- cmdbuf[4] = 0x0;
-
- if (R_FAILED(rc = svcSendSyncRequest(srvHandle)))
- return rc;
-
- if (out)
- *out = cmdbuf[3];
-
- return cmdbuf[1];
-}
-
-Result
-srvSysEnableNotification(Handle *semaphoreOut)
-{
- Result rc = 0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0x2, 0, 0);
-
- if (R_FAILED(rc = svcSendSyncRequest(srvHandle)))
- return rc;
-
- if (semaphoreOut)
- *semaphoreOut = cmdbuf[3];
-
- return cmdbuf[1];
-}
-
-Result
-srvSysReceiveNotification(u32 *notificationIdOut)
-{
- Result rc = 0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0xB, 0, 0); // 0xB0000
-
- if (R_FAILED(rc = svcSendSyncRequest(srvHandle)))
- return rc;
-
- if (notificationIdOut)
- *notificationIdOut = cmdbuf[2];
-
- return cmdbuf[1];
-}
-
-Result
-srvSysRegisterService(Handle *out, const char *name, int maxSessions)
-{
- Result rc = 0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0x3, 4, 0); // 0x30100
- strncpy((char *)&cmdbuf[1], name, 8);
- cmdbuf[3] = strlen(name);
- cmdbuf[4] = maxSessions;
-
- if (R_FAILED(rc = svcSendSyncRequest(srvHandle)))
- return rc;
-
- if (out)
- *out = cmdbuf[3];
-
- return cmdbuf[1];
-}
-
-Result
-srvSysUnregisterService(const char *name)
-{
- Result rc = 0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0x4, 3, 0); // 0x400C0
- strncpy((char *)&cmdbuf[1], name, 8);
- cmdbuf[3] = strlen(name);
-
- if (R_FAILED(rc = svcSendSyncRequest(srvHandle)))
- return rc;
-
- return cmdbuf[1];
-}
+++ /dev/null
-/**
- * @file srv.h
- * @brief Service API.
- */
-#ifndef __SRVSYS_H
-#define __SRVSYS_H
-
-/// Initializes the service API.
-Result srvSysInit(void);
-
-/// Exits the service API.
-Result srvSysExit(void);
-
-/**
- * @brief Retrieves a service handle, retrieving from the environment handle
- * list if possible.
- * @param out Pointer to write the handle to.
- * @param name Name of the service.
- */
-Result srvSysGetServiceHandle(Handle *out, const char *name);
-
-/// Registers the current process as a client to the service API.
-Result srvSysRegisterClient(void);
-
-/**
- * @brief Enables service notificatios, returning a notification semaphore.
- * @param semaphoreOut Pointer to output the notification semaphore to.
- */
-Result srvSysEnableNotification(Handle *semaphoreOut);
-
-/**
- * @brief Receives a notification.
- * @param notificationIdOut Pointer to output the ID of the received
- * notification to.
- */
-Result srvSysReceiveNotification(u32 *notificationIdOut);
-
-/**
- * @brief Registers the current process as a service.
- * @param out Pointer to write the service handle to.
- * @param name Name of the service.
- * @param maxSessions Maximum number of sessions the service can handle.
- */
-Result srvSysRegisterService(Handle *out, const char *name, int maxSessions);
-
-/**
- * @brief Unregisters the current process as a service.
- * @param name Name of the service.
- */
-Result srvSysUnregisterService(const char *name);
-
-#endif