diff --git a/stratosphere/loader/source/ldr_nso.cpp b/stratosphere/loader/source/ldr_nso.cpp index 2761dedf6..9472f3835 100644 --- a/stratosphere/loader/source/ldr_nso.cpp +++ b/stratosphere/loader/source/ldr_nso.cpp @@ -34,6 +34,14 @@ bool NsoUtils::IsNsoPresent(unsigned int index) { return g_nso_present[index]; } + +unsigned char *NsoUtils::GetNsoBuildId(unsigned int index) { + if (g_nso_present[index]) { + return g_nso_headers[index].build_id; + } + return NULL; +} + Result NsoUtils::LoadNsoHeaders(u64 title_id) { FILE *f_nso; @@ -234,6 +242,7 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo } } + /* Map in arguments. */ if (args != NULL && args_size) { u64 arg_map_addr = 0; if (R_FAILED((rc = MapUtils::LocateSpaceForMap(&arg_map_addr, extents->args_size)))) { @@ -259,5 +268,6 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo return rc; } } + return rc; } diff --git a/stratosphere/loader/source/ldr_nso.hpp b/stratosphere/loader/source/ldr_nso.hpp index 8424f7d25..2a2d8caf8 100644 --- a/stratosphere/loader/source/ldr_nso.hpp +++ b/stratosphere/loader/source/ldr_nso.hpp @@ -86,6 +86,7 @@ class NsoUtils { static FILE *OpenNso(unsigned int index, u64 title_id); static bool IsNsoPresent(unsigned int index); + static unsigned char *GetNsoBuildId(unsigned int index); static Result LoadNsoHeaders(u64 title_id); static Result ValidateNsoLoadSet(); static Result CalculateNsoLoadExtents(u32 addspace_type, u32 args_size, NsoLoadExtents *extents); diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index 59cf04ec0..e17abe9b1 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -92,6 +92,7 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc NsoUtils::NsoLoadExtents nso_extents = {0}; Registration::Process *target_process; Handle process_h = 0; + u64 process_id = 0; Result rc; /* Get the process from the registration queue. */ @@ -161,24 +162,35 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc /* Load all NSOs into Process memory, and set permissions accordingly. */ if (launch_item == NULL) { - NsoUtils::LoadNsosIntoProcessMemory(process_h, npdm_info.aci0->title_id, &nso_extents, (u8 *)launch_item->args, launch_item->arg_size); + rc = NsoUtils::LoadNsosIntoProcessMemory(process_h, npdm_info.aci0->title_id, &nso_extents, (u8 *)launch_item->args, launch_item->arg_size); } else { - NsoUtils::LoadNsosIntoProcessMemory(process_h, npdm_info.aci0->title_id, &nso_extents, NULL, 0); + rc = NsoUtils::LoadNsosIntoProcessMemory(process_h, npdm_info.aci0->title_id, &nso_extents, NULL, 0); + } + if (R_FAILED(rc)) { + svcCloseHandle(process_h); + goto CREATE_PROCESS_END; } - /* TODO: For each NSO, call svcMapProcessMemory, load the NSO into memory there (validating it), and then svcUnmapProcessMemory. */ - /* TODO: svcSetProcessMemoryPermission for each memory segment in the new process. */ + /* Update the list of registered processes with the new process. */ + svcGetProcessId(&process_id, process_h); + Registration::set_process_id_and_tid_min(index, process_id, npdm_info.aci0->title_id); + for (unsigned int i = 0; i < NSO_NUM_MAX; i++) { + if (NsoUtils::IsNsoPresent(i)) { + Registration::add_nso_info(index, nso_extents.nso_addresses[i], nso_extents.nso_sizes[i], NsoUtils::GetNsoBuildId(i)); + } + } - /* TODO: Map and load arguments to the process, if relevant. */ - - /* TODO: Update the list of registered processes with the new process. */ - - rc = 0; + rc = 0; CREATE_PROCESS_END: if (R_SUCCEEDED(rc)) { rc = ContentManagement::UnmountCode(); } else { ContentManagement::UnmountCode(); } + if (R_SUCCEEDED(rc)) { + *out_process_h = process_h; + } else { + svcCloseHandle(process_h); + } return rc; }