]> Chaos Git - corbenik/ctrulib.git/commitdiff
Started implementing BOSS support.
authoryellows8 <yellows8@users.noreply.github.com>
Tue, 20 Dec 2016 00:49:51 +0000 (19:49 -0500)
committeryellows8 <yellows8@users.noreply.github.com>
Tue, 20 Dec 2016 00:49:51 +0000 (19:49 -0500)
libctru/include/3ds.h
libctru/include/3ds/services/boss.h [new file with mode: 0644]
libctru/source/services/boss.c [new file with mode: 0644]

index 7b8ed5729cd1d259d7d908907d759d9d3db3dd5c..d4079d8f83b34bdbf035f4d8c91162d3c12363be 100644 (file)
@@ -31,6 +31,7 @@ extern "C" {
 #include <3ds/services/am.h>
 #include <3ds/services/ampxi.h>
 #include <3ds/services/apt.h>
+#include <3ds/services/boss.h>
 #include <3ds/services/cam.h>
 #include <3ds/services/cfgnor.h>
 #include <3ds/services/cfgu.h>
diff --git a/libctru/include/3ds/services/boss.h b/libctru/include/3ds/services/boss.h
new file mode 100644 (file)
index 0000000..479909c
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * @file boss.h
+ * @brief BOSS service, see also: https://www.3dbrew.org/wiki/BOSS_Services
+ */
+#pragma once
+
+/**
+ * @brief Initializes BOSS.
+ * @param programID programID to use, 0 for the current process. Not used internally unless BOSSP is available.
+ */
+Result bossInit(u64 programID);
+
+/// Exits BOSS.
+void bossExit(void);
+
+/// Returns the BOSS session handle.
+Handle bossGetSessionHandle();
+
+/**
+ * @brief ?
+ * @param taskID BOSS taskID.
+ */
+Result bossStartTaskImmediate(char *taskID);
+
+/**
+ * @brief ?
+ * @param taskID BOSS taskID.
+ */
+Result bossStartBgImmediate(char *taskID);
+
diff --git a/libctru/source/services/boss.c b/libctru/source/services/boss.c
new file mode 100644 (file)
index 0000000..987e0db
--- /dev/null
@@ -0,0 +1,109 @@
+#include <stdlib.h>
+#include <string.h>
+#include <3ds/types.h>
+#include <3ds/result.h>
+#include <3ds/svc.h>
+#include <3ds/srv.h>
+#include <3ds/synchronization.h>
+#include <3ds/services/boss.h>
+#include <3ds/ipc.h>
+#include <3ds/env.h>
+
+static Handle bossHandle;
+static int bossRefCount;
+static u32 bossPriv = 0;
+
+static Result bossipc_InitializeSession(u64 programID);
+
+Result bossInit(u64 programID)
+{
+       Result res=0;
+       Handle envhandle=0;
+       Handle handle=0;
+
+       if (AtomicPostIncrement(&bossRefCount)) return 0;
+
+       res = srvGetServiceHandle(&handle, "boss:P");
+       envhandle = envGetHandle("boss:P");
+       bossPriv = 1;
+       if (R_FAILED(res))
+       {
+               bossPriv = 0;
+               res = srvGetServiceHandle(&handle, "boss:U");
+               envhandle = envGetHandle("boss:U");
+       }
+
+       if (R_FAILED(res)) AtomicDecrement(&bossRefCount);
+
+       if (R_SUCCEEDED(res))
+       {
+               bossHandle = handle;
+
+               if(envhandle==0)res = bossipc_InitializeSession(programID);
+
+               if (R_FAILED(res))bossExit();
+       }
+
+       return res;
+}
+
+void bossExit(void)
+{
+       if (AtomicDecrement(&bossRefCount)) return;
+       svcCloseHandle(bossHandle);
+       bossHandle = 0;
+}
+
+Handle bossGetSessionHandle()
+{
+       return bossHandle;
+}
+
+static Result bossipc_InitializeSession(u64 programID)
+{
+       Result ret = 0;
+       u32 *cmdbuf = getThreadCommandBuffer();
+
+       if(bossPriv==0)cmdbuf[0] = IPC_MakeHeader(0x1,2,2); // 0x10082
+       if(bossPriv)cmdbuf[0] = IPC_MakeHeader(0x0401,2,2); // 0x04010082
+       cmdbuf[1] = (u32) programID;
+       cmdbuf[2] = (u32) (programID >> 32);
+       cmdbuf[3] = IPC_Desc_CurProcessHandle();
+
+       if(R_FAILED(ret = svcSendSyncRequest(bossHandle)))return ret;
+
+       return (Result)cmdbuf[1];
+}
+
+Result bossStartTaskImmediate(char *taskID)
+{
+       Result ret = 0;
+       u32 *cmdbuf = getThreadCommandBuffer();
+       u32 size = strlen(taskID)+1;
+
+       cmdbuf[0] = IPC_MakeHeader(0x1D,1,2); // 0x1D0042
+       cmdbuf[1] = size;
+       cmdbuf[2] = IPC_Desc_Buffer(size, IPC_BUFFER_R);
+       cmdbuf[3] = (u32)taskID;
+
+       if(R_FAILED(ret = svcSendSyncRequest(bossHandle)))return ret;
+
+       return (Result)cmdbuf[1];
+}
+
+Result bossStartBgImmediate(char *taskID)
+{
+       Result ret = 0;
+       u32 *cmdbuf = getThreadCommandBuffer();
+       u32 size = strlen(taskID)+1;
+
+       cmdbuf[0] = IPC_MakeHeader(0x33,1,2); // 0x330042
+       cmdbuf[1] = size;
+       cmdbuf[2] = IPC_Desc_Buffer(size, IPC_BUFFER_R);
+       cmdbuf[3] = (u32)taskID;
+
+       if(R_FAILED(ret = svcSendSyncRequest(bossHandle)))return ret;
+
+       return (Result)cmdbuf[1];
+}
+