diff options
| -rw-r--r-- | src/core/hle/service/sm/sm.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm_controller.cpp | 33 |
2 files changed, 27 insertions, 13 deletions
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index e2b8d8720..cb6c0e96f 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -149,9 +149,10 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& | |||
| 149 | return port_result.Code(); | 149 | return port_result.Code(); |
| 150 | } | 150 | } |
| 151 | auto& port = port_result.Unwrap(); | 151 | auto& port = port_result.Unwrap(); |
| 152 | SCOPE_EXIT({ port->GetClientPort().Close(); }); | 152 | SCOPE_EXIT({ |
| 153 | 153 | port->GetClientPort().Close(); | |
| 154 | kernel.RegisterServerObject(&port->GetServerPort()); | 154 | port->GetServerPort().Close(); |
| 155 | }); | ||
| 155 | 156 | ||
| 156 | // Create a new session. | 157 | // Create a new session. |
| 157 | Kernel::KClientSession* session{}; | 158 | Kernel::KClientSession* session{}; |
diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp index 273f79568..46a8439d8 100644 --- a/src/core/hle/service/sm/sm_controller.cpp +++ b/src/core/hle/service/sm/sm_controller.cpp | |||
| @@ -28,23 +28,36 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { | |||
| 28 | void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { | 28 | void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { |
| 29 | LOG_DEBUG(Service, "called"); | 29 | LOG_DEBUG(Service, "called"); |
| 30 | 30 | ||
| 31 | auto& process = *ctx.GetThread().GetOwnerProcess(); | ||
| 31 | auto& parent_session = *ctx.Session()->GetParent(); | 32 | auto& parent_session = *ctx.Session()->GetParent(); |
| 32 | auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort(); | ||
| 33 | auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager(); | 33 | auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager(); |
| 34 | auto& session_handler = session_manager->SessionHandler(); | ||
| 34 | 35 | ||
| 35 | // Create a session. | 36 | // FIXME: this is duplicated from the SVC, it should just call it instead |
| 36 | Kernel::KClientSession* session{}; | 37 | // once this is a proper process |
| 37 | const Result result = parent_port.CreateSession(std::addressof(session), session_manager); | 38 | |
| 38 | if (result.IsError()) { | 39 | // Reserve a new session from the process resource limit. |
| 39 | LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw); | 40 | Kernel::KScopedResourceReservation session_reservation(&process, |
| 40 | IPC::ResponseBuilder rb{ctx, 2}; | 41 | Kernel::LimitableResource::Sessions); |
| 41 | rb.Push(result); | 42 | ASSERT(session_reservation.Succeeded()); |
| 42 | } | 43 | |
| 44 | // Create the session. | ||
| 45 | Kernel::KSession* session = Kernel::KSession::Create(system.Kernel()); | ||
| 46 | ASSERT(session != nullptr); | ||
| 47 | |||
| 48 | // Initialize the session. | ||
| 49 | session->Initialize(nullptr, parent_session.GetName(), session_manager); | ||
| 50 | |||
| 51 | // Commit the session reservation. | ||
| 52 | session_reservation.Commit(); | ||
| 53 | |||
| 54 | // Register the session. | ||
| 55 | session_handler.ClientConnected(&session->GetServerSession()); | ||
| 43 | 56 | ||
| 44 | // We succeeded. | 57 | // We succeeded. |
| 45 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; | 58 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; |
| 46 | rb.Push(ResultSuccess); | 59 | rb.Push(ResultSuccess); |
| 47 | rb.PushMoveObjects(session); | 60 | rb.PushMoveObjects(session->GetClientSession()); |
| 48 | } | 61 | } |
| 49 | 62 | ||
| 50 | void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { | 63 | void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { |