This repository has been archived on 2022-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
Luma3DS-3GX/sysmodules/pm/source/info.c

139 lines
4.0 KiB
C

#include <3ds.h>
#include <string.h>
#include "exheader_info_heap.h"
#include "manager.h"
#include "info.h"
#include "util.h"
Result registerProgram(u64 *programHandle, const FS_ProgramInfo *programInfo, const FS_ProgramInfo *programInfoUpdate)
{
FS_ProgramInfo pi = *programInfo, piu = *programInfoUpdate;
Result res = 0;
if (IS_N3DS) {
pi.programId = (pi.programId & ~N3DS_TID_MASK) | N3DS_TID_BIT;
piu.programId = (piu.programId & ~N3DS_TID_MASK) | N3DS_TID_BIT;
res = LOADER_RegisterProgram(programHandle, &pi, &piu);
if (R_FAILED(res)) {
pi.programId &= ~N3DS_TID_MASK;
piu.programId &= ~N3DS_TID_MASK;
res = LOADER_RegisterProgram(programHandle, &pi, &piu);
}
} else {
res = LOADER_RegisterProgram(programHandle, &pi, &piu);
}
return res;
}
Result getAndListDependencies(u64 *dependencies, u32 *numDeps, ProcessData *process, ExHeader_Info *exheaderInfo)
{
Result res = 0;
TRY(LOADER_GetProgramInfo(exheaderInfo, process->programHandle));
return listDependencies(dependencies, numDeps, exheaderInfo);
}
Result listDependencies(u64 *dependencies, u32 *numDeps, const ExHeader_Info *exheaderInfo)
{
Result res = 0;
u32 num = 0;
for (u32 i = 0; i < 48 && exheaderInfo->sci.dependencies[i] != 0; i++) {
u64 titleId = exheaderInfo->sci.dependencies[i];
if (IS_N3DS || (titleId & N3DS_TID_MASK) == 0) {
// On O3DS, ignore N3DS titles.
// Then (on both) remove the N3DS titleId bits
dependencies[num++] = titleId & ~N3DS_TID_MASK;
}
}
*numDeps = num;
return res;
}
Result listMergeUniqueDependencies(ProcessData **procs, u64 *dependencies, u32 *remrefcounts, u32 *numDeps, const ExHeader_Info *exheaderInfo)
{
Result res = 0;
u32 numDepsUnique = *numDeps;
u32 num2;
u64 deps[48];
u32 newrefcounts[48] = {0};
TRY(listDependencies(deps, &num2, exheaderInfo));
ProcessList_Lock(&g_manager.processList);
for (u32 i = 0; i < num2; i++) {
// Filter duplicate results
u32 j;
for (j = 0; j < numDepsUnique && deps[i] != dependencies[j]; j++);
if (j >= numDepsUnique) {
if (numDepsUnique >= 48) {
panic(2);
}
dependencies[numDepsUnique] = deps[i];
newrefcounts[numDepsUnique] = 1;
procs[numDepsUnique] = ProcessList_FindProcessByTitleId(&g_manager.processList, deps[i]);
numDepsUnique++;
} else {
++newrefcounts[j];
}
}
// Apply refcounts
for (u32 i = 0; i < numDepsUnique; i++) {
if (procs[i] != NULL) {
ProcessData_Incref(procs[i], newrefcounts[i]);
} else {
remrefcounts[i] += newrefcounts[i];
}
}
ProcessList_Unlock(&g_manager.processList);
*numDeps = numDepsUnique;
return res;
}
Result GetTitleExHeaderFlags(ExHeader_Arm11CoreInfo *outCoreInfo, ExHeader_SystemInfoFlags *outSiFlags, const FS_ProgramInfo *programInfo)
{
Result res = 0;
u64 programHandle = 0;
if (g_manager.preparingForReboot) {
return 0xC8A05801;
}
ExHeader_Info *exheaderInfo = ExHeaderInfoHeap_New();
if (exheaderInfo == NULL) {
panic(0);
}
res = registerProgram(&programHandle, programInfo, programInfo);
if (R_SUCCEEDED(res))
{
res = LOADER_GetProgramInfo(exheaderInfo, programHandle);
if (R_SUCCEEDED(res)) {
*outCoreInfo = exheaderInfo->aci.local_caps.core_info;
*outSiFlags = exheaderInfo->sci.codeset_info.flags;
}
LOADER_UnregisterProgram(programHandle);
}
ExHeaderInfoHeap_Delete(exheaderInfo);
return res;
}
Result GetCurrentAppTitleId(u64 *outTitleId)
{
if (g_manager.runningApplicationData != NULL) {
*outTitleId = g_manager.runningApplicationData->titleId;
return 0;
} else {
*outTitleId = 0;
return MAKERESULT(RL_TEMPORARY, RS_NOTFOUND, RM_PM, 0x100);
}
}