diff --git a/stratosphere/loader/source/ldr_launch_queue.cpp b/stratosphere/loader/source/ldr_launch_queue.cpp index 6095c8572..94df49965 100644 --- a/stratosphere/loader/source/ldr_launch_queue.cpp +++ b/stratosphere/loader/source/ldr_launch_queue.cpp @@ -71,3 +71,12 @@ void LaunchQueue::clear() { g_launch_queue[i].tid = 0; } } + + +LaunchQueue::LaunchItem *LaunchQueue::get_item(u64 tid) { + int idx; + if ((idx = get_index(tid)) == LAUNCH_QUEUE_FULL) { + return NULL; + } + return &g_launch_queue[idx]; +} \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_launch_queue.hpp b/stratosphere/loader/source/ldr_launch_queue.hpp index bf85846db..cf90f951e 100644 --- a/stratosphere/loader/source/ldr_launch_queue.hpp +++ b/stratosphere/loader/source/ldr_launch_queue.hpp @@ -14,6 +14,8 @@ class LaunchQueue { char args[LAUNCH_QUEUE_ARG_SIZE_MAX]; }; + static LaunchQueue::LaunchItem *get_item(u64 tid); + static Result add(u64 tid, const char *args, u64 arg_size); static Result add_item(const LaunchItem *item); static Result add_copy(u64 tid_base, u64 new_tid); diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp new file mode 100644 index 000000000..c68de9cce --- /dev/null +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -0,0 +1,13 @@ +#pragma once +#include + +#include "ldr_process_creation.hpp" +#include "ldr_registration.hpp" +#include "ldr_launch_queue.hpp" +#include "ldr_content_management.hpp" +#include "ldr_npdm.hpp" + +Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nca_path, LaunchQueue::LaunchItem *launch_item, u64 flags, Handle reslimit_h) { + /* TODO */ + return 0xA09; +} diff --git a/stratosphere/loader/source/ldr_process_creation.hpp b/stratosphere/loader/source/ldr_process_creation.hpp new file mode 100644 index 000000000..778de83e0 --- /dev/null +++ b/stratosphere/loader/source/ldr_process_creation.hpp @@ -0,0 +1,12 @@ +#pragma once +#include + +#include "ldr_registration.hpp" +#include "ldr_launch_queue.hpp" + +/* Utilities for Process Creation, for Loader. */ + +class ProcessCreation { + public: + static Result CreateProcess(Handle *out_process_h, u64 index, char *nca_path, LaunchQueue::LaunchItem *launch_item, u64 flags, Handle reslimit_h); +}; \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_process_manager.cpp b/stratosphere/loader/source/ldr_process_manager.cpp index a26c4f1c2..b39861d37 100644 --- a/stratosphere/loader/source/ldr_process_manager.cpp +++ b/stratosphere/loader/source/ldr_process_manager.cpp @@ -28,10 +28,30 @@ Result ProcessManagerService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u return rc; } -std::tuple ProcessManagerService::create_process(u64 flags, u64 title_id, CopiedHandle reslimit_h) { - /* TODO */ - fprintf(stderr, "CreateProcess(%016lx, %016lx, %08x);\n", flags, title_id, reslimit_h.handle); - return std::make_tuple(0xF601, MovedHandle{0x00}); +std::tuple ProcessManagerService::create_process(u64 flags, u64 index, CopiedHandle reslimit_h) { + Result rc; + Registration::TidSid tid_sid; + LaunchQueue::LaunchItem *launch_item; + char nca_path[FS_MAX_PATH] = {0}; + Handle process_h = 0; + + fprintf(stderr, "CreateProcess(%016lx, %016lx, %08x);\n", flags, index, reslimit_h.handle); + + rc = Registration::get_registered_tid_sid(index, &tid_sid); + if (R_FAILED(rc)) { + std::make_tuple(rc, MovedHandle{process_h}); + } + + rc = ContentManagement::GetContentPathForTidSid(nca_path, &tid_sid); + if (R_FAILED(rc)) { + std::make_tuple(rc, MovedHandle{process_h}); + } + + launch_item = LaunchQueue::get_item(tid_sid.title_id); + + rc = ProcessCreation::CreateProcess(&process_h, index, nca_path, launch_item, flags, reslimit_h.handle); + + return std::make_tuple(rc, MovedHandle{process_h}); } std::tuple ProcessManagerService::get_program_info(Registration::TidSid tid_sid, OutPointerWithServerSize out_program_info) { diff --git a/stratosphere/loader/source/ldr_process_manager.hpp b/stratosphere/loader/source/ldr_process_manager.hpp index 8f3af5667..e908f6674 100644 --- a/stratosphere/loader/source/ldr_process_manager.hpp +++ b/stratosphere/loader/source/ldr_process_manager.hpp @@ -3,6 +3,7 @@ #include "iserviceobject.hpp" #include "ldr_registration.hpp" +#include "ldr_process_creation.hpp" enum ProcessManagerServiceCmd { Pm_Cmd_CreateProcess = 0, @@ -32,7 +33,7 @@ class ProcessManagerService : IServiceObject { private: /* Actual commands. */ - std::tuple create_process(u64 flags, u64 title_id, CopiedHandle reslimit_h); + std::tuple create_process(u64 flags, u64 index, CopiedHandle reslimit_h); std::tuple get_program_info(Registration::TidSid tid_sid, OutPointerWithServerSize out_program_info); std::tuple register_title(Registration::TidSid tid_sid); std::tuple unregister_title(u64 index); diff --git a/stratosphere/loader/source/ldr_registration.cpp b/stratosphere/loader/source/ldr_registration.cpp index a9c71857f..509b85f85 100644 --- a/stratosphere/loader/source/ldr_registration.cpp +++ b/stratosphere/loader/source/ldr_registration.cpp @@ -63,6 +63,18 @@ bool Registration::unregister_index(u64 index) { return true; } + +Result Registration::get_registered_tid_sid(u64 index, Registration::TidSid *out) { + Registration::Process *target_process = get_process(index); + if (target_process == NULL) { + return 0x1009; + } + + *out = target_process->tid_sid; + + return 0; +} + void Registration::set_process_id_and_tid_min(u64 index, u64 process_id, u64 tid_min) { Registration::Process *target_process = get_process(index); if (target_process == NULL) { diff --git a/stratosphere/loader/source/ldr_registration.hpp b/stratosphere/loader/source/ldr_registration.hpp index 7656931be..da95cde42 100644 --- a/stratosphere/loader/source/ldr_registration.hpp +++ b/stratosphere/loader/source/ldr_registration.hpp @@ -41,6 +41,7 @@ class Registration { static Registration::Process *get_free_process(); static Registration::Process *get_process(u64 index); static Registration::Process *get_process_by_process_id(u64 pid); + static Result get_registered_tid_sid(u64 index, Registration::TidSid *out); static bool register_tid_sid(const TidSid *tid_sid, u64 *out_index); static bool unregister_index(u64 index); static void set_process_id_and_tid_min(u64 index, u64 process_id, u64 tid_min);