diff options
| author | Subv <subv2112@gmail.com> | 2017-09-24 00:12:58 -0500 | 
|---|---|---|
| committer | Subv <subv2112@gmail.com> | 2017-09-24 00:12:58 -0500 | 
| commit | 0b33e36292ca44151da32c7866e4c4394add564b (patch) | |
| tree | ebe77b8f7d81b2c026dbe2276f383d72cc949bfe /src/core/hle | |
| parent | a7758b0b36f50b0d0f20149134551f4dfee01442 (diff) | |
HLE/SRV: Implemented RegisterService.
Now system modules can do more than just crash immediately on startup.
Diffstat (limited to 'src/core/hle')
| -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      std::string name, unsigned int max_sessions) {      CASCADE_CODE(ValidateServiceName(name)); + +    if (registered_services.find(name) != registered_services.end()) +        return ERR_ALREADY_REGISTERED; +      Kernel::SharedPtr<Kernel::ServerPort> server_port;      Kernel::SharedPtr<Kernel::ClientPort> client_port;      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                                         ErrorLevel::Permanent); // 0xD8E06406  constexpr ResultCode ERR_NAME_CONTAINS_NUL(7, ErrorModule::SRV, ErrorSummary::WrongArgument,                                             ErrorLevel::Permanent); // 0xD9006407 +constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorDescription::AlreadyExists, ErrorModule::OS, +                                            ErrorSummary::WrongArgument, +                                            ErrorLevel::Permanent); // 0xD9001BFC  class ServiceManager {  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 @@  #include "core/hle/kernel/errors.h"  #include "core/hle/kernel/hle_ipc.h"  #include "core/hle/kernel/semaphore.h" +#include "core/hle/kernel/server_port.h"  #include "core/hle/kernel/server_session.h"  #include "core/hle/service/sm/sm.h"  #include "core/hle/service/sm/srv.h" @@ -184,12 +185,35 @@ void SRV::PublishToSubscriber(Kernel::HLERequestContext& ctx) {                  flags);  } +void SRV::RegisterService(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp(ctx, 0x3, 4, 0); + +    auto name_buf = rp.PopRaw<std::array<char, 8>>(); +    size_t name_len = rp.Pop<u32>(); +    u32 max_sessions = rp.Pop<u32>(); + +    std::string name(name_buf.data(), std::min(name_len, name_buf.size())); + +    auto port = service_manager->RegisterService(name, max_sessions); + +    if (port.Failed()) { +        IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); +        rb.Push(port.Code()); +        LOG_ERROR(Service_SRV, "called service=%s -> error 0x%08X", name.c_str(), port.Code().raw); +        return; +    } + +    IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); +    rb.Push(RESULT_SUCCESS); +    rb.PushObjects(port.Unwrap()); +} +  SRV::SRV(std::shared_ptr<ServiceManager> service_manager)      : ServiceFramework("srv:", 4), service_manager(std::move(service_manager)) {      static const FunctionInfo functions[] = {          {0x00010002, &SRV::RegisterClient, "RegisterClient"},          {0x00020000, &SRV::EnableNotification, "EnableNotification"}, -        {0x00030100, nullptr, "RegisterService"}, +        {0x00030100, &SRV::RegisterService, "RegisterService"},          {0x000400C0, nullptr, "UnregisterService"},          {0x00050100, &SRV::GetServiceHandle, "GetServiceHandle"},          {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:      void Subscribe(Kernel::HLERequestContext& ctx);      void Unsubscribe(Kernel::HLERequestContext& ctx);      void PublishToSubscriber(Kernel::HLERequestContext& ctx); +    void RegisterService(Kernel::HLERequestContext& ctx);      std::shared_ptr<ServiceManager> service_manager;      Kernel::SharedPtr<Kernel::Semaphore> notification_semaphore; | 
