diff options
| -rw-r--r-- | src/core/hle/service/sm/sm.cpp | 54 | ||||
| -rw-r--r-- | 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<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService | |||
| 63 | return MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)); | 63 | return MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | ResultCode ServiceManager::UnregisterService(std::string name) { | ||
| 67 | CASCADE_CODE(ValidateServiceName(name)); | ||
| 68 | |||
| 69 | const auto iter = registered_services.find(name); | ||
| 70 | if (iter == registered_services.end()) | ||
| 71 | return ERR_SERVICE_NOT_REGISTERED; | ||
| 72 | |||
| 73 | registered_services.erase(iter); | ||
| 74 | return RESULT_SUCCESS; | ||
| 75 | } | ||
| 76 | |||
| 66 | ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> ServiceManager::GetServicePort( | 77 | ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> ServiceManager::GetServicePort( |
| 67 | const std::string& name) { | 78 | const std::string& name) { |
| 68 | 79 | ||
| @@ -127,13 +138,52 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { | |||
| 127 | } | 138 | } |
| 128 | } | 139 | } |
| 129 | 140 | ||
| 141 | void SM::RegisterService(Kernel::HLERequestContext& ctx) { | ||
| 142 | IPC::RequestParser rp{ctx}; | ||
| 143 | |||
| 144 | const auto name_buf = rp.PopRaw<std::array<char, 8>>(); | ||
| 145 | const auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); | ||
| 146 | |||
| 147 | const std::string name(name_buf.begin(), end); | ||
| 148 | |||
| 149 | const auto unk_bool = static_cast<bool>(rp.PopRaw<u32>()); | ||
| 150 | const auto session_count = rp.PopRaw<u32>(); | ||
| 151 | |||
| 152 | LOG_DEBUG(Service_SM, "called with unk_bool={}", unk_bool); | ||
| 153 | |||
| 154 | auto handle = service_manager->RegisterService(name, session_count); | ||
| 155 | if (handle.Failed()) { | ||
| 156 | LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", | ||
| 157 | handle.Code().raw); | ||
| 158 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 159 | rb.Push(handle.Code()); | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; | ||
| 164 | rb.Push(handle.Code()); | ||
| 165 | rb.PushMoveObjects(std::move(handle).Unwrap()); | ||
| 166 | } | ||
| 167 | |||
| 168 | void SM::UnregisterService(Kernel::HLERequestContext& ctx) { | ||
| 169 | IPC::RequestParser rp{ctx}; | ||
| 170 | |||
| 171 | const auto name_buf = rp.PopRaw<std::array<char, 8>>(); | ||
| 172 | const auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); | ||
| 173 | |||
| 174 | const std::string name(name_buf.begin(), end); | ||
| 175 | |||
| 176 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 177 | rb.Push(service_manager->UnregisterService(name)); | ||
| 178 | } | ||
| 179 | |||
| 130 | SM::SM(std::shared_ptr<ServiceManager> service_manager) | 180 | SM::SM(std::shared_ptr<ServiceManager> service_manager) |
| 131 | : ServiceFramework("sm:", 4), service_manager(std::move(service_manager)) { | 181 | : ServiceFramework("sm:", 4), service_manager(std::move(service_manager)) { |
| 132 | static const FunctionInfo functions[] = { | 182 | static const FunctionInfo functions[] = { |
| 133 | {0x00000000, &SM::Initialize, "Initialize"}, | 183 | {0x00000000, &SM::Initialize, "Initialize"}, |
| 134 | {0x00000001, &SM::GetService, "GetService"}, | 184 | {0x00000001, &SM::GetService, "GetService"}, |
| 135 | {0x00000002, nullptr, "RegisterService"}, | 185 | {0x00000002, &SM::RegisterService, "RegisterService"}, |
| 136 | {0x00000003, nullptr, "UnregisterService"}, | 186 | {0x00000003, &SM::UnregisterService, "UnregisterService"}, |
| 137 | }; | 187 | }; |
| 138 | RegisterHandlers(functions); | 188 | RegisterHandlers(functions); |
| 139 | } | 189 | } |
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: | |||
| 35 | private: | 35 | private: |
| 36 | void Initialize(Kernel::HLERequestContext& ctx); | 36 | void Initialize(Kernel::HLERequestContext& ctx); |
| 37 | void GetService(Kernel::HLERequestContext& ctx); | 37 | void GetService(Kernel::HLERequestContext& ctx); |
| 38 | void RegisterService(Kernel::HLERequestContext& ctx); | ||
| 39 | void UnregisterService(Kernel::HLERequestContext& ctx); | ||
| 38 | 40 | ||
| 39 | std::shared_ptr<ServiceManager> service_manager; | 41 | std::shared_ptr<ServiceManager> service_manager; |
| 40 | }; | 42 | }; |
| @@ -48,6 +50,7 @@ public: | |||
| 48 | 50 | ||
| 49 | ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> RegisterService(std::string name, | 51 | ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> RegisterService(std::string name, |
| 50 | unsigned int max_sessions); | 52 | unsigned int max_sessions); |
| 53 | ResultCode UnregisterService(std::string name); | ||
| 51 | ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> GetServicePort(const std::string& name); | 54 | ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> GetServicePort(const std::string& name); |
| 52 | ResultVal<Kernel::SharedPtr<Kernel::ClientSession>> ConnectToService(const std::string& name); | 55 | ResultVal<Kernel::SharedPtr<Kernel::ClientSession>> ConnectToService(const std::string& name); |
| 53 | 56 | ||