From af11f9fdecbb0f2f204a2cf76a3b50cf9dfe9b6f Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 18 Apr 2018 23:15:17 -0600 Subject: [PATCH] Stratosphere: Skeleton ldr:pm (RegisterTitle/UnregisterTitle are implemented) --- stratosphere/loader/source/ldr_main.cpp | 2 + .../loader/source/ldr_process_manager.cpp | 74 +++++++++++++++++++ .../loader/source/ldr_process_manager.hpp | 24 ++++++ .../loader/source/ldr_registration.cpp | 4 +- stratosphere/loader/source/ldr_shell.cpp | 4 +- stratosphere/loader/source/ldr_shell.hpp | 4 +- 6 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 stratosphere/loader/source/ldr_process_manager.cpp create mode 100644 stratosphere/loader/source/ldr_process_manager.hpp diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index 58ccc3212..0f4de2522 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -7,6 +7,7 @@ #include "waitablemanager.hpp" #include "serviceserver.hpp" +#include "ldr_process_manager.hpp" #include "ldr_debug_monitor.hpp" #include "ldr_shell.hpp" @@ -39,6 +40,7 @@ int main(int argc, char **argv) WaitableManager *server_manager = new WaitableManager(U64_MAX); /* Add services to manager. */ + server_manager->add_waitable(new ServiceServer("dbg:pm", 1)); server_manager->add_waitable(new ServiceServer("dbg:shel", 3)); server_manager->add_waitable(new ServiceServer("dbg:dmnt", 2)); diff --git a/stratosphere/loader/source/ldr_process_manager.cpp b/stratosphere/loader/source/ldr_process_manager.cpp new file mode 100644 index 000000000..2c9103063 --- /dev/null +++ b/stratosphere/loader/source/ldr_process_manager.cpp @@ -0,0 +1,74 @@ +#include +#include "ldr_process_manager.hpp" +#include "ldr_registration.hpp" +#include "ldr_launch_queue.hpp" + +Result ProcessManagerService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) { + + Result rc = 0xF601; + + switch ((ProcessManagerServiceCmd)cmd_id) { + case Pm_Cmd_CreateProcess: + /* TODO */ + break; + case Pm_Cmd_GetProgramInfo: + /* TODO */ + break; + case Pm_Cmd_RegisterTitle: + /* Validate arguments. */ + if (in_rawdata_size < 0x10 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) { + break; + } + + u64 out_index; + rc = register_title((Registration::TidSid *)in_rawdata, &out_index); + if (R_SUCCEEDED(rc)) { + ((u64 *)out_rawdata)[0] = out_index; + *out_raw_data_count = 8; + } else { + ((u64 *)out_rawdata)[0] = 0; + *out_raw_data_count = 0; + } + + break; + case Pm_Cmd_UnregisterTitle: + /* Validate arguments. */ + if (in_rawdata_size < 0x8 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) { + break; + } + + rc = unregister_title(((u64 *)in_rawdata)[0]); + *out_raw_data_count = 0; + + break; + default: + break; + } + return rc; +} + +Result ProcessManagerService::create_process() { + /* TODO */ + return 0xF601; +} + +Result ProcessManagerService::get_program_info() { + /* TODO */ + return 0xF601; +} + +Result ProcessManagerService::register_title(const Registration::TidSid *tid_sid, u64 *out_index) { + if (Registration::register_tid_sid(tid_sid, out_index)) { + return 0; + } else { + return 0xE09; + } +} + +Result ProcessManagerService::unregister_title(u64 index) { + if (Registration::unregister_index(index)) { + return 0; + } else { + return 0x1009; + } +} \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_process_manager.hpp b/stratosphere/loader/source/ldr_process_manager.hpp new file mode 100644 index 000000000..e1fbf4e44 --- /dev/null +++ b/stratosphere/loader/source/ldr_process_manager.hpp @@ -0,0 +1,24 @@ +#pragma once +#include + +#include "iserviceobject.hpp" +#include "ldr_registration.hpp" + +enum ProcessManagerServiceCmd { + Pm_Cmd_CreateProcess = 0, + Pm_Cmd_GetProgramInfo = 1, + Pm_Cmd_RegisterTitle = 2, + Pm_Cmd_UnregisterTitle = 3 +}; + +class ProcessManagerService : IServiceObject { + public: + Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count); + + private: + /* Actual commands. */ + Result create_process(); + Result get_program_info(); + Result register_title(const Registration::TidSid *tid_sid, u64 *out_index); + Result unregister_title(u64 index); +}; \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_registration.cpp b/stratosphere/loader/source/ldr_registration.cpp index c860af713..0013a51e8 100644 --- a/stratosphere/loader/source/ldr_registration.cpp +++ b/stratosphere/loader/source/ldr_registration.cpp @@ -6,7 +6,7 @@ static Registration::List g_registration_list = {0}; static u64 g_num_registered = 1; -Registration::Process *get_free_process() { +Registration::Process *Registration::get_free_process() { unsigned int i; for (i = 0; i < REGISTRATION_LIST_MAX; i++) { if (!g_registration_list.processes[i].in_use) { @@ -16,7 +16,7 @@ Registration::Process *get_free_process() { return NULL; } -Registration::Process *get_process(u64 index) { +Registration::Process *Registration::get_process(u64 index) { unsigned int i; for (i = 0; !g_registration_list.processes[i].in_use || g_registration_list.processes[i].index != index; i++) { if (i >= REGISTRATION_LIST_MAX) { diff --git a/stratosphere/loader/source/ldr_shell.cpp b/stratosphere/loader/source/ldr_shell.cpp index ae3116e1e..199f8e09e 100644 --- a/stratosphere/loader/source/ldr_shell.cpp +++ b/stratosphere/loader/source/ldr_shell.cpp @@ -7,7 +7,7 @@ Result ShellService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_b Result rc = 0xF601; switch ((ShellServiceCmd)cmd_id) { - case Cmd_AddTitleToLaunchQueue: + case Shell_Cmd_AddTitleToLaunchQueue: /* Validate arguments. */ if (in_rawdata_size < 0x10 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 1) { break; @@ -23,7 +23,7 @@ Result ShellService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_b *out_raw_data_count = 0; break; - case Cmd_ClearLaunchQueue: + case Shell_Cmd_ClearLaunchQueue: if (r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) { break; } diff --git a/stratosphere/loader/source/ldr_shell.hpp b/stratosphere/loader/source/ldr_shell.hpp index 5b8da6e84..1e17c36ee 100644 --- a/stratosphere/loader/source/ldr_shell.hpp +++ b/stratosphere/loader/source/ldr_shell.hpp @@ -4,8 +4,8 @@ #include "iserviceobject.hpp" enum ShellServiceCmd { - Cmd_AddTitleToLaunchQueue = 0, - Cmd_ClearLaunchQueue = 1 + Shell_Cmd_AddTitleToLaunchQueue = 0, + Shell_Cmd_ClearLaunchQueue = 1 }; class ShellService : IServiceObject {