TuxSH 7074ac1166 Move hb:ldr from Rosalina to Loader
Let's not pretend in 2022 that it needed things from rosalina sysmodule
- it did not.

This moves 3DSX loading from Rosalina to Loader, and also removes all
the dependencies Loader had to other Luma3DS components (if kernel ext.
is missing, a default config will be used). This means that, as long as
you replace Loader to the one in here, you will be able to properly load
3DSX files.

Changes:
- hb:ldr is now hosted in loader
- hb:ldr LoadProcess, PatchExHeaderInfo, DebugNextApplicationByForce:
  all removed
- fix a bug where some malformed 3DSX files were not rejected
- grant access to CONFIG11 registers to 3DSX homebrew
- move dirty homebrew chainload (when HM. isn't loaded nor loadable) to
  pm
- pm:dbg (ext.) PrepareToChainloadHomebrew: removed
2022-12-25 23:27:48 +01:00

93 lines
2.8 KiB
C

#include <3ds.h>
#include <string.h>
#include "manager.h"
#include "reslimit.h"
#include "util.h"
#include "luma.h"
Manager g_manager;
static void giveAllFsArchiveAccessToKip(u32 pid, u64 tid)
{
static const ExHeader_Arm11StorageInfo storageInfo = {
.fs_access_info = 0xFFFFFFFF,
};
static const u64 programHandle = 0xFFFF000000000000LL;
FS_ProgramInfo info = {
.programId = tid,
.mediaType = MEDIATYPE_NAND,
};
assertSuccess(FSREG_Register(pid, programHandle, &info, &storageInfo));
}
void Manager_Init(void *procBuf, size_t numProc)
{
memset(&g_manager, 0, sizeof(Manager));
ProcessList_Init(&g_manager.processList, procBuf, numProc);
assertSuccess(svcCreateEvent(&g_manager.newProcessEvent, RESET_ONESHOT));
assertSuccess(svcCreateEvent(&g_manager.allNotifiedTerminationEvent , RESET_ONESHOT));
}
void Manager_RegisterKips(void)
{
s64 numKips = 0;
ProcessData *process;
Handle processHandle;
svcGetSystemInfo(&numKips, 26, 0);
ProcessList_Lock(&g_manager.processList);
for (u32 i = 0; i < (u32)numKips; i++) {
process = ProcessList_New(&g_manager.processList);
if (process == NULL) {
panic(1);
}
assertSuccess(svcOpenProcess(&processHandle, i));
process->handle = processHandle;
process->pid = i;
process->refcount = 1;
process->titleId = 0x0004000100001000ULL; // note: same internal TID for all builtins
process->flags = PROCESSFLAG_KIP;
process->terminationStatus = TERMSTATUS_RUNNING;
if (i < 5) {
// Exempt rosalina from being resource-limited at all
assertSuccess(svcSetProcessResourceLimits(processHandle, g_manager.reslimits[RESLIMIT_CATEGORY_OTHER]));
}
}
ProcessList_Unlock(&g_manager.processList);
// Give full archive access to us (PM) and Rosalina (real PIDs don't matter, they just have to be unique (?))
// Loader doesn't depend on PM and has its own fs:REG handle so it must do it itself.
giveAllFsArchiveAccessToKip(2, 0x0004013000001202LL); // PM
if (numKips > 5) {
giveAllFsArchiveAccessToKip(5, 0x0004013000006902LL); // Rosalina
}
}
Result UnregisterProcess(u64 titleId)
{
ProcessData *foundProcess = NULL;
ProcessList_Lock(&g_manager.processList);
foundProcess = ProcessList_FindProcessByTitleId(&g_manager.processList, titleId & ~N3DS_TID_MASK);
if (foundProcess != NULL) {
if (foundProcess == g_manager.runningApplicationData) {
g_manager.runningApplicationData = NULL;
}
if (foundProcess == g_manager.debugData) {
g_manager.debugData = NULL;
}
svcCloseHandle(foundProcess->handle);
ProcessList_Delete(&g_manager.processList, foundProcess);
}
ProcessList_Unlock(&g_manager.processList);
return 0;
}