From 0080a8da586a97fc8ba0b7a4916b9870ab0ce96e Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 3 Nov 2018 20:02:18 -0400 Subject: sm: Implement RegisterService and UnregisterService These are needed by Edizon to boot. They are used to see if a user is using SX OS, as SX OS registers a custom service called 'tx' and attempting to register a service of the same name lets the application know if it is present. --- src/core/hle/service/sm/sm.cpp | 54 ++++++++++++++++++++++++++++++++++++++++-- src/core/hle/service/sm/sm.h | 3 +++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 464e79d01..c1b2f33b9 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -63,6 +63,17 @@ ResultVal> ServiceManager::RegisterService return MakeResult>(std::move(server_port)); } +ResultCode ServiceManager::UnregisterService(std::string name) { + CASCADE_CODE(ValidateServiceName(name)); + + const auto iter = registered_services.find(name); + if (iter == registered_services.end()) + return ERR_SERVICE_NOT_REGISTERED; + + registered_services.erase(iter); + return RESULT_SUCCESS; +} + ResultVal> ServiceManager::GetServicePort( const std::string& name) { @@ -127,13 +138,52 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { } } +void SM::RegisterService(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto name_buf = rp.PopRaw>(); + const auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); + + const std::string name(name_buf.begin(), end); + + const auto unk_bool = static_cast(rp.PopRaw()); + const auto session_count = rp.PopRaw(); + + LOG_DEBUG(Service_SM, "called with unk_bool={}", unk_bool); + + auto handle = service_manager->RegisterService(name, session_count); + if (handle.Failed()) { + LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", + handle.Code().raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(handle.Code()); + return; + } + + IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; + rb.Push(handle.Code()); + rb.PushMoveObjects(std::move(handle).Unwrap()); +} + +void SM::UnregisterService(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto name_buf = rp.PopRaw>(); + const auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); + + const std::string name(name_buf.begin(), end); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(service_manager->UnregisterService(name)); +} + SM::SM(std::shared_ptr service_manager) : ServiceFramework("sm:", 4), service_manager(std::move(service_manager)) { static const FunctionInfo functions[] = { {0x00000000, &SM::Initialize, "Initialize"}, {0x00000001, &SM::GetService, "GetService"}, - {0x00000002, nullptr, "RegisterService"}, - {0x00000003, nullptr, "UnregisterService"}, + {0x00000002, &SM::RegisterService, "RegisterService"}, + {0x00000003, &SM::UnregisterService, "UnregisterService"}, }; RegisterHandlers(functions); } diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 4f8145dda..c4714b3e3 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -35,6 +35,8 @@ public: private: void Initialize(Kernel::HLERequestContext& ctx); void GetService(Kernel::HLERequestContext& ctx); + void RegisterService(Kernel::HLERequestContext& ctx); + void UnregisterService(Kernel::HLERequestContext& ctx); std::shared_ptr service_manager; }; @@ -48,6 +50,7 @@ public: ResultVal> RegisterService(std::string name, unsigned int max_sessions); + ResultCode UnregisterService(std::string name); ResultVal> GetServicePort(const std::string& name); ResultVal> ConnectToService(const std::string& name); -- cgit v1.2.3