From 321286ceabc17573d2c78110832ac3742e793700 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 18 Apr 2018 12:10:45 -0600 Subject: [PATCH] Stratosphere: Fill out Loader main(), fix template classes. --- stratosphere/loader/source/iserviceobject.hpp | 1 + stratosphere/loader/source/iwaitable.hpp | 3 +- .../loader/source/ldr_debug_monitor.cpp | 6 +- .../loader/source/ldr_debug_monitor.hpp | 6 +- stratosphere/loader/source/ldr_main.cpp | 17 ++++ stratosphere/loader/source/serviceserver.cpp | 99 ------------------- stratosphere/loader/source/serviceserver.hpp | 96 ++++++++++++++++-- stratosphere/loader/source/servicesession.cpp | 30 ------ stratosphere/loader/source/servicesession.hpp | 29 ++++-- 9 files changed, 136 insertions(+), 151 deletions(-) delete mode 100644 stratosphere/loader/source/serviceserver.cpp delete mode 100644 stratosphere/loader/source/servicesession.cpp diff --git a/stratosphere/loader/source/iserviceobject.hpp b/stratosphere/loader/source/iserviceobject.hpp index 053d19bda..3b6148cb3 100644 --- a/stratosphere/loader/source/iserviceobject.hpp +++ b/stratosphere/loader/source/iserviceobject.hpp @@ -3,5 +3,6 @@ class IServiceObject { public: + virtual ~IServiceObject() { } virtual Result dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) = 0; }; \ No newline at end of file diff --git a/stratosphere/loader/source/iwaitable.hpp b/stratosphere/loader/source/iwaitable.hpp index e090298fc..bd574f09e 100644 --- a/stratosphere/loader/source/iwaitable.hpp +++ b/stratosphere/loader/source/iwaitable.hpp @@ -6,7 +6,8 @@ class IWaitable { u64 wait_priority = 0; IWaitable *parent_waitable; public: - virtual ~IWaitable(); + virtual ~IWaitable() { } + virtual unsigned int get_num_waitables() = 0; virtual void get_waitables(IWaitable **dst) = 0; virtual void delete_child(IWaitable *child) = 0; diff --git a/stratosphere/loader/source/ldr_debug_monitor.cpp b/stratosphere/loader/source/ldr_debug_monitor.cpp index 9d24cb2ab..f4d492967 100644 --- a/stratosphere/loader/source/ldr_debug_monitor.cpp +++ b/stratosphere/loader/source/ldr_debug_monitor.cpp @@ -9,7 +9,7 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_ /* TODO: Prepare SFCO. */ switch ((DebugMonitorServiceCmd)cmd_id) { - case Cmd_AddTitleToLaunchQueue: + case Dmnt_Cmd_AddTitleToLaunchQueue: /* Validate arguments. */ if (in_rawdata_size < 0x10 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 1) { break; @@ -20,7 +20,7 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_ *out_raw_data_count = 0; break; - case Cmd_ClearLaunchQueue: + case Dmnt_Cmd_ClearLaunchQueue: if (r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) { break; } @@ -29,7 +29,7 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_ *out_raw_data_count = 0; break; - case Cmd_GetNsoInfo: + case Dmnt_Cmd_GetNsoInfo: if (in_rawdata_size < 0x8 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 1) { break; } diff --git a/stratosphere/loader/source/ldr_debug_monitor.hpp b/stratosphere/loader/source/ldr_debug_monitor.hpp index 01ae19f9f..223aee111 100644 --- a/stratosphere/loader/source/ldr_debug_monitor.hpp +++ b/stratosphere/loader/source/ldr_debug_monitor.hpp @@ -4,9 +4,9 @@ #include "iserviceobject.hpp" enum DebugMonitorServiceCmd { - Cmd_AddTitleToLaunchQueue = 0, - Cmd_ClearLaunchQueue = 1, - Cmd_GetNsoInfo = 2 + Dmnt_Cmd_AddTitleToLaunchQueue = 0, + Dmnt_Cmd_ClearLaunchQueue = 1, + Dmnt_Cmd_GetNsoInfo = 2 }; class DebugMonitorService : IServiceObject { diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index daf7124c5..bf3673240 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -5,6 +5,11 @@ #include +#include "waitablemanager.hpp" +#include "serviceserver.hpp" +#include "ldr_debug_monitor.hpp" +#include "ldr_shell.hpp" + extern u32 __start__; u32 __nx_applet_type = AppletType_None; @@ -28,6 +33,18 @@ void __libnx_initheap(void) int main(int argc, char **argv) { + /* TODO: What's a good timeout value to use here? */ + WaitableManager *server_manager = new WaitableManager(U64_MAX); + + /* Add services to manager. */ + server_manager->add_waitable(new ServiceServer("ldr:shel", 3)); + server_manager->add_waitable(new ServiceServer("ldr:dmnt", 2)); + + /* Loop forever, servicing our services. */ + server_manager->process(); + + /* Cleanup. */ + delete server_manager; return 0; } diff --git a/stratosphere/loader/source/serviceserver.cpp b/stratosphere/loader/source/serviceserver.cpp deleted file mode 100644 index 7199f7cfd..000000000 --- a/stratosphere/loader/source/serviceserver.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include - -#include "serviceserver.hpp" - -template -ServiceServer::ServiceServer(const char *service_name, unsigned int max_s) : max_sessions(max_s) { - if (R_FAILED(smRegisterService(&this->port_handle, service_name, false, this->max_sessions))) { - /* TODO: Panic. */ - } - this->sessions = new ServiceSession *[this->max_sessions]; - for (unsigned int i = 0; i < this->max_sessions; i++) { - this->sessions[i] = NULL; - } - this->num_sessions = 0; -} - -template -ServiceServer::~ServiceServer() { - for (unsigned int i = 0; i < this->max_sessions; i++) { - if (this->sessions[i]) { - delete this->sessions[i]; - } - - delete this->sessions; - } - - if (port_handle) { - svcCloseHandle(port_handle); - } -} - -/* IWaitable functions. */ -template -unsigned int ServiceServer::get_num_waitables() { - unsigned int n = 1; - for (unsigned int i = 0; i < this->max_sessions; i++) { - if (this->sessions[i]) { - n += this->sessions[i]->get_num_waitables(); - } - } - return n; -} - -template -void ServiceServer::get_waitables(IWaitable **dst) { - dst[0] = this; - unsigned int n = 0; - for (unsigned int i = 0; i < this->max_sessions; i++) { - if (this->sessions[i]) { - this->sessions[i]->get_waitables(&dst[1 + n]); - n += this->sessions[i]->get_num_waitables(); - } - } -} - -template -void ServiceSession::delete_child(IWaitable *child) { - unsigned int i; - for (i = 0; i < this->max_sessions; i++) { - if (this->sessions[i] == child) { - break; - } - } - - if (i == this->max_sessions) { - /* TODO: Panic, because this isn't our child. */ - } else { - delete this->sessions[i]; - this->sessions[i] = NULL; - this->num_sessions--; - } -} - -template -Handle ServiceServer::get_handle() { - return this->port_handle; -} - -template -Result ServiceServer::handle_signaled() { - /* If this server's port was signaled, accept a new session. */ - Handle session_h; - svcAcceptSession(&session_h, this->port_handle); - - if (this->num_sessions >= this->max_sessions) { - svcCloseHandle(session_h); - return 0x10601; - } - - unsigned int i; - for (i = 0; i < this->max_sessions; i++) { - if (this->sessions[i] = NULL) { - break; - } - } - - this->sessions[i] = new ServiceSession(this, session_h, 0); - this->num_sessions++; -} \ No newline at end of file diff --git a/stratosphere/loader/source/serviceserver.hpp b/stratosphere/loader/source/serviceserver.hpp index d0469e1d7..a48decf86 100644 --- a/stratosphere/loader/source/serviceserver.hpp +++ b/stratosphere/loader/source/serviceserver.hpp @@ -10,7 +10,7 @@ template class ServiceSession; template -class ServiceServer : IWaitable { +class ServiceServer : public IWaitable { static_assert(std::is_base_of::value, "Service Objects must derive from IServiceObject"); Handle port_handle; @@ -19,13 +19,93 @@ class ServiceServer : IWaitable { ServiceSession **sessions; public: - ServiceServer(const char *service_name, unsigned int max_s); - virtual ~ServiceServer(); + ServiceServer(const char *service_name, unsigned int max_s) { + if (R_FAILED(smRegisterService(&this->port_handle, service_name, false, this->max_sessions))) { + /* TODO: Panic. */ + } + this->sessions = new ServiceSession *[this->max_sessions]; + for (unsigned int i = 0; i < this->max_sessions; i++) { + this->sessions[i] = NULL; + } + this->num_sessions = 0; + } + + virtual ~ServiceServer() { + for (unsigned int i = 0; i < this->max_sessions; i++) { + if (this->sessions[i]) { + delete this->sessions[i]; + } + + delete this->sessions; + } + + if (port_handle) { + svcCloseHandle(port_handle); + } + } /* IWaitable */ - virtual unsigned int get_num_waitables(); - virtual void get_waitables(IWaitable **dst); - virtual void delete_child(IWaitable *child); - virtual Handle get_handle(); - virtual Result handle_signaled(); + virtual unsigned int get_num_waitables() { + unsigned int n = 1; + for (unsigned int i = 0; i < this->max_sessions; i++) { + if (this->sessions[i]) { + n += this->sessions[i]->get_num_waitables(); + } + } + return n; + } + + virtual void get_waitables(IWaitable **dst) { + dst[0] = this; + unsigned int n = 0; + for (unsigned int i = 0; i < this->max_sessions; i++) { + if (this->sessions[i]) { + this->sessions[i]->get_waitables(&dst[1 + n]); + n += this->sessions[i]->get_num_waitables(); + } + } + } + + virtual void delete_child(IWaitable *child) { + unsigned int i; + for (i = 0; i < this->max_sessions; i++) { + if (this->sessions[i] == child) { + break; + } + } + + if (i == this->max_sessions) { + /* TODO: Panic, because this isn't our child. */ + } else { + delete this->sessions[i]; + this->sessions[i] = NULL; + this->num_sessions--; + } + } + + virtual Handle get_handle() { + return this->port_handle; + } + + virtual Result handle_signaled() { + /* If this server's port was signaled, accept a new session. */ + Handle session_h; + svcAcceptSession(&session_h, this->port_handle); + + if (this->num_sessions >= this->max_sessions) { + svcCloseHandle(session_h); + return 0x10601; + } + + unsigned int i; + for (i = 0; i < this->max_sessions; i++) { + if (this->sessions[i] == NULL) { + break; + } + } + + this->sessions[i] = new ServiceSession(this, session_h, 0); + this->num_sessions++; + return 0; + } }; \ No newline at end of file diff --git a/stratosphere/loader/source/servicesession.cpp b/stratosphere/loader/source/servicesession.cpp deleted file mode 100644 index 36e0c4abf..000000000 --- a/stratosphere/loader/source/servicesession.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include - -#include "servicesession.hpp" - -/* IWaitable functions. */ -template -unsigned int ServiceSession::get_num_waitables() { - return 1; -} - -template -void ServiceSession::get_waitables(IWaitable **dst) { - dst[0] = this; -} - -template -void ServiceSession::delete_child(IWaitable *child) { - /* TODO: Panic, because we can never have any children. */ -} - -template -Handle ServiceSession::get_handle() { - return this->server_handle; -} - -template -Result ServiceSession::handle_signaled() { - /* TODO */ - return 0; -} \ No newline at end of file diff --git a/stratosphere/loader/source/servicesession.hpp b/stratosphere/loader/source/servicesession.hpp index 84e6beead..6d06d9398 100644 --- a/stratosphere/loader/source/servicesession.hpp +++ b/stratosphere/loader/source/servicesession.hpp @@ -10,7 +10,7 @@ template class ServiceServer; template -class ServiceSession : IWaitable { +class ServiceSession : public IWaitable { static_assert(std::is_base_of::value, "Service Objects must derive from IServiceObject"); T *service_object; @@ -18,7 +18,7 @@ class ServiceSession : IWaitable { Handle server_handle; Handle client_handle; public: - ServiceSession(ServiceServer *s, Handle s_h, Handle c_h) : server(s), server_handle(s_h), client_handle(c_h) { + ServiceSession(ServiceServer *s, Handle s_h, Handle c_h) : server(s), server_handle(s_h), client_handle(c_h) { this->service_object = new T(); } @@ -37,9 +37,24 @@ class ServiceSession : IWaitable { Handle get_client_handle() { return this->client_handle; } /* IWaitable */ - virtual unsigned int get_num_waitables(); - virtual void get_waitables(IWaitable **dst); - virtual void delete_child(IWaitable *child); - virtual Handle get_handle(); - virtual Result handle_signaled(); + virtual unsigned int get_num_waitables() { + return 1; + } + + virtual void get_waitables(IWaitable **dst) { + dst[0] = this; + } + + virtual void delete_child(IWaitable *child) { + /* TODO: Panic, because we can never have any children. */ + } + + virtual Handle get_handle() { + return this->server_handle; + } + + virtual Result handle_signaled() { + /* TODO */ + return 0; + } }; \ No newline at end of file