Use <string.h> & <3ds/exheader.h>, fix some bugs, etc.
also fix all warnings and use -Werror
This commit is contained in:
@@ -28,8 +28,8 @@ INCLUDES := include
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||
DEFINES := -DARM11 -D_3DS
|
||||
|
||||
CFLAGS := -g -std=gnu11 -Wall -Wextra -O2 -mword-relocations \
|
||||
-fomit-frame-pointer -ffunction-sections -fdata-sections -fno-builtin \
|
||||
CFLAGS := -g -std=gnu11 -Wall -Wextra -Werror -O2 -mword-relocations \
|
||||
-fomit-frame-pointer -ffunction-sections -fdata-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE)
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 reserved[5];
|
||||
u8 flag;
|
||||
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;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 programid;
|
||||
u32 firm;
|
||||
u8 flags[3];
|
||||
u8 priority;
|
||||
u16 resourcelimitdescriptor[0x10];
|
||||
exheader_storageinfo storageinfo;
|
||||
u64 serviceaccesscontrol[0x22];
|
||||
u8 reserved[0xf];
|
||||
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
|
||||
{
|
||||
// systemcontrol info {
|
||||
// coreinfo {
|
||||
exheader_codesetinfo codesetinfo;
|
||||
exheader_dependencylist deplist;
|
||||
// }
|
||||
exheader_systeminfo systeminfo;
|
||||
// }
|
||||
// accesscontrolinfo {
|
||||
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;
|
||||
@@ -14,16 +14,16 @@ static Result fsldrPatchPermissions(void)
|
||||
u32 pid;
|
||||
Result res;
|
||||
FS_ProgramInfo info;
|
||||
u32 storage[8] = {0};
|
||||
ExHeader_Arm11StorageInfo storage = {0};
|
||||
|
||||
storage[6] = 0x680; // SDMC access and NAND access flag
|
||||
// SDMC access and NAND access flags
|
||||
storage.fs_access_info = FSACCESS_NANDRW | FSACCESS_NANDRO_RO | FSACCESS_SDMC_RW;
|
||||
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);
|
||||
}
|
||||
|
||||
if(R_SUCCEEDED(res = svcGetProcessId(&pid, CUR_PROCESS_HANDLE)))
|
||||
res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, &storage);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -163,4 +163,4 @@ Result FSLDR_OpenDirectory(Handle* out, FS_Archive archive, FS_Path path)
|
||||
if(out) *out = cmdbuf[3];
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title)
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSREG_GetProgramInfo(exheader_header *exheader, u32 entry_count, u64 prog_handle)
|
||||
Result FSREG_GetProgramInfo(ExHeader *exheader, u32 entry_count, u64 prog_handle)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include "exheader.h"
|
||||
#include <3ds/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_GetProgramInfo(ExHeader *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);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <3ds.h>
|
||||
#include "memory.h"
|
||||
#include "patcher.h"
|
||||
#include "exheader.h"
|
||||
#include "ifile.h"
|
||||
#include "fsldr.h"
|
||||
#include "fsreg.h"
|
||||
@@ -30,7 +29,7 @@ typedef struct
|
||||
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 g_exheader;
|
||||
static char g_ret_buf[1024];
|
||||
|
||||
static inline void loadCFWInfo(void)
|
||||
@@ -184,10 +183,12 @@ static Result load_code(u64 progid, prog_addrs_t *shared, u64 prog_handle, int i
|
||||
}
|
||||
}
|
||||
|
||||
u16 progver = g_exheader.codesetinfo.flags.remasterversion[0] | (g_exheader.codesetinfo.flags.remasterversion[1] << 8);
|
||||
ExHeader_CodeSetInfo *csi = &g_exheader.info.sci.codeset_info;
|
||||
u16 progver = csi->flags.remaster_version;
|
||||
|
||||
// patch
|
||||
patchCode(progid, progver, (u8 *)shared->text_addr, shared->total_size << 12, g_exheader.codesetinfo.text.codesize, g_exheader.codesetinfo.ro.codesize, g_exheader.codesetinfo.data.codesize, g_exheader.codesetinfo.ro.address, g_exheader.codesetinfo.data.address);
|
||||
patchCode(progid, progver, (u8 *)shared->text_addr, shared->total_size << 12,
|
||||
csi->text.size, csi->rodata.size, csi->data.size, csi->rodata.address, csi->data.address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -207,7 +208,7 @@ static Result HBLDR_Init(Handle *session)
|
||||
return res;
|
||||
}
|
||||
|
||||
static Result loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
|
||||
static Result loader_GetProgramInfo(ExHeader *exheader, u64 prog_handle)
|
||||
{
|
||||
Result res;
|
||||
|
||||
@@ -236,13 +237,13 @@ static Result loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
|
||||
svcGetSystemInfo(&nbSection0Modules, 26, 0);
|
||||
|
||||
// Force always having sdmc:/ and nand:/rw permission
|
||||
exheader->arm11systemlocalcaps.storageinfo.accessinfo[0] |= 0x480;
|
||||
exheader->accessdesc.arm11systemlocalcaps.storageinfo.accessinfo[0] |= 0x480;
|
||||
exheader->info.aci.local_caps.storage_info.fs_access_info |= FSACCESS_SDMC_RW | FSACCESS_NANDRW;
|
||||
exheader->access_descriptor.acli.local_caps.storage_info.fs_access_info |= FSACCESS_SDMC_RW | FSACCESS_NANDRW;;
|
||||
|
||||
// Tweak 3dsx placeholder title exheader
|
||||
if (nbSection0Modules == 6)
|
||||
{
|
||||
if(exheader->arm11systemlocalcaps.programid == HBLDR_3DSX_TID)
|
||||
if(exheader->info.aci.local_caps.title_id == HBLDR_3DSX_TID)
|
||||
{
|
||||
Handle hbldr = 0;
|
||||
res = HBLDR_Init(&hbldr);
|
||||
@@ -260,11 +261,11 @@ static Result loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
|
||||
}
|
||||
}
|
||||
|
||||
u64 originalProgId = exheader->arm11systemlocalcaps.programid;
|
||||
if(CONFIG(PATCHGAMES) && loadTitleExheader(exheader->arm11systemlocalcaps.programid, exheader))
|
||||
u64 originalProgId = exheader->info.aci.local_caps.title_id;
|
||||
if(CONFIG(PATCHGAMES) && loadTitleExheader(exheader->info.aci.local_caps.title_id, exheader))
|
||||
{
|
||||
exheader->arm11systemlocalcaps.programid = originalProgId;
|
||||
exheader->accessdesc.arm11systemlocalcaps.programid = originalProgId;
|
||||
exheader->info.aci.local_caps.title_id = originalProgId;
|
||||
exheader->access_descriptor.acli.local_caps.title_id = originalProgId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +288,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
|
||||
u64 progid;
|
||||
|
||||
// make sure the cached info corrosponds to the current prog_handle
|
||||
if (g_cached_prog_handle != prog_handle || g_exheader.arm11systemlocalcaps.programid == HBLDR_3DSX_TID)
|
||||
if (g_cached_prog_handle != prog_handle || g_exheader.info.aci.local_caps.title_id == HBLDR_3DSX_TID)
|
||||
{
|
||||
res = loader_GetProgramInfo(&g_exheader, prog_handle);
|
||||
g_cached_prog_handle = prog_handle;
|
||||
@@ -302,7 +303,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
|
||||
flags = 0;
|
||||
for (count = 0; count < 28; count++)
|
||||
{
|
||||
desc = g_exheader.arm11kernelcaps.descriptors[count];
|
||||
desc = g_exheader.info.aci.kernel_caps.descriptors[count];
|
||||
if (0x1FE == desc >> 23)
|
||||
{
|
||||
flags = desc & 0xF00;
|
||||
@@ -314,7 +315,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
|
||||
}
|
||||
|
||||
// check for 3dsx process
|
||||
progid = g_exheader.arm11systemlocalcaps.programid;
|
||||
progid = g_exheader.info.aci.local_caps.title_id;
|
||||
if (progid == HBLDR_3DSX_TID)
|
||||
{
|
||||
Handle hbldr = 0;
|
||||
@@ -326,11 +327,11 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
|
||||
}
|
||||
u32* cmdbuf = getThreadCommandBuffer();
|
||||
cmdbuf[0] = IPC_MakeHeader(1,6,0);
|
||||
cmdbuf[1] = g_exheader.codesetinfo.text.address;
|
||||
cmdbuf[1] = g_exheader.info.sci.codeset_info.text.address;
|
||||
cmdbuf[2] = flags & 0xF00;
|
||||
cmdbuf[3] = progid;
|
||||
cmdbuf[4] = progid>>32;
|
||||
memcpy(&cmdbuf[5], g_exheader.codesetinfo.name, 8);
|
||||
memcpy(&cmdbuf[5], g_exheader.info.sci.codeset_info.name, 8);
|
||||
res = svcSendSyncRequest(hbldr);
|
||||
svcCloseHandle(hbldr);
|
||||
if (R_SUCCEEDED(res))
|
||||
@@ -343,19 +344,20 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
|
||||
return res;
|
||||
}
|
||||
codeset = (Handle)cmdbuf[3];
|
||||
res = svcCreateProcess(process, codeset, g_exheader.arm11kernelcaps.descriptors, count);
|
||||
res = svcCreateProcess(process, codeset, g_exheader.info.aci.kernel_caps.descriptors, count);
|
||||
svcCloseHandle(codeset);
|
||||
return res;
|
||||
}
|
||||
|
||||
// allocate process memory
|
||||
vaddr.text_addr = g_exheader.codesetinfo.text.address;
|
||||
vaddr.text_size = (g_exheader.codesetinfo.text.codesize + 4095) >> 12;
|
||||
vaddr.ro_addr = g_exheader.codesetinfo.ro.address;
|
||||
vaddr.ro_size = (g_exheader.codesetinfo.ro.codesize + 4095) >> 12;
|
||||
vaddr.data_addr = g_exheader.codesetinfo.data.address;
|
||||
vaddr.data_size = (g_exheader.codesetinfo.data.codesize + 4095) >> 12;
|
||||
data_mem_size = (g_exheader.codesetinfo.data.codesize + g_exheader.codesetinfo.bsssize + 4095) >> 12;
|
||||
ExHeader_CodeSetInfo *csi = &g_exheader.info.sci.codeset_info;
|
||||
vaddr.text_addr = csi->text.address;
|
||||
vaddr.text_size = (csi->text.size + 4095) >> 12;
|
||||
vaddr.ro_addr = csi->rodata.address;
|
||||
vaddr.ro_size = (csi->rodata.size + 4095) >> 12;
|
||||
vaddr.data_addr = csi->data.address;
|
||||
vaddr.data_size = (csi->data.size + 4095) >> 12;
|
||||
data_mem_size = (csi->data.size + csi->bss_size + 4095) >> 12;
|
||||
vaddr.total_size = vaddr.text_size + vaddr.ro_size + vaddr.data_size;
|
||||
if ((res = allocate_shared_mem(&shared_addr, &vaddr, flags)) < 0)
|
||||
{
|
||||
@@ -363,9 +365,9 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
|
||||
}
|
||||
|
||||
// load code
|
||||
if ((res = load_code(progid, &shared_addr, prog_handle, g_exheader.codesetinfo.flags.flag & 1)) >= 0)
|
||||
if ((res = load_code(progid, &shared_addr, prog_handle, csi->flags.compress_exefs_code)) >= 0)
|
||||
{
|
||||
memcpy(&codesetinfo.name, g_exheader.codesetinfo.name, 8);
|
||||
memcpy(&codesetinfo.name, csi->name, 8);
|
||||
codesetinfo.program_id = progid;
|
||||
codesetinfo.text_addr = vaddr.text_addr;
|
||||
codesetinfo.text_size = vaddr.text_size;
|
||||
@@ -379,7 +381,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
|
||||
res = svcCreateCodeSet(&codeset, &codesetinfo, (void *)shared_addr.text_addr, (void *)shared_addr.ro_addr, (void *)shared_addr.data_addr);
|
||||
if (res >= 0)
|
||||
{
|
||||
res = svcCreateProcess(process, codeset, g_exheader.arm11kernelcaps.descriptors, count);
|
||||
res = svcCreateProcess(process, codeset, g_exheader.info.aci.kernel_caps.descriptors, count);
|
||||
svcCloseHandle(codeset);
|
||||
if (res >= 0)
|
||||
{
|
||||
@@ -515,7 +517,7 @@ static void handle_commands(void)
|
||||
case 4: // GetProgramInfo
|
||||
{
|
||||
prog_handle = *(u64 *)&cmdbuf[1];
|
||||
if (prog_handle != g_cached_prog_handle || g_exheader.arm11systemlocalcaps.programid == HBLDR_3DSX_TID)
|
||||
if (prog_handle != g_cached_prog_handle || g_exheader.info.aci.local_caps.title_id == HBLDR_3DSX_TID)
|
||||
{
|
||||
res = loader_GetProgramInfo(&g_exheader, prog_handle);
|
||||
if (res >= 0)
|
||||
@@ -582,7 +584,7 @@ void __appExit()
|
||||
void __sync_init();
|
||||
void __sync_fini();
|
||||
void __system_initSyscalls();
|
||||
|
||||
|
||||
void __ctru_exit()
|
||||
{
|
||||
void __libc_fini_array(void);
|
||||
@@ -669,7 +671,7 @@ int main()
|
||||
g_active_handles--;
|
||||
reply_target = 0;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
svcBreak(USERBREAK_ASSERT);
|
||||
}
|
||||
|
||||
@@ -1,36 +1,5 @@
|
||||
#include "memory.h"
|
||||
|
||||
void memcpy(void *dest, const void *src, u32 size)
|
||||
{
|
||||
u8 *destc = (u8 *)dest;
|
||||
const u8 *srcc = (const u8 *)src;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
destc[i] = srcc[i];
|
||||
}
|
||||
|
||||
void memset32(void *dest, u32 filler, u32 size)
|
||||
{
|
||||
u32 *dest32 = (u32 *)dest;
|
||||
|
||||
for(u32 i = 0; i < size / 4; i++)
|
||||
dest32[i] = filler;
|
||||
}
|
||||
|
||||
int memcmp(const void *buf1, const void *buf2, u32 size)
|
||||
{
|
||||
const u8 *buf1c = (const u8 *)buf1,
|
||||
*buf2c = (const u8 *)buf2;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
{
|
||||
int cmp = buf1c[i] - buf2c[i];
|
||||
if(cmp != 0) return cmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Boyer-Moore Horspool algorithm, adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180
|
||||
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
|
||||
{
|
||||
@@ -54,4 +23,4 @@ u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <string.h>
|
||||
|
||||
void memcpy(void *dest, const void *src, u32 size);
|
||||
void memset32(void *dest, u32 filler, u32 size);
|
||||
int memcmp(const void *buf1, const void *buf2, u32 size);
|
||||
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize);
|
||||
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize);
|
||||
|
||||
@@ -356,7 +356,7 @@ error:
|
||||
while(true);
|
||||
}
|
||||
|
||||
bool loadTitleExheader(u64 progId, exheader_header *exheader)
|
||||
bool loadTitleExheader(u64 progId, ExHeader *exheader)
|
||||
{
|
||||
/* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/exheader.bin"
|
||||
If it exists it should be a decrypted exheader */
|
||||
@@ -370,7 +370,7 @@ bool loadTitleExheader(u64 progId, exheader_header *exheader)
|
||||
|
||||
u64 fileSize;
|
||||
|
||||
if(R_FAILED(IFile_GetSize(&file, &fileSize)) || fileSize != sizeof(exheader_header)) goto error;
|
||||
if(R_FAILED(IFile_GetSize(&file, &fileSize)) || fileSize != sizeof(ExHeader)) goto error;
|
||||
else
|
||||
{
|
||||
u64 total;
|
||||
@@ -715,7 +715,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 ro
|
||||
//Patch N3DS CPU Clock and L2 cache setting
|
||||
*(off - 4) = *(off - 3);
|
||||
*(off - 3) = *(off - 1);
|
||||
memcpy(off - 1, off, 16);
|
||||
memmove(off - 1, off, 16);
|
||||
*(off + 3) = 0xE3800000 | cpuSetting;
|
||||
}
|
||||
}
|
||||
@@ -736,7 +736,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 ro
|
||||
for(end = start + 8; *(u32 *)end != 0xCC010000; end += 8)
|
||||
if(end >= roStart + roSize - 12) goto error;
|
||||
|
||||
memset32(start, 0, end - start);
|
||||
memset(start, 0, end - start);
|
||||
}
|
||||
|
||||
s64 nbSection0Modules;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include "exheader.h"
|
||||
#include <3ds/exheader.h>
|
||||
#include "ifile.h"
|
||||
|
||||
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
||||
@@ -44,4 +44,4 @@ extern bool isN3DS, needToInitSd, isSdMode;
|
||||
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 roSize, u32 dataSize, u32 roAddress, u32 dataAddress);
|
||||
Result fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags);
|
||||
bool loadTitleCodeSection(u64 progId, u8 *code, u32 size);
|
||||
bool loadTitleExheader(u64 progId, exheader_header *exheader);
|
||||
bool loadTitleExheader(u64 progId, ExHeader *exheader);
|
||||
|
||||
@@ -43,7 +43,7 @@ Result PXIPM_RegisterProgram(u64 *prog_handle, FS_ProgramInfo *title, FS_Program
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result PXIPM_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
|
||||
Result PXIPM_GetProgramInfo(ExHeader *exheader, u64 prog_handle)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#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 *exheader, u64 prog_handle);
|
||||
Result PXIPM_UnregisterProgram(u64 prog_handle);
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
#include "strings.h"
|
||||
|
||||
size_t strnlen(const char *string, size_t maxlen)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
for(size = 0; *string && size < maxlen; string++, size++);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void progIdToStr(char *strEnd, u64 progId)
|
||||
{
|
||||
while(progId > 0)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <string.h>
|
||||
|
||||
size_t strnlen(const char *string, size_t maxlen);
|
||||
void progIdToStr(char *strEnd, u64 progId);
|
||||
|
||||
Reference in New Issue
Block a user