diff --git a/stratosphere/sm/sm.json b/stratosphere/sm/sm.json index 0d3074e10..cce46d816 100644 --- a/stratosphere/sm/sm.json +++ b/stratosphere/sm/sm.json @@ -1,7 +1,7 @@ { "name" : "sm", "title_id" : "0x0100000000000004", - "main_thread_stack_size" : "0x1000", + "main_thread_stack_size" : "0x2000", "main_thread_priority" : 27, "default_cpu_id" : 3, "process_category" : 1, @@ -56,6 +56,7 @@ "svcReplyAndReceiveLight" : "0x42", "svcReplyAndReceive" : "0x43", "svcReplyAndReceiveWithUserBuffer" : "0x44", + "svcCreateEvent" : "0x45", "svcGetMemoryInfo" : "0x6F", "svcCreatePort" : "0x70", "svcManageNamedPort" : "0x71", diff --git a/stratosphere/sm/source/sm_main.cpp b/stratosphere/sm/source/sm_main.cpp index d9381b821..60ceb3c45 100644 --- a/stratosphere/sm/source/sm_main.cpp +++ b/stratosphere/sm/source/sm_main.cpp @@ -61,15 +61,18 @@ void __appExit(void) { /* Nothing to clean up, because we're sm. */ } + + + int main(int argc, char **argv) { consoleDebugInit(debugDevice_SVC); /* TODO: What's a good timeout value to use here? */ - WaitableManager *server_manager = new WaitableManager(U64_MAX); - + auto server_manager = new WaitableManager(1); + /* Create sm:, (and thus allow things to register to it). */ - server_manager->add_waitable(new ManagedPortServer("sm:", 0x40)); + server_manager->AddWaitable(new ManagedPortServer("sm:", 0x40)); /* Create sm:m manually. */ Handle smm_h; @@ -78,10 +81,10 @@ int main(int argc, char **argv) while (1) { } } - server_manager->add_waitable(new ExistingPortServer(smm_h, 1)); - + server_manager->AddWaitable(new ExistingPortServer(smm_h, 1)); + /* Loop forever, servicing our services. */ - server_manager->process(); + server_manager->Process(); /* Cleanup. */ delete server_manager; diff --git a/stratosphere/sm/source/sm_manager_service.cpp b/stratosphere/sm/source/sm_manager_service.cpp index 03e0e5d95..1ae5ca624 100644 --- a/stratosphere/sm/source/sm_manager_service.cpp +++ b/stratosphere/sm/source/sm_manager_service.cpp @@ -19,40 +19,15 @@ #include "sm_manager_service.hpp" #include "sm_registration.hpp" -Result ManagerService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - switch ((ManagerServiceCmd)cmd_id) { - case Manager_Cmd_RegisterProcess: - rc = WrapIpcCommandImpl<&ManagerService::register_process>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Manager_Cmd_UnregisterProcess: - rc = WrapIpcCommandImpl<&ManagerService::unregister_process>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Manager_Cmd_AtmosphereEndInitDefers: - rc = WrapIpcCommandImpl<&ManagerService::end_init_defers>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - return rc; +Result ManagerService::RegisterProcess(u64 pid, InBuffer acid_sac, InBuffer aci0_sac) { + return Registration::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements); } -Result ManagerService::handle_deferred() { - /* This service is never deferrable. */ - return 0; +Result ManagerService::UnregisterProcess(u64 pid) { + return Registration::UnregisterProcess(pid); } - -std::tuple ManagerService::register_process(u64 pid, InBuffer acid_sac, InBuffer aci0_sac) { - return {Registration::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements)}; -} - -std::tuple ManagerService::unregister_process(u64 pid) { - return {Registration::UnregisterProcess(pid)}; -} - -std::tuple ManagerService::end_init_defers() { +void ManagerService::AtmosphereEndInitDefers() { Registration::EndInitDefers(); - return {0}; } diff --git a/stratosphere/sm/source/sm_manager_service.hpp b/stratosphere/sm/source/sm_manager_service.hpp index fd7a98647..080c4c93e 100644 --- a/stratosphere/sm/source/sm_manager_service.hpp +++ b/stratosphere/sm/source/sm_manager_service.hpp @@ -16,7 +16,7 @@ #pragma once #include -#include +#include enum ManagerServiceCmd { Manager_Cmd_RegisterProcess = 0, @@ -27,17 +27,16 @@ enum ManagerServiceCmd { }; class ManagerService final : public IServiceObject { - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override; - - ManagerService *clone() override { - return new ManagerService(); - } - private: /* Actual commands. */ - std::tuple register_process(u64 pid, InBuffer acid_sac, InBuffer aci0_sac); - std::tuple unregister_process(u64 pid); - std::tuple end_init_defers(); + virtual Result RegisterProcess(u64 pid, InBuffer acid_sac, InBuffer aci0_sac); + virtual Result UnregisterProcess(u64 pid); + virtual void AtmosphereEndInitDefers(); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + + MakeServiceCommandMeta(), + }; }; diff --git a/stratosphere/sm/source/sm_registration.cpp b/stratosphere/sm/source/sm_registration.cpp index 46c6d62fc..0932db1f7 100644 --- a/stratosphere/sm/source/sm_registration.cpp +++ b/stratosphere/sm/source/sm_registration.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include "sm_registration.hpp" #include "meta_tools.hpp" @@ -250,7 +250,7 @@ Result Registration::GetServiceHandle(u64 pid, u64 service, Handle *out) { struct { u64 magic; u64 result; - u64 should_mitm; + bool should_mitm; } *resp = ((decltype(resp))r.Raw); rc = resp->result; if (R_SUCCEEDED(rc)) { diff --git a/stratosphere/sm/source/sm_user_service.cpp b/stratosphere/sm/source/sm_user_service.cpp index 00cf6f971..40079ec15 100644 --- a/stratosphere/sm/source/sm_user_service.cpp +++ b/stratosphere/sm/source/sm_user_service.cpp @@ -15,57 +15,20 @@ */ #include -#include +#include #include "sm_user_service.hpp" #include "sm_registration.hpp" -Result UserService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - switch ((UserServiceCmd)cmd_id) { - case User_Cmd_Initialize: - rc = WrapIpcCommandImpl<&UserService::initialize>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case User_Cmd_GetService: - rc = WrapIpcCommandImpl<&UserService::get_service>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case User_Cmd_RegisterService: - rc = WrapIpcCommandImpl<&UserService::register_service>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case User_Cmd_UnregisterService: - rc = WrapIpcCommandImpl<&UserService::unregister_service>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; -#ifdef SM_ENABLE_MITM - case User_Cmd_AtmosphereInstallMitm: - rc = WrapIpcCommandImpl<&UserService::install_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case User_Cmd_AtmosphereUninstallMitm: - rc = WrapIpcCommandImpl<&UserService::uninstall_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case User_Cmd_AtmosphereAssociatePidTidForMitm: - rc = WrapIpcCommandImpl<&UserService::associate_pid_tid_for_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; -#endif - default: - break; - } - return rc; -} - -Result UserService::handle_deferred() { - /* If we're deferred, GetService failed. */ - return WrapDeferredIpcCommandImpl<&UserService::deferred_get_service>(this, this->deferred_service); -} - - -std::tuple UserService::initialize(PidDescriptor pid) { +Result UserService::Initialize(PidDescriptor pid) { this->pid = pid.pid; this->has_initialized = true; - return {0}; + return 0; } -std::tuple UserService::get_service(u64 service) { +Result UserService::GetService(Out out_h, u64 service) { Handle session_h = 0; Result rc = 0x415; + #ifdef SM_ENABLE_SMHAX if (!this->has_initialized) { rc = Registration::GetServiceForPid(Registration::GetInitialProcessId(), service, &session_h); @@ -74,20 +37,14 @@ std::tuple UserService::get_service(u64 service) { if (this->has_initialized) { rc = Registration::GetServiceForPid(this->pid, service, &session_h); } - /* It's possible that this will end up deferring us...take that into account. */ - if (rc == RESULT_DEFER_SESSION) { - this->deferred_service = service; + + if (R_SUCCEEDED(rc)) { + out_h.SetValue(session_h); } - return {rc, MovedHandle{session_h}}; + return rc; } -std::tuple UserService::deferred_get_service(u64 service) { - Handle session_h = 0; - Result rc = Registration::GetServiceHandle(this->pid, service, &session_h); - return {rc, MovedHandle{session_h}}; -} - -std::tuple UserService::register_service(u64 service, u8 is_light, u32 max_sessions) { +Result UserService::RegisterService(Out out_h, u64 service, u8 is_light, u32 max_sessions) { Handle service_h = 0; Result rc = 0x415; #ifdef SM_ENABLE_SMHAX @@ -98,10 +55,14 @@ std::tuple UserService::register_service(u64 service, u8 is if (this->has_initialized) { rc = Registration::RegisterServiceForPid(this->pid, service, max_sessions, (is_light & 1) != 0, &service_h); } - return {rc, MovedHandle{service_h}}; + + if (R_SUCCEEDED(rc)) { + out_h.SetValue(service_h); + } + return rc; } -std::tuple UserService::unregister_service(u64 service) { +Result UserService::UnregisterService(u64 service) { Result rc = 0x415; #ifdef SM_ENABLE_SMHAX if (!this->has_initialized) { @@ -111,20 +72,33 @@ std::tuple UserService::unregister_service(u64 service) { if (this->has_initialized) { rc = Registration::UnregisterServiceForPid(this->pid, service); } - return {rc}; + return rc; } -std::tuple UserService::install_mitm(u64 service) { +Result UserService::AtmosphereInstallMitm(Out srv_h, Out qry_h, u64 service) { Handle service_h = 0; Handle query_h = 0; Result rc = 0x415; if (this->has_initialized) { rc = Registration::InstallMitmForPid(this->pid, service, &service_h, &query_h); } - return {rc, MovedHandle{service_h}, MovedHandle{query_h}}; + + if (R_SUCCEEDED(rc)) { + srv_h.SetValue(service_h); + qry_h.SetValue(query_h); + } + return rc; } -std::tuple UserService::associate_pid_tid_for_mitm(u64 pid, u64 tid) { +Result UserService::AtmosphereUninstallMitm(u64 service) { + Result rc = 0x415; + if (this->has_initialized) { + rc = Registration::UninstallMitmForPid(this->pid, service); + } + return rc; +} + +Result UserService::AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid) { Result rc = 0x415; if (this->has_initialized) { if (Registration::IsInitialProcess(pid)) { @@ -133,13 +107,5 @@ std::tuple UserService::associate_pid_tid_for_mitm(u64 pid, u64 tid) { rc = Registration::AssociatePidTidForMitm(pid, tid); } } - return {rc}; + return rc; } - -std::tuple UserService::uninstall_mitm(u64 service) { - Result rc = 0x415; - if (this->has_initialized) { - rc = Registration::UninstallMitmForPid(this->pid, service); - } - return {rc}; -} \ No newline at end of file diff --git a/stratosphere/sm/source/sm_user_service.hpp b/stratosphere/sm/source/sm_user_service.hpp index 8f3250472..206b4f771 100644 --- a/stratosphere/sm/source/sm_user_service.hpp +++ b/stratosphere/sm/source/sm_user_service.hpp @@ -16,7 +16,7 @@ #pragma once #include -#include +#include enum UserServiceCmd { User_Cmd_Initialize = 0, @@ -30,32 +30,31 @@ enum UserServiceCmd { }; class UserService final : public IServiceObject { - u64 pid = U64_MAX; - bool has_initialized = false; - u64 deferred_service = 0; - - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override; - - UserService *clone() override { - auto new_srv = new UserService(); - new_srv->pid = pid; - new_srv->has_initialized = has_initialized; - new_srv->deferred_service = deferred_service; - return new_srv; - } - private: + u64 pid = U64_MAX; + bool has_initialized = false; + /* Actual commands. */ - std::tuple initialize(PidDescriptor pid); - std::tuple get_service(u64 service); - std::tuple deferred_get_service(u64 service); - std::tuple register_service(u64 service, u8 is_light, u32 max_sessions); - std::tuple unregister_service(u64 service); + virtual Result Initialize(PidDescriptor pid); + virtual Result GetService(Out out_h, u64 service); + virtual Result RegisterService(Out out_h, u64 service, u8 is_light, u32 max_sessions); + virtual Result UnregisterService(u64 service); /* Atmosphere commands. */ - std::tuple install_mitm(u64 service); - std::tuple uninstall_mitm(u64 service); - std::tuple associate_pid_tid_for_mitm(u64 pid, u64 tid); + virtual Result AtmosphereInstallMitm(Out srv_h, Out qry_h, u64 service); + virtual Result AtmosphereUninstallMitm(u64 service); + virtual Result AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + +#ifdef SM_ENABLE_MITM + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), +#endif + }; };