2016-03-29 17:43:53 +02:00
|
|
|
#include <3ds.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "fsreg.h"
|
|
|
|
#include "srvsys.h"
|
|
|
|
|
|
|
|
static Handle fsregHandle;
|
|
|
|
static int fsregRefCount;
|
|
|
|
|
|
|
|
Result fsregInit(void)
|
|
|
|
{
|
|
|
|
Result ret = 0;
|
|
|
|
|
|
|
|
if (AtomicPostIncrement(&fsregRefCount)) return 0;
|
|
|
|
|
|
|
|
ret = srvSysGetServiceHandle(&fsregHandle, "fs:REG");
|
|
|
|
|
|
|
|
if (R_FAILED(ret)) AtomicDecrement(&fsregRefCount);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void fsregExit(void)
|
|
|
|
{
|
|
|
|
if (AtomicDecrement(&fsregRefCount)) return;
|
|
|
|
svcCloseHandle(fsregHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
Result FSREG_CheckHostLoadId(u64 prog_handle)
|
|
|
|
{
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x406,2,0); // 0x4060080
|
|
|
|
cmdbuf[1] = (u32) (prog_handle);
|
|
|
|
cmdbuf[2] = (u32) (prog_handle >> 32);
|
|
|
|
|
|
|
|
Result ret = 0;
|
|
|
|
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle))) return ret;
|
|
|
|
|
|
|
|
return cmdbuf[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title)
|
|
|
|
{
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x404,4,0); // 0x4040100
|
|
|
|
memcpy(&cmdbuf[1], &title->programId, sizeof(u64));
|
|
|
|
*(u8 *)&cmdbuf[3] = title->mediaType;
|
|
|
|
memcpy(((u8 *)&cmdbuf[3])+1, &title->padding, 7);
|
|
|
|
|
|
|
|
Result ret = 0;
|
|
|
|
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle))) return ret;
|
|
|
|
*prog_handle = *(u64 *)&cmdbuf[2];
|
|
|
|
|
|
|
|
return cmdbuf[1];
|
|
|
|
}
|
|
|
|
|
2018-05-24 00:55:38 +02:00
|
|
|
Result FSREG_GetProgramInfo(ExHeader *exheader, u32 entry_count, u64 prog_handle)
|
2016-03-29 17:43:53 +02:00
|
|
|
{
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x403,3,0); // 0x40300C0
|
|
|
|
cmdbuf[1] = entry_count;
|
|
|
|
*(u64 *)&cmdbuf[2] = prog_handle;
|
|
|
|
cmdbuf[64] = ((entry_count << 10) << 14) | 2;
|
|
|
|
cmdbuf[65] = (u32) exheader;
|
|
|
|
|
|
|
|
Result ret = 0;
|
|
|
|
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle))) return ret;
|
|
|
|
|
|
|
|
return cmdbuf[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
Result FSREG_UnloadProgram(u64 prog_handle)
|
|
|
|
{
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x405,2,0); // 0x4050080
|
|
|
|
cmdbuf[1] = (u32) (prog_handle);
|
|
|
|
cmdbuf[2] = (u32) (prog_handle >> 32);
|
|
|
|
|
|
|
|
Result ret = 0;
|
|
|
|
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle))) return ret;
|
|
|
|
|
|
|
|
return cmdbuf[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
Result FSREG_Unregister(u32 pid)
|
|
|
|
{
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x402,1,0); // 0x4020040
|
|
|
|
cmdbuf[1] = pid;
|
|
|
|
|
|
|
|
Result ret = 0;
|
|
|
|
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle))) return ret;
|
|
|
|
|
|
|
|
return cmdbuf[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
Result FSREG_Register(u32 pid, u64 prog_handle, FS_ProgramInfo *info, void *storageinfo)
|
|
|
|
{
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x401,0xf,0); // 0x40103C0
|
|
|
|
cmdbuf[1] = pid;
|
|
|
|
*(u64 *)&cmdbuf[2] = prog_handle;
|
|
|
|
memcpy(&cmdbuf[4], &info->programId, sizeof(u64));
|
|
|
|
*(u8 *)&cmdbuf[6] = info->mediaType;
|
|
|
|
memcpy(((u8 *)&cmdbuf[6])+1, &info->padding, 7);
|
|
|
|
memcpy((u8 *)&cmdbuf[8], storageinfo, 32);
|
|
|
|
|
|
|
|
Result ret = 0;
|
|
|
|
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle))) return ret;
|
|
|
|
|
|
|
|
return cmdbuf[1];
|
|
|
|
}
|