From 9fa1d42aa86b3a247fc8d94ee438f2a680f37cd3 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sun, 9 Jul 2023 22:00:51 +0200 Subject: [PATCH] Loader: make it simpler to load ext. modules by clearing N3DS bit And also move the location of IPS/BPS patches for (non-KIP) sysmodules to /luma/sysmodules/. and only require "Load ext firm/modules" option for it. --- sysmodules/loader/source/bps_patcher.cpp | 22 ++++++++++++--- sysmodules/loader/source/loader.c | 7 +++-- sysmodules/loader/source/patcher.c | 36 +++++++++++++++++------- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/sysmodules/loader/source/bps_patcher.cpp b/sysmodules/loader/source/bps_patcher.cpp index 0c8ca0a..7092c3c 100644 --- a/sysmodules/loader/source/bps_patcher.cpp +++ b/sysmodules/loader/source/bps_patcher.cpp @@ -247,11 +247,25 @@ private: static inline bool ApplyCodeBpsPatch(u64 prog_id, u8 *code, u32 size) { - char bps_path[] = "/luma/titles/0000000000000000/code.bps"; - progIdToStr(bps_path + 28, prog_id); + bool isSysmodule = (prog_id >> 32) == 0x00040130; util::File patch_file; - if(!patch_file.Open(bps_path, FS_OPEN_READ)) - return true; + + if (isSysmodule) + { + char bps_path[] = "/luma/sysmodules/0000000000000000.bps"; + prog_id &= ~0xF0000000ull; // clear N3DS bit + progIdToStr(bps_path + 32, prog_id); + if(!patch_file.Open(bps_path, FS_OPEN_READ)) + return true; + } + else + { + char bps_path[] = "/luma/titles/0000000000000000/code.bps"; + progIdToStr(bps_path + 28, prog_id); + if(!patch_file.Open(bps_path, FS_OPEN_READ)) + return true; + } + const u32 patch_size = u32(patch_file.GetSize().value_or(0)); // Temporarily use APPLICATION memory to store the source and patch data. diff --git a/sysmodules/loader/source/loader.c b/sysmodules/loader/source/loader.c index ab94287..721db7b 100644 --- a/sysmodules/loader/source/loader.c +++ b/sysmodules/loader/source/loader.c @@ -394,15 +394,16 @@ static Result RegisterProgram(u64 *programHandle, FS_ProgramInfo *title, FS_Prog bool loadedCxiFromStorage = false; if (IsSysmoduleId(titleId) && CONFIG(LOADEXTFIRMSANDMODULES)) { + u64 tid2 = titleId & ~0xF0000000ull; // Forbid having two such file handles being open at the same time // Also reload the file even if already cached. InvalidateCachedCxiFile(); - res = openSysmoduleCxi(&g_cached_sysmoduleCxiFile, titleId); + res = openSysmoduleCxi(&g_cached_sysmoduleCxiFile, tid2); if (R_SUCCEEDED(res)) { - // A .cxi with the correct name in /luma/sysmodule exists, proceed - *programHandle = SYSMODULE_CXI_COOKIE_MASK | (u32)titleId; + // A .cxi with the correct name in /luma/sysmodule exists, proceed (ignoring N3DS TID bits) + *programHandle = SYSMODULE_CXI_COOKIE_MASK | (u32)tid2; g_cached_sysmoduleCxiCookie = *programHandle; loadedCxiFromStorage = true; } diff --git a/sysmodules/loader/source/patcher.c b/sysmodules/loader/source/patcher.c index a7d0301..e427abd 100644 --- a/sysmodules/loader/source/patcher.c +++ b/sysmodules/loader/source/patcher.c @@ -265,12 +265,22 @@ static inline bool applyCodeIpsPatch(u64 progId, u8 *code, u32 size) /* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/code.ips" If it exists it should be an IPS format patch */ - char path[] = "/luma/titles/0000000000000000/code.ips"; - progIdToStr(path + 28, progId); - + bool isSysmodule = (progId >> 32) == 0x00040130; IFile file; - if(!openLumaFile(&file, path)) return true; + if (isSysmodule) + { + char path[] = "/luma/sysmodules/0000000000000000.ips"; + progId &= ~0xF0000000ull; // clear N3DS bit + progIdToStr(path + 32, progId); + if(!openLumaFile(&file, path)) return true; + } + else + { + char path[] = "/luma/titles/0000000000000000/code.ips"; + progIdToStr(path + 28, progId); + if(!openLumaFile(&file, path)) return true; + } bool ret = false; u8 buffer[5]; @@ -321,6 +331,7 @@ exit: Result openSysmoduleCxi(IFile *outFile, u64 progId) { + progId &= ~0xF0000000ull; // clear N3DS bit char path[] = "/luma/sysmodules/0000000000000000.cxi"; progIdToStr(path + sizeof("/luma/sysmodules/0000000000000000") - 2, progId); @@ -619,6 +630,10 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 ro progId == 0x000400300000A102LL || //CHN Home Menu progId == 0x000400300000B102LL; //TWN Home Menu + bool isApp = ((progId >> 32) & ~0x12) == 0x00040000; + bool isApplet = (progId >> 32) == 0x00040030; + bool isSysmodule = (progId >> 32) == 0x00040130; + if(isHomeMenu) { bool applyRegionFreePatch = true; @@ -909,14 +924,15 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 ro )) goto error; } + if (isSysmodule && CONFIG(LOADEXTFIRMSANDMODULES)) + { + if(!patcherApplyCodeBpsPatch(progId, code, size)) goto error; + if(!applyCodeIpsPatch(progId, code, size)) goto error; + } + if(CONFIG(PATCHGAMES)) { - bool isApp = ((progId >> 32) & ~0x12) == 0x00040000; - bool isApplet = (progId >> 32) == 0x00040030; - bool isSysmodule = (progId >> 32) == 0x00040130; - - bool shouldPatchIps = !isSysmodule || (isSysmodule && CONFIG(LOADEXTFIRMSANDMODULES)); - if (shouldPatchIps) + if (!isSysmodule) { if(!patcherApplyCodeBpsPatch(progId, code, size)) goto error; if(!applyCodeIpsPatch(progId, code, size)) goto error;