PM services overhaul
This commit is contained in:
parent
8ffc9461ea
commit
09688ea6fc
@ -54,7 +54,8 @@ extern "C" {
|
||||
#include <3ds/services/nwmext.h>
|
||||
#include <3ds/services/ir.h>
|
||||
#include <3ds/services/ns.h>
|
||||
#include <3ds/services/pm.h>
|
||||
#include <3ds/services/pmapp.h>
|
||||
#include <3ds/services/pmdbg.h>
|
||||
#include <3ds/services/ps.h>
|
||||
#include <3ds/services/ptmu.h>
|
||||
#include <3ds/services/ptmsysm.h>
|
||||
|
@ -1,80 +0,0 @@
|
||||
/**
|
||||
* @file pm.h
|
||||
* @brief PM (Process Manager) service.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/// Launch flags for PM launch commands.
|
||||
enum {
|
||||
PMLAUNCHFLAG_NORMAL_APPLICATION = BIT(0),
|
||||
PMLAUNCHFLAG_LOAD_DEPENDENCIES = BIT(1),
|
||||
PMLAUNCHFLAG_NOTIFY_TERMINATION = BIT(2),
|
||||
PMLAUNCHFLAG_QUEUE_DEBUG_APPLICATION = BIT(3),
|
||||
PMLAUNCHFLAG_TERMINATION_NOTIFICATION_MASK = 0xF0,
|
||||
PMLAUNCHFLAG_FORCE_USE_O3DS_APP_MEM = BIT(8), ///< Forces the usage of the O3DS system mode app memory setting even if N3DS system mode is not "Legacy". Dev4 and Dev5 not supported. N3DS only.
|
||||
PMLAUNCHFLAG_FORCE_USE_O3DS_MAX_APP_MEM = BIT(9), ///< In conjunction with the above, forces the 96MB app memory setting. N3DS only.
|
||||
PMLAUNCHFLAG_USE_UPDATE_TITLE = BIT(16),
|
||||
};
|
||||
|
||||
/// Initializes PM.
|
||||
Result pmInit(void);
|
||||
|
||||
/// Exits PM.
|
||||
void pmExit(void);
|
||||
|
||||
/**
|
||||
* @brief Launches a title.
|
||||
* @param mediatype Mediatype of the title.
|
||||
* @param titleid ID of the title.
|
||||
* @param launch_flags Flags to launch the title with.
|
||||
*/
|
||||
Result PM_LaunchTitle(u8 mediatype, u64 titleid, u32 launch_flags);
|
||||
|
||||
/**
|
||||
* @brief Gets launch flags from a title's exheader.
|
||||
* @param mediatype Mediatype of the title.
|
||||
* @param titleid ID of the title.
|
||||
* @param out Pointer to write the launch flags to.
|
||||
*/
|
||||
Result PM_GetTitleExheaderFlags(u8 mediatype, u64 titleid, u8* out);
|
||||
|
||||
/**
|
||||
* @brief Sets the current FIRM launch parameters.
|
||||
* @param size Size of the FIRM launch parameter buffer.
|
||||
* @param in Buffer to retrieve the launch parameters from.
|
||||
*/
|
||||
Result PM_SetFIRMLaunchParams(u32 size, u8* in);
|
||||
|
||||
/**
|
||||
* @brief Gets the current FIRM launch parameters.
|
||||
* @param size Size of the FIRM launch parameter buffer.
|
||||
* @param out Buffer to write the launch parameters to.
|
||||
*/
|
||||
Result PM_GetFIRMLaunchParams(u32 size, u8* out);
|
||||
|
||||
/**
|
||||
* @brief Sets the current FIRM launch parameters.
|
||||
* @param firm_titleid_low Low Title ID of the FIRM title to launch.
|
||||
* @param size Size of the FIRM launch parameter buffer.
|
||||
* @param in Buffer to retrieve the launch parameters from.
|
||||
*/
|
||||
Result PM_LaunchFIRMSetParams(u32 firm_titleid_low, u32 size, u8* in);
|
||||
|
||||
/**
|
||||
* @brief Terminates the current Application
|
||||
* @param timeout Timeout in nanoseconds
|
||||
*/
|
||||
Result PM_TerminateCurrentApplication(u64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Terminates the specified Process
|
||||
* @param pid Process-ID of the process to terminate
|
||||
* @param timeout Timeout on nanoseconds
|
||||
*/
|
||||
Result PM_TerminateProcess(u8 pid, u64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Unregisters a process
|
||||
* @param tid TitleID of the process to unregister
|
||||
*/
|
||||
Result PM_UnregisterProcess(u64 tid);
|
123
libctru/include/3ds/services/pmapp.h
Normal file
123
libctru/include/3ds/services/pmapp.h
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @file pmapp.h
|
||||
* @brief PM (Process Manager) application service.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <3ds/services/fs.h>
|
||||
#include <3ds/exheader.h>
|
||||
|
||||
/// Launch flags for PM launch commands.
|
||||
enum {
|
||||
PMLAUNCHFLAG_NORMAL_APPLICATION = BIT(0),
|
||||
PMLAUNCHFLAG_LOAD_DEPENDENCIES = BIT(1),
|
||||
PMLAUNCHFLAG_NOTIFY_TERMINATION = BIT(2),
|
||||
PMLAUNCHFLAG_QUEUE_DEBUG_APPLICATION = BIT(3),
|
||||
PMLAUNCHFLAG_TERMINATION_NOTIFICATION_MASK = 0xF0,
|
||||
PMLAUNCHFLAG_FORCE_USE_O3DS_APP_MEM = BIT(8), ///< Forces the usage of the O3DS system mode app memory setting even if N3DS system mode is not "Legacy". Dev4 and Dev5 not supported. N3DS only.
|
||||
PMLAUNCHFLAG_FORCE_USE_O3DS_MAX_APP_MEM = BIT(9), ///< In conjunction with the above, forces the 96MB app memory setting. N3DS only.
|
||||
PMLAUNCHFLAG_USE_UPDATE_TITLE = BIT(16),
|
||||
};
|
||||
|
||||
/// Initializes pm:app.
|
||||
Result pmAppInit(void);
|
||||
|
||||
/// Exits pm:app.
|
||||
void pmAppExit(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the current pm:app session handle.
|
||||
* @return The current pm:app session handle.
|
||||
*/
|
||||
Handle *pmAppGetSessionHandle(void);
|
||||
|
||||
/**
|
||||
* @brief Launches a title.
|
||||
* @param programInfo Program information of the title.
|
||||
* @param launchFlags Flags to launch the title with.
|
||||
*/
|
||||
Result PMAPP_LaunchTitle(const FS_ProgramInfo *programInfo, u32 launchFlags);
|
||||
|
||||
/**
|
||||
* @brief Launches a title, applying patches.
|
||||
* @param programInfo Program information of the title.
|
||||
* @param programInfoUpdate Program information of the update title.
|
||||
* @param launchFlags Flags to launch the title with.
|
||||
*/
|
||||
Result PMAPP_LaunchTitleUpdate(const FS_ProgramInfo *programInfo, const FS_ProgramInfo *programInfoUpdate, u32 launchFlags);
|
||||
|
||||
/**
|
||||
* @brief Gets a title's ExHeader Arm11CoreInfo and SystemInfo flags.
|
||||
* @param[out] outCoreInfo Pointer to write the ExHeader Arm11CoreInfo to.
|
||||
* @param[out] outSiFlags Pointer to write the ExHeader SystemInfo flags to.
|
||||
* @param programInfo Program information of the title.
|
||||
*/
|
||||
Result PMAPP_GetTitleExheaderFlags(ExHeader_Arm11CoreInfo* outCoreInfo, ExHeader_SystemInfoFlags* outSiFlags, const FS_ProgramInfo *programInfo);
|
||||
|
||||
/**
|
||||
* @brief Sets the current FIRM launch parameters.
|
||||
* @param size Size of the FIRM launch parameter buffer.
|
||||
* @param in Buffer to retrieve the launch parameters from.
|
||||
*/
|
||||
Result PMAPP_SetFIRMLaunchParams(u32 size, const void* in);
|
||||
|
||||
/**
|
||||
* @brief Gets the current FIRM launch parameters.
|
||||
* @param size Size of the FIRM launch parameter buffer.
|
||||
* @param[out] out Buffer to write the launch parameters to.
|
||||
*/
|
||||
Result PMAPP_GetFIRMLaunchParams(void *out, u32 size);
|
||||
|
||||
/**
|
||||
* @brief Sets the current FIRM launch parameters.
|
||||
* @param firmTidLow Low Title ID of the FIRM title to launch.
|
||||
* @param size Size of the FIRM launch parameter buffer.
|
||||
* @param in Buffer to retrieve the launch parameters from.
|
||||
*/
|
||||
Result PMAPP_LaunchFIRMSetParams(u32 firmTidLow, u32 size, const void* in);
|
||||
|
||||
/**
|
||||
* @brief Terminate most processes, to prepare for a reboot or a shutdown.
|
||||
* @param timeout Time limit in ns for process termination, after which the remaining processes are killed.
|
||||
*/
|
||||
Result PMAPP_PrepareForReboot(s64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Terminates the current Application
|
||||
* @param timeout Timeout in nanoseconds
|
||||
*/
|
||||
Result PMAPP_TerminateCurrentApplication(s64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Terminates the processes having the specified titleId.
|
||||
* @param titleId Title ID of the processes to terminate
|
||||
* @param timeout Timeout in nanoseconds
|
||||
*/
|
||||
Result PMAPP_TerminateTitle(u64 titleId, s64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Terminates the specified process
|
||||
* @param pid Process-ID of the process to terminate
|
||||
* @param timeout Timeout in nanoseconds
|
||||
*/
|
||||
Result PMAPP_TerminateProcess(u32 pid, s64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Unregisters a process
|
||||
* @param tid TitleID of the process to unregister
|
||||
*/
|
||||
Result PMAPP_UnregisterProcess(u64 tid);
|
||||
|
||||
/**
|
||||
* @brief Sets the APPLICATION cputime reslimit.
|
||||
* @param cpuTime Reslimit value.
|
||||
* @note cpuTime can be no higher than reslimitdesc[0] & 0x7F in exheader (or 80 if the latter is 0).
|
||||
*/
|
||||
Result PMAPP_SetAppResourceLimit(s64 cpuTime);
|
||||
|
||||
/**
|
||||
* @brief Gets the APPLICATION cputime reslimit.
|
||||
* @param[out] cpuTime Pointer to write the reslimit value to.
|
||||
*/
|
||||
Result PMAPP_GetAppResourceLimit(s64 *outCpuTime);
|
||||
|
41
libctru/include/3ds/services/pmdbg.h
Normal file
41
libctru/include/3ds/services/pmdbg.h
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @file pmdbg.h
|
||||
* @brief PM (Process Manager) debug service.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <3ds/services/pmapp.h>
|
||||
|
||||
/// Initializes pm:dbg.
|
||||
Result pmDbgInit(void);
|
||||
|
||||
/// Exits pm:dbg.
|
||||
void pmDbgExit(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the current pm:dbg session handle.
|
||||
* @return The current pm:dbg session handle.
|
||||
*/
|
||||
Handle *pmDbgGetSessionHandle(void);
|
||||
|
||||
/**
|
||||
* @brief Enqueues an application for debug after setting cpuTime to 0, and returns a debug handle to it.
|
||||
* If another process was enqueued, this just calls @ref RunQueuedProcess instead.
|
||||
* @param[out] Pointer to output the debug handle to.
|
||||
* @param programInfo Program information of the title.
|
||||
* @param launchFlags Flags to launch the title with.
|
||||
*/
|
||||
Result PMDBG_LaunchAppDebug(Handle *outDebug, const FS_ProgramInfo *programInfo, u32 launchFlags);
|
||||
|
||||
/**
|
||||
* @brief Launches an application for debug after setting cpuTime to 0.
|
||||
* @param programInfo Program information of the title.
|
||||
* @param launchFlags Flags to launch the title with.
|
||||
*/
|
||||
Result PMDBG_LaunchApp(const FS_ProgramInfo *programInfo, u32 launchFlags);
|
||||
|
||||
/**
|
||||
* @brief Runs the queued process and returns a debug handle to it.
|
||||
* @param[out] Pointer to output the debug handle to.
|
||||
*/
|
||||
Result PMDBG_RunQueuedProcess(Handle *outDebug);
|
@ -1,151 +0,0 @@
|
||||
#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/pm.h>
|
||||
#include <3ds/ipc.h>
|
||||
|
||||
static Handle pmHandle;
|
||||
static int pmRefCount;
|
||||
|
||||
Result pmInit(void)
|
||||
{
|
||||
Result res;
|
||||
if (AtomicPostIncrement(&pmRefCount)) return 0;
|
||||
res = srvGetServiceHandle(&pmHandle, "pm:app");
|
||||
if (R_FAILED(res)) AtomicDecrement(&pmRefCount);
|
||||
return res;
|
||||
}
|
||||
|
||||
void pmExit(void)
|
||||
{
|
||||
if (AtomicDecrement(&pmRefCount)) return;
|
||||
svcCloseHandle(pmHandle);
|
||||
}
|
||||
|
||||
Result PM_LaunchTitle(u8 mediatype, u64 titleid, u32 launch_flags)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x1,5,0); // 0x10140
|
||||
cmdbuf[1] = titleid & 0xffffffff;
|
||||
cmdbuf[2] = (titleid >> 32) & 0xffffffff;
|
||||
cmdbuf[3] = mediatype;
|
||||
cmdbuf[4] = 0x0;
|
||||
cmdbuf[5] = launch_flags;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PM_LaunchFIRMSetParams(u32 firm_titleid_low, u32 size, u8* in)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x2,2,2); // 0x20082
|
||||
cmdbuf[1] = firm_titleid_low;
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = IPC_Desc_Buffer(size,IPC_BUFFER_R);
|
||||
cmdbuf[4] = (u32)in;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PM_TerminateCurrentApplication(u64 timeout)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x3,2,0); // 0x30080
|
||||
cmdbuf[1] = timeout & 0xffffffff;
|
||||
cmdbuf[2] = (timeout >> 32) & 0xffffffff;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PM_TerminateProcess(u8 pid, u64 timeout)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x5,3,0); // 0x500C0
|
||||
cmdbuf[1] = pid;
|
||||
cmdbuf[2] = timeout & 0xffffffff;
|
||||
cmdbuf[3] = (timeout >> 32) & 0xffffffff;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PM_GetFIRMLaunchParams(u32 size, u8* out)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x7,1,2); // 0x70042
|
||||
cmdbuf[1] = size;
|
||||
cmdbuf[2] = IPC_Desc_Buffer(size,IPC_BUFFER_W);
|
||||
cmdbuf[3] = (u32)out;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PM_GetTitleExheaderFlags(u8 mediatype, u64 titleid, u8* out)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x8,4,0); // 0x80100
|
||||
cmdbuf[1] = titleid & 0xffffffff;
|
||||
cmdbuf[2] = (titleid >> 32) & 0xffffffff;
|
||||
cmdbuf[3] = mediatype;
|
||||
cmdbuf[4] = 0x0;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
memcpy(out, (u8*)(&cmdbuf[2]), 8);
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PM_SetFIRMLaunchParams(u32 size, u8* in)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x9,1,2); // 0x90042
|
||||
cmdbuf[1] = size;
|
||||
cmdbuf[2] = IPC_Desc_Buffer(size,IPC_BUFFER_R);
|
||||
cmdbuf[3] = (u32)in;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PM_UnregisterProcess(u64 tid)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0xC,0,0); // 0xC0000
|
||||
cmdbuf[1] = tid & 0xffffffff;
|
||||
cmdbuf[2] = (tid >> 32) & 0xffffffff;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
232
libctru/source/services/pmapp.c
Normal file
232
libctru/source/services/pmapp.c
Normal file
@ -0,0 +1,232 @@
|
||||
#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/pmapp.h>
|
||||
#include <3ds/ipc.h>
|
||||
|
||||
static Handle pmAppHandle;
|
||||
static int pmAppRefcount;
|
||||
|
||||
Result pmAppInit(void)
|
||||
{
|
||||
Result res;
|
||||
if (AtomicPostIncrement(&pmAppRefcount)) return 0;
|
||||
res = srvGetServiceHandle(&pmAppHandle, "pm:app");
|
||||
if (R_FAILED(res)) AtomicDecrement(&pmAppRefcount);
|
||||
return res;
|
||||
}
|
||||
|
||||
void pmAppExit(void)
|
||||
{
|
||||
if (AtomicDecrement(&pmAppRefcount)) return;
|
||||
svcCloseHandle(pmAppHandle);
|
||||
}
|
||||
|
||||
Handle *pmAppGetSessionHandle(void)
|
||||
{
|
||||
return &pmAppHandle;
|
||||
}
|
||||
|
||||
Result PMAPP_LaunchTitle(const FS_ProgramInfo *programInfo, u32 launchFlags)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x1, 5, 0); // 0x10140
|
||||
memcpy(&cmdbuf[1], programInfo, sizeof(FS_ProgramInfo));
|
||||
cmdbuf[5] = launchFlags;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_LaunchFIRMSetParams(u32 firmTidLow, u32 size, const void* in)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x2, 2, 2); // 0x20082
|
||||
cmdbuf[1] = firmTidLow;
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = IPC_Desc_Buffer(size, IPC_BUFFER_R);
|
||||
cmdbuf[4] = (u32)in;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_TerminateCurrentApplication(s64 timeout)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x3, 2, 0); // 0x30080
|
||||
cmdbuf[1] = (u32)timeout;
|
||||
cmdbuf[2] = (u32)(timeout >> 32);
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_TerminateTitle(u64 titleId, s64 timeout)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x3, 4, 0); // 0x40100
|
||||
cmdbuf[1] = (u32)titleId;
|
||||
cmdbuf[2] = (u32)(titleId >> 32);
|
||||
cmdbuf[3] = (u32)timeout;
|
||||
cmdbuf[4] = (u32)(timeout >> 32);
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_TerminateProcess(u32 pid, s64 timeout)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x5, 3, 0); // 0x500C0
|
||||
cmdbuf[1] = pid;
|
||||
cmdbuf[2] = (u32)timeout;
|
||||
cmdbuf[3] = (u32)(timeout >> 32);
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_PrepareForReboot(s64 timeout)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x6, 2, 2); // 0x60082
|
||||
cmdbuf[1] = (u32)timeout;
|
||||
cmdbuf[2] = (u32)(timeout >> 32);
|
||||
cmdbuf[3] = IPC_Desc_CurProcessId();
|
||||
cmdbuf[4] = 0;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_GetFIRMLaunchParams(void *out, u32 size)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x7, 1, 2); // 0x70042
|
||||
cmdbuf[1] = size;
|
||||
cmdbuf[2] = IPC_Desc_Buffer(size, IPC_BUFFER_W);
|
||||
cmdbuf[3] = (u32)out;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_GetTitleExheaderFlags(ExHeader_Arm11CoreInfo* outCoreInfo, ExHeader_SystemInfoFlags* outSiFlags, const FS_ProgramInfo *programInfo)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x8, 4, 0); // 0x80100
|
||||
memcpy(&cmdbuf[1], programInfo, sizeof(FS_ProgramInfo));
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
memcpy(outCoreInfo, &cmdbuf[2], sizeof(ExHeader_Arm11CoreInfo));
|
||||
memcpy(outSiFlags, &cmdbuf[4], sizeof(ExHeader_SystemInfoFlags));
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_SetFIRMLaunchParams(u32 size, const void* in)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x9, 1, 2); // 0x90042
|
||||
cmdbuf[1] = size;
|
||||
cmdbuf[2] = IPC_Desc_Buffer(size, IPC_BUFFER_R);
|
||||
cmdbuf[3] = (u32)in;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_SetAppResourceLimit(s64 cpuTime)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0xA, 5, 0); // 0xA0140
|
||||
cmdbuf[1] = 0;
|
||||
cmdbuf[2] = RESLIMIT_CPUTIME;
|
||||
cmdbuf[3] = (u32)cpuTime;
|
||||
cmdbuf[4] = 0;
|
||||
cmdbuf[5] = 0;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_GetAppResourceLimit(s64 *outCpuTime)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0xB, 5, 0); // 0xB0140
|
||||
cmdbuf[1] = 0;
|
||||
cmdbuf[2] = RESLIMIT_CPUTIME;
|
||||
cmdbuf[3] = 0;
|
||||
cmdbuf[4] = 0;
|
||||
cmdbuf[5] = 0;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
*outCpuTime = cmdbuf[2] | ((s64)cmdbuf[3] << 32);
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_UnregisterProcess(u64 tid)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0xC, 0, 0); // 0xC0000
|
||||
cmdbuf[1] = (u32)tid;
|
||||
cmdbuf[2] = (u32)(tid >> 32);
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMAPP_LaunchTitleUpdate(const FS_ProgramInfo *programInfo, const FS_ProgramInfo *programInfoUpdate, u32 launchFlags)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0xD, 9, 0); // 0xD0240
|
||||
memcpy(&cmdbuf[1], programInfo, sizeof(FS_ProgramInfo));
|
||||
memcpy(&cmdbuf[5], programInfoUpdate, sizeof(FS_ProgramInfo));
|
||||
cmdbuf[9] = launchFlags;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmAppHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
74
libctru/source/services/pmdbg.c
Normal file
74
libctru/source/services/pmdbg.c
Normal file
@ -0,0 +1,74 @@
|
||||
#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/pmdbg.h>
|
||||
#include <3ds/ipc.h>
|
||||
|
||||
static Handle pmDbgHandle;
|
||||
static int pmDbgRefcount;
|
||||
|
||||
Result pmDbgInit(void)
|
||||
{
|
||||
Result res;
|
||||
if (AtomicPostIncrement(&pmDbgRefcount)) return 0;
|
||||
res = srvGetServiceHandle(&pmDbgHandle, "pm:dbg");
|
||||
if (R_FAILED(res)) AtomicDecrement(&pmDbgRefcount);
|
||||
return res;
|
||||
}
|
||||
|
||||
void pmDbgExit(void)
|
||||
{
|
||||
if (AtomicDecrement(&pmDbgRefcount)) return;
|
||||
svcCloseHandle(pmDbgHandle);
|
||||
}
|
||||
|
||||
Handle *pmDbgGetSessionHandle(void)
|
||||
{
|
||||
return &pmDbgHandle;
|
||||
}
|
||||
|
||||
Result PMDBG_LaunchAppDebug(Handle *outDebug, const FS_ProgramInfo *programInfo, u32 launchFlags)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x1, 5, 0); // 0x10140
|
||||
memcpy(&cmdbuf[1], programInfo, sizeof(FS_ProgramInfo));
|
||||
cmdbuf[5] = launchFlags;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmDbgHandle)))return ret;
|
||||
|
||||
*outDebug = cmdbuf[3];
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMDBG_LaunchApp(const FS_ProgramInfo *programInfo, u32 launchFlags)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x2, 5, 0); // 0x20140
|
||||
memcpy(&cmdbuf[1], programInfo, sizeof(FS_ProgramInfo));
|
||||
cmdbuf[5] = launchFlags;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmDbgHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PMDBG_RunQueuedProcess(Handle *outDebug)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x3, 0, 0); // 0x30000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmDbgHandle)))return ret;
|
||||
|
||||
*outDebug = cmdbuf[3];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
Loading…
Reference in New Issue
Block a user