summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/svc')
-rw-r--r--src/core/hle/kernel/svc/svc_port.cpp54
1 files changed, 51 insertions, 3 deletions
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp
index 2b7cebde5..2f9bfcb52 100644
--- a/src/core/hle/kernel/svc/svc_port.cpp
+++ b/src/core/hle/kernel/svc/svc_port.cpp
@@ -5,6 +5,7 @@
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/kernel/k_client_port.h" 6#include "core/hle/kernel/k_client_port.h"
7#include "core/hle/kernel/k_client_session.h" 7#include "core/hle/kernel/k_client_session.h"
8#include "core/hle/kernel/k_object_name.h"
8#include "core/hle/kernel/k_port.h" 9#include "core/hle/kernel/k_port.h"
9#include "core/hle/kernel/k_process.h" 10#include "core/hle/kernel/k_process.h"
10#include "core/hle/kernel/svc.h" 11#include "core/hle/kernel/svc.h"
@@ -74,10 +75,57 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) {
74 R_THROW(ResultNotImplemented); 75 R_THROW(ResultNotImplemented);
75} 76}
76 77
77Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name, 78Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
78 int32_t max_sessions) { 79 int32_t max_sessions) {
79 UNIMPLEMENTED(); 80 // Copy the provided name from user memory to kernel memory.
80 R_THROW(ResultNotImplemented); 81 std::array<char, KObjectName::NameLengthMax> name{};
82 system.Memory().ReadBlock(user_name, name.data(), sizeof(name));
83
84 // Validate that sessions and name are valid.
85 R_UNLESS(max_sessions >= 0, ResultOutOfRange);
86 R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange);
87
88 if (max_sessions > 0) {
89 // Get the current handle table.
90 auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
91
92 // Create a new port.
93 KPort* port = KPort::Create(system.Kernel());
94 R_UNLESS(port != nullptr, ResultOutOfResource);
95
96 // Initialize the new port.
97 port->Initialize(max_sessions, false, "");
98
99 // Register the port.
100 KPort::Register(system.Kernel(), port);
101
102 // Ensure that our only reference to the port is in the handle table when we're done.
103 SCOPE_EXIT({
104 port->GetClientPort().Close();
105 port->GetServerPort().Close();
106 });
107
108 // Register the handle in the table.
109 R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort())));
110 ON_RESULT_FAILURE {
111 handle_table.Remove(*out_server_handle);
112 };
113
114 // Create a new object name.
115 R_TRY(KObjectName::NewFromName(system.Kernel(), std::addressof(port->GetClientPort()),
116 name.data()));
117 } else /* if (max_sessions == 0) */ {
118 // Ensure that this else case is correct.
119 ASSERT(max_sessions == 0);
120
121 // If we're closing, there's no server handle.
122 *out_server_handle = InvalidHandle;
123
124 // Delete the object.
125 R_TRY(KObjectName::Delete<KClientPort>(system.Kernel(), name.data()));
126 }
127
128 R_SUCCEED();
81} 129}
82 130
83Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name) { 131Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name) {