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/<titleId>.<ips/bps> and only require "Load ext
firm/modules" option for it.
This commit is contained in:
TuxSH 2023-07-09 22:00:51 +02:00
parent 5b417189db
commit 9fa1d42aa8
3 changed files with 48 additions and 17 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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;