-SUBDIRS = libctr9 loader bits
+SUBDIRS = libctr9 ctrulib/libctru loader bits
install:
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
-LIBDIRS := $(CTRULIB)
+LIBDIRS := $(CURDIR)/../ctrulib/libctru
#---------------------------------------------------------------------------------
+++ /dev/null
-#ifndef __EXHEADER_H
-#define __EXHEADER_H
-
-#include <3ds/types.h>
-
-typedef struct
-{
- u32 text_addr;
- u32 text_size;
- u32 ro_addr;
- u32 ro_size;
- u32 data_addr;
- u32 data_size;
- u32 total_size;
-} prog_addrs_t;
-
-typedef struct
-{
- u8 reserved[5];
- u8 flag; // Maybe a feature - Bits 2-7 are unused. We could allow uh, custom flags here. Like zlib compression on code rather than lzss.
- u8 remasterversion[2];
-} PACKED exheader_systeminfoflags;
-
-typedef struct
-{
- u32 address;
- u32 nummaxpages;
- u32 codesize;
-} PACKED exheader_codesegmentinfo;
-
-typedef struct
-{
- u8 name[8];
- exheader_systeminfoflags flags;
- exheader_codesegmentinfo text;
- u8 stacksize[4];
- exheader_codesegmentinfo ro;
- u8 reserved[4];
- exheader_codesegmentinfo data;
- u32 bsssize;
-} PACKED exheader_codesetinfo;
-
-typedef struct
-{
- u64 programid[0x30];
-} PACKED exheader_dependencylist;
-
-typedef struct
-{
- u8 savedatasize[4];
- u8 reserved[4];
- u8 jumpid[8];
- u8 reserved2[0x30];
-} PACKED exheader_systeminfo;
-
-typedef struct
-{
- u8 extsavedataid[8];
- u8 systemsavedataid[8];
- u8 reserved[8];
- u8 accessinfo[7];
- u8 otherattributes;
-} PACKED exheader_storageinfo;
-
-// New3DS speed is flags[1]:1
-
-typedef struct
-{
- u64 programid;
- u8 coreVersion[4]; // Kernel version required for this.
- u8 flag2;
- u8 flag1;
- u8 flag0; // CPU speed settings.
- u8 priority;
- u16 resourcelimitdescriptor[0x10];
- exheader_storageinfo storageinfo;
- u64 serviceaccesscontrol[0x20];
- u8 reserved[0x1f];
- u8 resourcelimitcategory;
-} PACKED exheader_arm11systemlocalcaps;
-
-typedef struct
-{
- u32 descriptors[28];
- u8 reserved[0x10];
-} PACKED exheader_arm11kernelcapabilities;
-
-typedef struct
-{
- u8 descriptors[15];
- u8 descversion;
-} PACKED exheader_arm9accesscontrol;
-
-typedef struct
-{
- exheader_codesetinfo codesetinfo;
- exheader_dependencylist deplist;
- exheader_systeminfo systeminfo;
- exheader_arm11systemlocalcaps arm11systemlocalcaps;
- exheader_arm11kernelcapabilities arm11kernelcaps;
- exheader_arm9accesscontrol arm9accesscontrol;
- struct
- {
- u8 signature[0x100];
- u8 ncchpubkeymodulus[0x100];
- exheader_arm11systemlocalcaps arm11systemlocalcaps;
- exheader_arm11kernelcapabilities arm11kernelcaps;
- exheader_arm9accesscontrol arm9accesscontrol;
- } PACKED accessdesc;
-} PACKED exheader_header;
-
-#endif
+++ /dev/null
-/**
- * Random annoyance; All the command headers etc for fsLdr are EXACTLY the same as fsUser.
- * This is annpying mainly because - if I could open the file handle manually in ctrulib -
- * e.g. not static and inaccessible - I could simply use the FSUSER API for this. ALL. OF. THIS.
- */
-#include <3ds.h>
-#include "fsldr.h"
-#include "fsreg.h"
-#include "srvsys.h"
-
-static Handle fsldrHandle;
-static int fsldrRefCount;
-
-// MAKE SURE fsreg has been init before calling this
-static Result
-fsldrPatchPermissions(void)
-{
- u32 pid;
- Result res;
- FS_ProgramInfo info;
- u32 storage[8] = { 0 };
-
- storage[6] = 0x680; // SDMC access and NAND access flag
- info.programId = 0x0004013000001302LL; // loader PID
- info.mediaType = MEDIATYPE_NAND;
- res = svcGetProcessId(&pid, 0xFFFF8001);
- if (R_SUCCEEDED(res)) {
- res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, (u8 *)storage);
- }
- return res;
-}
-
-Result
-fsldrInit(void)
-{
- Result ret = 0;
-
- if (AtomicPostIncrement(&fsldrRefCount))
- return 0;
-
- ret = srvSysGetServiceHandle(&fsldrHandle, "fs:LDR");
- if (R_SUCCEEDED(ret)) {
- fsldrPatchPermissions();
- ret = FSLDR_Initialize(fsldrHandle);
- if (R_FAILED(ret))
- svcBreak(USERBREAK_ASSERT); // Can't properly panic here; no logger
- } else {
- AtomicDecrement(&fsldrRefCount);
- }
-
- return ret;
-}
-
-void
-fsldrExit(void)
-{
- if (AtomicDecrement(&fsldrRefCount))
- return;
- svcCloseHandle(fsldrHandle);
-}
-
-Result
-FSLDR_Initialize(Handle session)
-{
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0x801, 0, 2); // 0x8010002
- cmdbuf[1] = 32;
-
- Result ret = 0;
- if (R_FAILED(ret = svcSendSyncRequest(session)))
- return ret;
-
- return cmdbuf[1];
-}
-
-Result
-FSLDR_OpenFileDirectly(Handle *out, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 openFlags, u32 attributes)
-{
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0x803, 8, 4); // 0x8030204
- cmdbuf[1] = 0;
- cmdbuf[2] = archiveId;
- cmdbuf[3] = archivePath.type;
- cmdbuf[4] = archivePath.size;
- cmdbuf[5] = filePath.type;
- cmdbuf[6] = filePath.size;
- cmdbuf[7] = openFlags;
- cmdbuf[8] = attributes;
- cmdbuf[9] = IPC_Desc_StaticBuffer(archivePath.size, 2);
- cmdbuf[10] = (u32)archivePath.data;
- cmdbuf[11] = IPC_Desc_StaticBuffer(filePath.size, 0);
- cmdbuf[12] = (u32)filePath.data;
-
- Result ret = 0;
- if (R_FAILED(ret = svcSendSyncRequest(fsldrHandle)))
- return ret;
-
- if (out)
- *out = cmdbuf[3];
-
- return cmdbuf[1];
-}
-
-Result
-FSLDR_GetNandCid(u8* out, u32 length)
-{
- u32 *cmdbuf = getThreadCommandBuffer();
-
- cmdbuf[0] = IPC_MakeHeader(0x81A, 1, 2); // 0x81A0042
- cmdbuf[1] = length;
- cmdbuf[2] = IPC_Desc_Buffer(length, IPC_BUFFER_W);
- cmdbuf[3] = (u32) out;
-
- Result ret = 0;
- if(R_FAILED(ret = svcSendSyncRequest(fsldrHandle)))
- return ret;
-
- return cmdbuf[1];
-}
+++ /dev/null
-#ifndef __FSLDR_H
-#define __FSLDR_H
-
-#include <3ds/types.h>
-
-Result fsldrInit(void);
-void fsldrExit(void);
-
-Result FSLDR_Initialize(Handle session);
-Result FSLDR_SetPriority(u32 priority);
-Result FSLDR_OpenFileDirectly(Handle *out, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 openFlags, u32 attributes);
-Result FSLDR_GetNandCid(u8* out, u32 length);
-
-#endif
+++ /dev/null
-#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];
-}
-
-Result
-FSREG_GetProgramInfo(exheader_header *exheader, u32 entry_count, u64 prog_handle)
-{
- 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];
-}
+++ /dev/null
-#ifndef __FSREG_H
-#define __FSREG_H
-
-#include <3ds/types.h>
-#include "exheader.h"
-
-Result fsregInit(void);
-void fsregExit(void);
-Result FSREG_CheckHostLoadId(u64 prog_handle);
-Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title);
-Result FSREG_GetProgramInfo(exheader_header *exheader, u32 entry_count, u64 prog_handle);
-Result FSREG_UnloadProgram(u64 prog_handle);
-Result FSREG_Unregister(u32 pid);
-Result FSREG_Register(u32 pid, u64 prog_handle, FS_ProgramInfo *info, void *storageinfo);
-
-#endif
#include <3ds.h>
#include <stdlib.h>
#include "patcher.h"
-#include "exheader.h"
-#include "fsldr.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <3ds.h>
#include "patcher.h"
-#include "exheader.h"
-#include "fsldr.h"
-#include "fsreg.h"
#include "pxipm.h"
-#include "srvsys.h"
#include <lzss.c>
#include <string.h>
#include <stdio.h>
static Handle g_handles[MAX_SESSIONS + 2];
static int g_active_handles;
static u64 g_cached_prog_handle;
-static exheader_header g_exheader;
+static EXHEADER_header g_exheader;
static char g_ret_buf[1024];
static Result
-allocate_shared_mem(prog_addrs_t *shared, prog_addrs_t *vaddr, int flags)
+allocate_shared_mem(EXHEADER_prog_addrs *shared, EXHEADER_prog_addrs *vaddr, int flags)
{
// Somehow, we need to allow reallocating.
u32 dummy;
- memcpy(shared, vaddr, sizeof(prog_addrs_t));
+ memcpy(shared, vaddr, sizeof(EXHEADER_prog_addrs));
shared->text_addr = 0x10000000; // Base virtual address for code.
shared->ro_addr = shared->text_addr + (shared->text_size << 12);
shared->data_addr = shared->ro_addr + (shared->ro_size << 12);
}
static Result
-load_code(u64 progid, u16 progver, prog_addrs_t *shared, prog_addrs_t *original, u64 prog_handle, int is_compressed)
+load_code(u64 progid, u16 progver, EXHEADER_prog_addrs *shared, EXHEADER_prog_addrs *original, u64 prog_handle, int is_compressed)
{
Handle handle;
FS_Path archivePath;
path.data = CODE_PATH;
path.size = sizeof(CODE_PATH);
- if (R_FAILED(FSLDR_OpenFileDirectly(&handle, ARCHIVE_SAVEDATA_AND_CONTENT2, archivePath, path, FS_OPEN_READ, 0))) {
+ if (R_FAILED(FSUSER_OpenFileDirectly(&handle, ARCHIVE_SAVEDATA_AND_CONTENT2, archivePath, path, FS_OPEN_READ, 0))) {
panicstr("Failed to open program code path.\n");
}
}
static Result
-loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
+loader_GetProgramInfo(EXHEADER_header *exheader, u64 prog_handle)
{
Result res;
u32 flags;
u32 desc;
u32 dummy;
- prog_addrs_t shared_addr;
- prog_addrs_t vaddr;
- prog_addrs_t original_vaddr;
+ EXHEADER_prog_addrs shared_addr;
+ EXHEADER_prog_addrs vaddr;
+ EXHEADER_prog_addrs original_vaddr;
Handle codeset;
CodeSetInfo codesetinfo;
u32 data_mem_size;
u32 notid;
Result ret;
- ret = srvSysReceiveNotification(¬id);
+ ret = srvReceiveNotification(¬id);
if (R_FAILED(ret)) {
return ret;
}
srv_handle = &g_handles[1];
notification_handle = &g_handles[0];
- if (R_FAILED(srvSysRegisterService(srv_handle, "Loader", MAX_SESSIONS))) {
+ if (R_FAILED(srvRegisterService(srv_handle, "Loader", MAX_SESSIONS))) {
panicstr("Failed to register loader service.\n");
}
- if (R_FAILED(srvSysEnableNotification(notification_handle))) {
+ if (R_FAILED(srvEnableNotification(notification_handle))) {
panicstr("Failed to enable notifcations to loader service.\n");
}
}
} while (!term_request || g_active_handles != 2);
- srvSysUnregisterService("Loader");
+ srvUnregisterService("Loader");
svcCloseHandle(*srv_handle);
svcCloseHandle(*notification_handle);
#include <3ds.h>
#include "patcher.h"
-#include "fsldr.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <3ds.h>
#include <string.h>
#include "patcher.h"
-#include "fsldr.h"
#include <string.h>
#ifndef PATH_MAX
#include <3ds.h>
#include <string.h>
#include "patcher.h"
-#include "exheader.h"
-#include "fsldr.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
ppath.data = path;
ppath.size = strnlen(path, PATH_MAX) + 1;
- return FSLDR_OpenFileDirectly(file, id, apath, ppath, flags, 0);
+ return FSUSER_OpenFileDirectly(file, id, apath, ppath, flags, 0);
}
struct config_file config;
static u32 cid[4];
static char config_file_path[] = SYSCONFDIR "/config-00000000";
- if (!R_SUCCEEDED(FSLDR_GetNandCid((u8*)cid, 0x10))) {
+ if (!R_SUCCEEDED(FSUSER_GetNandCid((u8*)cid, 0x10))) {
return;
}
}
void
-code_handler(u64 progId, prog_addrs_t *shared)
+code_handler(u64 progId, EXHEADER_prog_addrs *shared)
{
// If configuration was not loaded, or both options (load / dump) are disabled
if (failed_load_config || (!config.options[OPTION_LOADER_DUMPCODE] && !config.options[OPTION_LOADER_LOADCODE]))
#define __PATCHER_H
#include <3ds/types.h>
-#include "exheader.h"
+#include <3ds/exheader.h>
void patch_exe(u64 progId, u16 progver, u8 *text, u32 text_size, u32 orig_text, u8 *data, u32 data_size, u32 orig_data, u8 *ro, u32 ro_size, u32 orig_ro);
-void code_handler(u64 progId, prog_addrs_t* shared);
+void code_handler(u64 progId, EXHEADER_prog_addrs* shared);
u32 get_text_extend(u64 progId, u16 progver, u32 size_orig);
u32 get_ro_extend(u64 progId, u16 progver, u32 size_orig);
}
Result
-PXIPM_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
+PXIPM_GetProgramInfo(EXHEADER_header *exheader, u64 prog_handle)
{
u32 *cmdbuf = getThreadCommandBuffer();
#define __PXIPM_H
#include <3ds/types.h>
-#include "exheader.h"
+#include <3ds/exheader.h>
Result pxipmInit(void);
void pxipmExit(void);
Result PXIPM_RegisterProgram(u64 *prog_handle, FS_ProgramInfo *title, FS_ProgramInfo *update);
-Result PXIPM_GetProgramInfo(exheader_header *exheader, u64 prog_handle);
+Result PXIPM_GetProgramInfo(EXHEADER_header *exheader, u64 prog_handle);
Result PXIPM_UnregisterProgram(u64 prog_handle);
#endif
#include <3ds.h>
#include "patcher.h"
-#include "exheader.h"
-#include "fsldr.h"
-#include "fsreg.h"
#include "pxipm.h"
-#include "srvsys.h"
#include <string.h>
#include "logger.h"
void
__appInit()
{
- srvSysInit();
+ srvInit();
fsregInit();
- fsldrInit();
+ fsInitFromService("fs:LDR");
pxipmInit();
}
__appExit()
{
pxipmExit();
- fsldrExit();
+ fsExit();
fsregExit();
- srvSysExit();
+ srvExit();
}
void __system_allocateHeaps(void) {