Add Loader service commands

This commit is contained in:
TuxSH 2017-08-01 21:13:23 +02:00
parent f132a7a2a9
commit cad255f1b5
3 changed files with 139 additions and 0 deletions

View File

@ -63,6 +63,7 @@ extern "C" {
#include <3ds/services/news.h>
#include <3ds/services/qtm.h>
#include <3ds/services/srvpm.h>
#include <3ds/services/loader.h>
#include <3ds/services/y2r.h>
#include <3ds/services/hb.h>

View File

@ -0,0 +1,45 @@
/**
* @file loader.h
* @brief LOADER Service
*/
#pragma once
#include <3ds/exheader.h>
#include <3ds/services/fs.h>
/// Initializes LOADER.
Result loaderInit(void);
/// Exits LOADER.
void loaderExit(void);
/**
* @brief Loads a program and returns a process handle to the newly created process.
* @param[out] process Pointer to output the process handle to.
* @param programHandle The handle of the program to load.
*/
Result LOADER_LoadProcess(Handle* process, u64 programHandle);
/**
* @brief Registers a program (along with its update).
* @param[out] programHandle Pointer to output the program handle to.
* @param titleId The program's title ID.
* @param mediaType The program's media type.
* @param updateTitleId The program update's title ID.
* @param updateMediaType The program update's media type.
*/
Result LOADER_RegisterProgram(u64* programHandle, u64 titleId, FS_MediaType mediaType, u64 updateTitleId, FS_MediaType updateMediaType);
/**
* @brief Registers a program (along with its update).
* @param programHandle The handle of the program to unregister.
*/
Result LOADER_UnregisterProgram(u64 programHandle);
/**
* @brief Retrives a program's main NCCH extended header info (SCI + ACI, see @ref ExHeader_Info).
* @param[out] exheaderInfo Pointer to output the main NCCH extended header info.
* @param programHandle The handle of the program to unregister
*/
Result LOADER_GetProgramInfo(ExHeader_Info* exheaderInfo, u64 programHandle);

View File

@ -0,0 +1,93 @@
#include <3ds/services/loader.h>
#include <3ds/result.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
#include <3ds/synchronization.h>
#include <3ds/ipc.h>
static Handle loaderHandle;
static int loaderRefCount;
Result loaderInit(void)
{
Result res;
if (AtomicPostIncrement(&loaderRefCount)) return 0;
res = srvGetServiceHandle(&loaderHandle, "Loader");
if (R_FAILED(res)) AtomicDecrement(&loaderRefCount);
return res;
}
void loaderExit(void)
{
if (AtomicDecrement(&loaderRefCount)) return;
svcCloseHandle(loaderHandle);
}
Result LOADER_LoadProcess(Handle* process, u64 programHandle)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(1, 2, 0); // 0x10080
cmdbuf[1] = (u32)programHandle;
cmdbuf[2] = (u32)(programHandle >> 32);
if(R_FAILED(ret = svcSendSyncRequest(loaderHandle))) return ret;
*process = cmdbuf[3];
return (Result)cmdbuf[1];
}
Result LOADER_RegisterProgram(u64* programHandle, u64 titleId, FS_MediaType mediaType, u64 updateTitleId, FS_MediaType updateMediaType)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(2, 8, 0); // 0x20200
cmdbuf[1] = (u32)titleId;
cmdbuf[2] = (u32)(titleId >> 32);
cmdbuf[3] = mediaType;
cmdbuf[5] = (u32)updateTitleId;
cmdbuf[6] = (u32)(updateTitleId >> 32);
cmdbuf[7] = updateMediaType;
if(R_FAILED(ret = svcSendSyncRequest(loaderHandle))) return ret;
*programHandle = ((u64)cmdbuf[2] << 32) | cmdbuf[3];
return (Result)cmdbuf[1];
}
Result LOADER_UnregisterProgram(u64 programHandle)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(3, 2, 0); // 0x30080
cmdbuf[1] = (u32)programHandle;
cmdbuf[2] = (u32)(programHandle >> 32);
if(R_FAILED(ret = svcSendSyncRequest(loaderHandle))) return ret;
return (Result)cmdbuf[1];
}
Result LOADER_GetProgramInfo(ExHeader_Info* exheaderInfo, u64 programHandle)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(4, 2, 0); // 0x40080
cmdbuf[1] = (u32)programHandle;
cmdbuf[2] = (u32)(programHandle >> 32);
staticbufs[0] = IPC_Desc_StaticBuffer(0x400, 0);
staticbufs[1] = (u32)exheaderInfo;
if(R_FAILED(ret = svcSendSyncRequest(loaderHandle))) return ret;
return (Result)cmdbuf[1];
}