diff options
author | bunnei <bunneidev@gmail.com> | 2021-05-16 07:30:21 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-16 07:30:21 +0200 |
commit | 5a2b15bf75318987d773a2bc69bd6224a28b7939 (patch) | |
tree | f213f5b011410022e8e98f7c3905d16d575ed413 /src/core/hle/service | |
parent | Merge pull request #6289 from ameerj/oob-blit (diff) | |
parent | common: tree: Avoid a nullptr dereference. (diff) | |
download | yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.tar yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.tar.gz yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.tar.bz2 yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.tar.lz yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.tar.xz yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.tar.zst yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.zip |
Diffstat (limited to 'src/core/hle/service')
-rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 39 | ||||
-rw-r--r-- | src/core/hle/service/audio/audren_u.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 55 | ||||
-rw-r--r-- | src/core/hle/service/service.h | 35 | ||||
-rw-r--r-- | src/core/hle/service/sm/controller.cpp | 14 | ||||
-rw-r--r-- | src/core/hle/service/sm/sm.cpp | 107 | ||||
-rw-r--r-- | src/core/hle/service/sm/sm.h | 10 |
7 files changed, 177 insertions, 85 deletions
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 513bd3730..65887011f 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -169,10 +169,9 @@ private: class IAudioDevice final : public ServiceFramework<IAudioDevice> { public: - explicit IAudioDevice(Core::System& system_, u32_le revision_num) - : ServiceFramework{system_, "IAudioDevice"}, revision{revision_num}, - buffer_event{system.Kernel()}, audio_input_device_switch_event{system.Kernel()}, - audio_output_device_switch_event{system.Kernel()} { + explicit IAudioDevice(Core::System& system_, Kernel::KEvent& buffer_event_, u32_le revision_) + : ServiceFramework{system_, "IAudioDevice"}, buffer_event{buffer_event_}, revision{ + revision_} { static const FunctionInfo functions[] = { {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, @@ -189,18 +188,6 @@ public: {13, nullptr, "GetAudioSystemMasterVolumeSetting"}, }; RegisterHandlers(functions); - - Kernel::KAutoObject::Create(std::addressof(buffer_event)); - buffer_event.Initialize("IAudioOutBufferReleasedEvent"); - - // Should be similar to audio_output_device_switch_event - Kernel::KAutoObject::Create(std::addressof(audio_input_device_switch_event)); - audio_input_device_switch_event.Initialize("IAudioDevice:AudioInputDeviceSwitchedEvent"); - - // Should only be signalled when an audio output device has been changed, example: speaker - // to headset - Kernel::KAutoObject::Create(std::addressof(audio_output_device_switch_event)); - audio_output_device_switch_event.Initialize("IAudioDevice:AudioOutputDeviceSwitchedEvent"); } private: @@ -310,7 +297,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(audio_input_device_switch_event.GetReadableEvent()); + rb.PushCopyObjects(buffer_event.GetReadableEvent()); } void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) { @@ -318,17 +305,16 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(audio_output_device_switch_event.GetReadableEvent()); + rb.PushCopyObjects(buffer_event.GetReadableEvent()); } + Kernel::KEvent& buffer_event; u32_le revision = 0; - Kernel::KEvent buffer_event; - Kernel::KEvent audio_input_device_switch_event; - Kernel::KEvent audio_output_device_switch_event; +}; -}; // namespace Audio +AudRenU::AudRenU(Core::System& system_) + : ServiceFramework{system_, "audren:u"}, buffer_event{system.Kernel()} { -AudRenU::AudRenU(Core::System& system_) : ServiceFramework{system_, "audren:u"} { // clang-format off static const FunctionInfo functions[] = { {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, @@ -340,6 +326,9 @@ AudRenU::AudRenU(Core::System& system_) : ServiceFramework{system_, "audren:u"} // clang-format on RegisterHandlers(functions); + + Kernel::KAutoObject::Create(std::addressof(buffer_event)); + buffer_event.Initialize("IAudioOutBufferReleasedEvent"); } AudRenU::~AudRenU() = default; @@ -662,7 +651,7 @@ void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) { // always assumes the initial release revision (REV1). IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1')); + rb.PushIpcInterface<IAudioDevice>(system, buffer_event, Common::MakeMagic('R', 'E', 'V', '1')); } void AudRenU::OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx) { @@ -684,7 +673,7 @@ void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& c IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IAudioDevice>(system, revision); + rb.PushIpcInterface<IAudioDevice>(system, buffer_event, revision); } void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index 37e8b4716..0ee6f9542 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h @@ -4,6 +4,7 @@ #pragma once +#include "core/hle/kernel/k_event.h" #include "core/hle/service/service.h" namespace Core { @@ -31,6 +32,7 @@ private: void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx); std::size_t audren_instance_count = 0; + Kernel::KEvent buffer_event; }; // Describes a particular audio feature that may be supported in a particular revision. diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 00e683c2f..2c9b2ce6d 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -111,7 +111,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) port_installed = true; } -void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) { +Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) { const auto guard = LockService(); ASSERT(!port_installed); @@ -119,9 +119,10 @@ void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) { auto* port = Kernel::KPort::Create(kernel); port->Initialize(max_sessions, false, service_name); port->GetServerPort().SetHleHandler(shared_from_this()); - kernel.AddNamedPort(service_name, &port->GetClientPort()); port_installed = true; + + return port->GetClientPort(); } void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { @@ -132,6 +133,16 @@ void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* function } } +void ServiceFrameworkBase::RegisterHandlersBaseTipc(const FunctionInfoBase* functions, + std::size_t n) { + handlers_tipc.reserve(handlers_tipc.size() + n); + for (std::size_t i = 0; i < n; ++i) { + // Usually this array is sorted by id already, so hint to insert at the end + handlers_tipc.emplace_hint(handlers_tipc.cend(), functions[i].expected_header, + functions[i]); + } +} + void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info) { auto cmd_buf = ctx.CommandBuffer(); @@ -166,33 +177,55 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { handler_invoker(this, info->handler_callback, ctx); } -ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& context) { +void ServiceFrameworkBase::InvokeRequestTipc(Kernel::HLERequestContext& ctx) { + boost::container::flat_map<u32, FunctionInfoBase>::iterator itr; + + itr = handlers_tipc.find(ctx.GetCommand()); + + const FunctionInfoBase* info = itr == handlers_tipc.end() ? nullptr : &itr->second; + if (info == nullptr || info->handler_callback == nullptr) { + return ReportUnimplementedFunction(ctx, info); + } + + LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer())); + handler_invoker(this, info->handler_callback, ctx); +} + +ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, + Kernel::HLERequestContext& ctx) { const auto guard = LockService(); - switch (context.GetCommandType()) { - case IPC::CommandType::Close: { - IPC::ResponseBuilder rb{context, 2}; + switch (ctx.GetCommandType()) { + case IPC::CommandType::Close: + case IPC::CommandType::TIPC_Close: { + session.Close(); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); return IPC::ERR_REMOTE_PROCESS_DEAD; } case IPC::CommandType::ControlWithContext: case IPC::CommandType::Control: { - system.ServiceManager().InvokeControlRequest(context); + system.ServiceManager().InvokeControlRequest(ctx); break; } case IPC::CommandType::RequestWithContext: case IPC::CommandType::Request: { - InvokeRequest(context); + InvokeRequest(ctx); break; } default: - UNIMPLEMENTED_MSG("command_type={}", context.GetCommandType()); + if (ctx.IsTipc()) { + InvokeRequestTipc(ctx); + break; + } + + UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType()); } // If emulation was shutdown, we are closing service threads, do not write the response back to // memory that may be shutting down as well. if (system.IsPoweredOn()) { - context.WriteToOutgoingCommandBuffer(context.GetThread()); + ctx.WriteToOutgoingCommandBuffer(ctx.GetThread()); } return RESULT_SUCCESS; @@ -207,7 +240,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); - SM::ServiceManager::InstallInterfaces(sm, system); + system.Kernel().RegisterNamedService("sm:", SM::ServiceManager::InterfaceFactory); Account::InstallInterfaces(system); AM::InstallInterfaces(*sm, *nv_flinger, system); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 884951428..3dfb0740a 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -21,7 +21,9 @@ class System; namespace Kernel { class HLERequestContext; -} +class KClientPort; +class KServerSession; +} // namespace Kernel namespace Service { @@ -64,12 +66,19 @@ public: /// Creates a port pair and registers this service with the given ServiceManager. void InstallAsService(SM::ServiceManager& service_manager); - /// Creates a port pair and registers it on the kernel's global port registry. - void InstallAsNamedPort(Kernel::KernelCore& kernel); - /// Invokes a service request routine. + + /// Invokes a service request routine using the HIPC protocol. void InvokeRequest(Kernel::HLERequestContext& ctx); + + /// Invokes a service request routine using the HIPC protocol. + void InvokeRequestTipc(Kernel::HLERequestContext& ctx); + + /// Creates a port pair and registers it on the kernel's global port registry. + Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel); + /// Handles a synchronization request for the service. - ResultCode HandleSyncRequest(Kernel::HLERequestContext& context) override; + ResultCode HandleSyncRequest(Kernel::KServerSession& session, + Kernel::HLERequestContext& context) override; protected: /// Member-function pointer type of SyncRequest handlers. @@ -102,6 +111,7 @@ private: ~ServiceFrameworkBase() override; void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n); + void RegisterHandlersBaseTipc(const FunctionInfoBase* functions, std::size_t n); void ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info); /// Identifier string used to connect to the service. @@ -116,6 +126,7 @@ private: /// Function used to safely up-cast pointers to the derived class before invoking a handler. InvokerFn* handler_invoker; boost::container::flat_map<u32, FunctionInfoBase> handlers; + boost::container::flat_map<u32, FunctionInfoBase> handlers_tipc; /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. Common::SpinLock lock_service; @@ -183,6 +194,20 @@ protected: RegisterHandlersBase(functions, n); } + /// Registers handlers in the service. + template <std::size_t N> + void RegisterHandlersTipc(const FunctionInfo (&functions)[N]) { + RegisterHandlersTipc(functions, N); + } + + /** + * Registers handlers in the service. Usually prefer using the other RegisterHandlers + * overload in order to avoid needing to specify the array size. + */ + void RegisterHandlersTipc(const FunctionInfo* functions, std::size_t n) { + RegisterHandlersBaseTipc(functions, n); + } + private: /** * This function is used to allow invocation of pointers to handlers stored in the base class diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index ee026e22f..de530cbfb 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -26,15 +26,23 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { // TODO(bunnei): This is just creating a new handle to the same Session. I assume this is wrong // and that we probably want to actually make an entirely new Session, but we still need to // verify this on hardware. + LOG_DEBUG(Service, "called"); + auto session = ctx.Session()->GetParent(); + + // Open a reference to the session to simulate a new one being created. + session->Open(); + session->GetClientSession().Open(); + session->GetServerSession().Open(); + IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(RESULT_SUCCESS); - rb.PushMoveObjects(ctx.Session()->GetParent()->GetClientSession()); + rb.PushMoveObjects(session->GetClientSession()); } void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called, using CloneCurrentObject"); + LOG_DEBUG(Service, "called"); CloneCurrentObject(ctx); } @@ -44,7 +52,7 @@ void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push<u16>(0x1000); + rb.Push<u16>(0x8000); } // https://switchbrew.org/wiki/IPC_Marshalling diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 568effbc9..8cc9aee8a 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -9,6 +9,7 @@ #include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_client_session.h" #include "core/hle/kernel/k_port.h" +#include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_server_port.h" #include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/k_session.h" @@ -18,6 +19,7 @@ namespace Service::SM { +constexpr ResultCode ERR_NOT_INITIALIZED(ErrorModule::SM, 2); constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::SM, 4); constexpr ResultCode ERR_INVALID_NAME(ErrorModule::SM, 6); constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); @@ -34,20 +36,17 @@ static ResultCode ValidateServiceName(const std::string& name) { LOG_ERROR(Service_SM, "Invalid service name! service={}", name); return ERR_INVALID_NAME; } - if (name.rfind('\0') != std::string::npos) { - LOG_ERROR(Service_SM, "A non null terminated service was passed"); - return ERR_INVALID_NAME; - } return RESULT_SUCCESS; } -void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self, Core::System& system) { - ASSERT(self->sm_interface.expired()); +Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core::System& system) { + ASSERT(self.sm_interface.expired()); auto sm = std::make_shared<SM>(self, system); - sm->InstallAsNamedPort(system.Kernel()); - self->sm_interface = sm; - self->controller_interface = std::make_unique<Controller>(system); + self.sm_interface = sm; + self.controller_interface = std::make_unique<Controller>(system); + + return sm->CreatePort(system.Kernel()); } ResultVal<Kernel::KServerPort*> ServiceManager::RegisterService(std::string name, @@ -107,33 +106,68 @@ SM::~SM() = default; void SM::Initialize(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_SM, "called"); + is_initialized = true; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void SM::GetService(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; + auto result = GetServiceImpl(ctx); + if (result.Succeeded()) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; + rb.Push(result.Code()); + rb.PushMoveObjects(result.Unwrap()); + } else { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result.Code()); + } +} + +void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) { + auto result = GetServiceImpl(ctx); + IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; + rb.Push(result.Code()); + rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr); +} + +static std::string PopServiceName(IPC::RequestParser& rp) { auto name_buf = rp.PopRaw<std::array<char, 8>>(); - auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); + std::string result; + for (const auto& c : name_buf) { + if (c >= ' ' && c <= '~') { + result.push_back(c); + } + } + return result; +} - std::string name(name_buf.begin(), end); +ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& ctx) { + if (!is_initialized) { + return ERR_NOT_INITIALIZED; + } + + IPC::RequestParser rp{ctx}; + std::string name(PopServiceName(rp)); - auto result = service_manager->GetServicePort(name); + auto result = service_manager.GetServicePort(name); if (result.Failed()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result.Code()); LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.Code().raw); - if (name.length() == 0) - return; // LibNX Fix - UNIMPLEMENTED(); - return; + return result.Code(); } auto* port = result.Unwrap(); + // Kernel::KScopedResourceReservation session_reservation( + // kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions); + // R_UNLESS(session_reservation.Succeeded(), Kernel::ResultLimitReached); + auto* session = Kernel::KSession::Create(kernel); session->Initialize(&port->GetClientPort(), std::move(name)); + // Commit the session reservation. + // session_reservation.Commit(); + if (port->GetServerPort().GetHLEHandler()) { port->GetServerPort().GetHLEHandler()->ClientConnected(&session->GetServerSession()); } else { @@ -141,18 +175,12 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { } LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); - IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; - rb.Push(RESULT_SUCCESS); - rb.PushMoveObjects(session->GetClientSession()); + return MakeResult(&session->GetClientSession()); } void SM::RegisterService(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - - const auto name_buf = rp.PopRaw<std::array<char, 8>>(); - const auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); - - const std::string name(name_buf.begin(), end); + std::string name(PopServiceName(rp)); const auto is_light = static_cast<bool>(rp.PopRaw<u32>()); const auto max_session_count = rp.PopRaw<u32>(); @@ -160,7 +188,7 @@ void SM::RegisterService(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_SM, "called with name={}, max_session_count={}, is_light={}", name, max_session_count, is_light); - auto handle = service_manager->RegisterService(name, max_session_count); + auto handle = service_manager.RegisterService(name, max_session_count); if (handle.Failed()) { LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", handle.Code().raw); @@ -178,28 +206,31 @@ void SM::RegisterService(Kernel::HLERequestContext& ctx) { void SM::UnregisterService(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; + std::string name(PopServiceName(rp)); - const auto name_buf = rp.PopRaw<std::array<char, 8>>(); - const auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); - - const std::string name(name_buf.begin(), end); LOG_DEBUG(Service_SM, "called with name={}", name); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(service_manager->UnregisterService(name)); + rb.Push(service_manager.UnregisterService(name)); } -SM::SM(std::shared_ptr<ServiceManager> service_manager_, Core::System& system_) +SM::SM(ServiceManager& service_manager_, Core::System& system_) : ServiceFramework{system_, "sm:", 4}, - service_manager{std::move(service_manager_)}, kernel{system_.Kernel()} { - static const FunctionInfo functions[] = { + service_manager{service_manager_}, kernel{system_.Kernel()} { + RegisterHandlers({ {0, &SM::Initialize, "Initialize"}, {1, &SM::GetService, "GetService"}, {2, &SM::RegisterService, "RegisterService"}, {3, &SM::UnregisterService, "UnregisterService"}, {4, nullptr, "DetachClient"}, - }; - RegisterHandlers(functions); + }); + RegisterHandlersTipc({ + {0, &SM::Initialize, "Initialize"}, + {1, &SM::GetServiceTipc, "GetService"}, + {2, &SM::RegisterService, "RegisterService"}, + {3, &SM::UnregisterService, "UnregisterService"}, + {4, nullptr, "DetachClient"}, + }); } } // namespace Service::SM diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index af5010c3b..60f0b3f8a 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -34,22 +34,26 @@ class Controller; /// Interface to "sm:" service class SM final : public ServiceFramework<SM> { public: - explicit SM(std::shared_ptr<ServiceManager> service_manager_, Core::System& system_); + explicit SM(ServiceManager& service_manager_, Core::System& system_); ~SM() override; private: void Initialize(Kernel::HLERequestContext& ctx); void GetService(Kernel::HLERequestContext& ctx); + void GetServiceTipc(Kernel::HLERequestContext& ctx); void RegisterService(Kernel::HLERequestContext& ctx); void UnregisterService(Kernel::HLERequestContext& ctx); - std::shared_ptr<ServiceManager> service_manager; + ResultVal<Kernel::KClientSession*> GetServiceImpl(Kernel::HLERequestContext& ctx); + + ServiceManager& service_manager; + bool is_initialized{}; Kernel::KernelCore& kernel; }; class ServiceManager { public: - static void InstallInterfaces(std::shared_ptr<ServiceManager> self, Core::System& system); + static Kernel::KClientPort& InterfaceFactory(ServiceManager& self, Core::System& system); explicit ServiceManager(Kernel::KernelCore& kernel_); ~ServiceManager(); |