Add Loader service commands
This commit is contained in:
parent
f132a7a2a9
commit
cad255f1b5
@ -63,6 +63,7 @@ extern "C" {
|
|||||||
#include <3ds/services/news.h>
|
#include <3ds/services/news.h>
|
||||||
#include <3ds/services/qtm.h>
|
#include <3ds/services/qtm.h>
|
||||||
#include <3ds/services/srvpm.h>
|
#include <3ds/services/srvpm.h>
|
||||||
|
#include <3ds/services/loader.h>
|
||||||
#include <3ds/services/y2r.h>
|
#include <3ds/services/y2r.h>
|
||||||
#include <3ds/services/hb.h>
|
#include <3ds/services/hb.h>
|
||||||
|
|
||||||
|
45
libctru/include/3ds/services/loader.h
Normal file
45
libctru/include/3ds/services/loader.h
Normal 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);
|
93
libctru/source/services/loader.c
Normal file
93
libctru/source/services/loader.c
Normal 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];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user