diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/sm/sm.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/sm/srv.cpp | 26 | ||||
| -rw-r--r-- | src/core/hle/service/sm/srv.h | 1 |
4 files changed, 33 insertions, 1 deletions
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 5e7fc68f9..854ab9a05 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -36,6 +36,10 @@ ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService | |||
| 36 | std::string name, unsigned int max_sessions) { | 36 | std::string name, unsigned int max_sessions) { |
| 37 | 37 | ||
| 38 | CASCADE_CODE(ValidateServiceName(name)); | 38 | CASCADE_CODE(ValidateServiceName(name)); |
| 39 | |||
| 40 | if (registered_services.find(name) != registered_services.end()) | ||
| 41 | return ERR_ALREADY_REGISTERED; | ||
| 42 | |||
| 39 | Kernel::SharedPtr<Kernel::ServerPort> server_port; | 43 | Kernel::SharedPtr<Kernel::ServerPort> server_port; |
| 40 | Kernel::SharedPtr<Kernel::ClientPort> client_port; | 44 | Kernel::SharedPtr<Kernel::ClientPort> client_port; |
| 41 | std::tie(server_port, client_port) = Kernel::ServerPort::CreatePortPair(max_sessions, name); | 45 | std::tie(server_port, client_port) = Kernel::ServerPort::CreatePortPair(max_sessions, name); |
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 8f0dbf2db..9f60a7965 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h | |||
| @@ -32,6 +32,9 @@ constexpr ResultCode ERR_ACCESS_DENIED(6, ErrorModule::SRV, ErrorSummary::Invali | |||
| 32 | ErrorLevel::Permanent); // 0xD8E06406 | 32 | ErrorLevel::Permanent); // 0xD8E06406 |
| 33 | constexpr ResultCode ERR_NAME_CONTAINS_NUL(7, ErrorModule::SRV, ErrorSummary::WrongArgument, | 33 | constexpr ResultCode ERR_NAME_CONTAINS_NUL(7, ErrorModule::SRV, ErrorSummary::WrongArgument, |
| 34 | ErrorLevel::Permanent); // 0xD9006407 | 34 | ErrorLevel::Permanent); // 0xD9006407 |
| 35 | constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorDescription::AlreadyExists, ErrorModule::OS, | ||
| 36 | ErrorSummary::WrongArgument, | ||
| 37 | ErrorLevel::Permanent); // 0xD9001BFC | ||
| 35 | 38 | ||
| 36 | class ServiceManager { | 39 | class ServiceManager { |
| 37 | public: | 40 | public: |
diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 352941e69..5c955cf54 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "core/hle/kernel/errors.h" | 13 | #include "core/hle/kernel/errors.h" |
| 14 | #include "core/hle/kernel/hle_ipc.h" | 14 | #include "core/hle/kernel/hle_ipc.h" |
| 15 | #include "core/hle/kernel/semaphore.h" | 15 | #include "core/hle/kernel/semaphore.h" |
| 16 | #include "core/hle/kernel/server_port.h" | ||
| 16 | #include "core/hle/kernel/server_session.h" | 17 | #include "core/hle/kernel/server_session.h" |
| 17 | #include "core/hle/service/sm/sm.h" | 18 | #include "core/hle/service/sm/sm.h" |
| 18 | #include "core/hle/service/sm/srv.h" | 19 | #include "core/hle/service/sm/srv.h" |
| @@ -184,12 +185,35 @@ void SRV::PublishToSubscriber(Kernel::HLERequestContext& ctx) { | |||
| 184 | flags); | 185 | flags); |
| 185 | } | 186 | } |
| 186 | 187 | ||
| 188 | void SRV::RegisterService(Kernel::HLERequestContext& ctx) { | ||
| 189 | IPC::RequestParser rp(ctx, 0x3, 4, 0); | ||
| 190 | |||
| 191 | auto name_buf = rp.PopRaw<std::array<char, 8>>(); | ||
| 192 | size_t name_len = rp.Pop<u32>(); | ||
| 193 | u32 max_sessions = rp.Pop<u32>(); | ||
| 194 | |||
| 195 | std::string name(name_buf.data(), std::min(name_len, name_buf.size())); | ||
| 196 | |||
| 197 | auto port = service_manager->RegisterService(name, max_sessions); | ||
| 198 | |||
| 199 | if (port.Failed()) { | ||
| 200 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||
| 201 | rb.Push(port.Code()); | ||
| 202 | LOG_ERROR(Service_SRV, "called service=%s -> error 0x%08X", name.c_str(), port.Code().raw); | ||
| 203 | return; | ||
| 204 | } | ||
| 205 | |||
| 206 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||
| 207 | rb.Push(RESULT_SUCCESS); | ||
| 208 | rb.PushObjects(port.Unwrap()); | ||
| 209 | } | ||
| 210 | |||
| 187 | SRV::SRV(std::shared_ptr<ServiceManager> service_manager) | 211 | SRV::SRV(std::shared_ptr<ServiceManager> service_manager) |
| 188 | : ServiceFramework("srv:", 4), service_manager(std::move(service_manager)) { | 212 | : ServiceFramework("srv:", 4), service_manager(std::move(service_manager)) { |
| 189 | static const FunctionInfo functions[] = { | 213 | static const FunctionInfo functions[] = { |
| 190 | {0x00010002, &SRV::RegisterClient, "RegisterClient"}, | 214 | {0x00010002, &SRV::RegisterClient, "RegisterClient"}, |
| 191 | {0x00020000, &SRV::EnableNotification, "EnableNotification"}, | 215 | {0x00020000, &SRV::EnableNotification, "EnableNotification"}, |
| 192 | {0x00030100, nullptr, "RegisterService"}, | 216 | {0x00030100, &SRV::RegisterService, "RegisterService"}, |
| 193 | {0x000400C0, nullptr, "UnregisterService"}, | 217 | {0x000400C0, nullptr, "UnregisterService"}, |
| 194 | {0x00050100, &SRV::GetServiceHandle, "GetServiceHandle"}, | 218 | {0x00050100, &SRV::GetServiceHandle, "GetServiceHandle"}, |
| 195 | {0x000600C2, nullptr, "RegisterPort"}, | 219 | {0x000600C2, nullptr, "RegisterPort"}, |
diff --git a/src/core/hle/service/sm/srv.h b/src/core/hle/service/sm/srv.h index 75cca5184..aad839563 100644 --- a/src/core/hle/service/sm/srv.h +++ b/src/core/hle/service/sm/srv.h | |||
| @@ -28,6 +28,7 @@ private: | |||
| 28 | void Subscribe(Kernel::HLERequestContext& ctx); | 28 | void Subscribe(Kernel::HLERequestContext& ctx); |
| 29 | void Unsubscribe(Kernel::HLERequestContext& ctx); | 29 | void Unsubscribe(Kernel::HLERequestContext& ctx); |
| 30 | void PublishToSubscriber(Kernel::HLERequestContext& ctx); | 30 | void PublishToSubscriber(Kernel::HLERequestContext& ctx); |
| 31 | void RegisterService(Kernel::HLERequestContext& ctx); | ||
| 31 | 32 | ||
| 32 | std::shared_ptr<ServiceManager> service_manager; | 33 | std::shared_ptr<ServiceManager> service_manager; |
| 33 | Kernel::SharedPtr<Kernel::Semaphore> notification_semaphore; | 34 | Kernel::SharedPtr<Kernel::Semaphore> notification_semaphore; |