Started implementing BOSS support.

This commit is contained in:
yellows8 2016-12-19 19:49:51 -05:00
parent b5a8183dbd
commit e8c3a9139e
3 changed files with 140 additions and 0 deletions

View 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>

View File

@ -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);

View File

@ -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];
}