diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 1095dcf6c..14e0a03c8 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -22,6 +22,7 @@ constexpr Result ResultInvalidClient(ErrorModule::SM, 2); constexpr Result ResultAlreadyRegistered(ErrorModule::SM, 4); constexpr Result ResultInvalidServiceName(ErrorModule::SM, 6); constexpr Result ResultNotRegistered(ErrorModule::SM, 7); +constexpr Result ResultNotAllowed(ErrorModule::SM, 1); ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} { controller_interface = std::make_unique(kernel.System()); @@ -157,9 +158,10 @@ void SM::GetServiceTipc(HLERequestContext& ctx) { } static std::string PopServiceName(IPC::RequestParser& rp) { - auto name_buf = rp.PopRaw>(); + const u64 name_encoded = rp.PopRaw(); std::string result; - for (const auto& c : name_buf) { + for (int i = 0; i < 8; i++) { + const char c = static_cast((name_encoded >> (i * 8)) & 0xFF); if (c >= ' ' && c <= '~') { result.push_back(c); } @@ -250,22 +252,48 @@ void SM::UnregisterService(HLERequestContext& ctx) { rb.Push(service_manager.UnregisterService(name)); } +void SM::RegisterClient(HLERequestContext& ctx) { + LOG_DEBUG(Service_SM, "called"); + + IPC::RequestParser rp{ctx}; + + // Read PID descriptor + rp.Skip(2, false); // Skip PID descriptor and reserved u64 + + ctx.GetManager()->SetIsInitializedForSm(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void SM::DetachClient(HLERequestContext& ctx) { + LOG_DEBUG(Service_SM, "called"); + + IPC::RequestParser rp{ctx}; + rp.Skip(2, false); // Skip PID descriptor and reserved u64 + + ctx.GetManager()->SetIsInitializedForSm(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + SM::SM(ServiceManager& service_manager_, Core::System& system_) : ServiceFramework{system_, "sm:", 4}, service_manager{service_manager_}, kernel{system_.Kernel()} { RegisterHandlers({ - {0, &SM::Initialize, "Initialize"}, + {0, &SM::RegisterClient, "RegisterClient"}, {1, &SM::GetServiceCmif, "GetService"}, {2, &SM::RegisterServiceCmif, "RegisterService"}, {3, &SM::UnregisterService, "UnregisterService"}, - {4, nullptr, "DetachClient"}, + {4, &SM::DetachClient, "DetachClient"}, }); RegisterHandlersTipc({ - {0, &SM::Initialize, "Initialize"}, + {0, &SM::RegisterClient, "RegisterClient"}, {1, &SM::GetServiceTipc, "GetService"}, {2, &SM::RegisterServiceTipc, "RegisterService"}, {3, &SM::UnregisterService, "UnregisterService"}, - {4, nullptr, "DetachClient"}, + {4, &SM::DetachClient, "DetachClient"}, }); } diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 32c218638..d73eac08e 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -38,12 +38,14 @@ public: ~SM() override; private: + void RegisterClient(HLERequestContext& ctx); void Initialize(HLERequestContext& ctx); void GetServiceCmif(HLERequestContext& ctx); void GetServiceTipc(HLERequestContext& ctx); void RegisterServiceCmif(HLERequestContext& ctx); void RegisterServiceTipc(HLERequestContext& ctx); void UnregisterService(HLERequestContext& ctx); + void DetachClient(HLERequestContext& ctx); Result GetServiceImpl(Kernel::KClientSession** out_client_session, HLERequestContext& ctx); void RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_session_count,