kern: Implement SvcManageNamedPort

This commit is contained in:
Michael Scire 2020-03-13 23:12:47 -07:00
parent 6c52cc3e26
commit ca26d8ce27
22 changed files with 1035 additions and 11 deletions

View file

@ -21,7 +21,61 @@ namespace ams::kern::svc {
namespace {
Result ManageNamedPort(ams::svc::Handle *out_server_handle, KUserPointer<const char *> user_name, s32 max_sessions) {
/* Copy the provided name from user memory to kernel memory. */
char name[KObjectName::NameLengthMax] = {};
R_TRY(user_name.CopyStringTo(name, sizeof(name)));
/* Validate that sessions and name are valid. */
R_UNLESS(max_sessions >= 0, svc::ResultOutOfRange());
R_UNLESS(name[sizeof(name) - 1] == '\x00', svc::ResultOutOfRange());
if (max_sessions > 0) {
MESOSPHERE_LOG("Creating Named Port %s (max sessions = %d)\n", name, max_sessions);
/* Get the current handle table. */
auto &handle_table = GetCurrentProcess().GetHandleTable();
/* Create a new port. */
KPort *port = KPort::Create();
R_UNLESS(port != nullptr, svc::ResultOutOfResource());
/* Reserve a handle for the server port. */
R_TRY(handle_table.Reserve(out_server_handle));
auto reserve_guard = SCOPE_GUARD { handle_table.Unreserve(*out_server_handle); };
/* Initialize the new port. */
port->Initialize(max_sessions, false, 0);
/* Register the port. */
KPort::Register(port);
/* Register the handle in the table. */
handle_table.Register(*out_server_handle, std::addressof(port->GetServerPort()));
reserve_guard.Cancel();
auto register_guard = SCOPE_GUARD { handle_table.Remove(*out_server_handle); };
/* Create a new object name. */
R_TRY(KObjectName::NewFromName(std::addressof(port->GetClientPort()), name));
/* Perform resource cleanup. */
port->GetServerPort().Close();
port->GetClientPort().Close();
register_guard.Cancel();
} else /* if (max_sessions == 0) */ {
MESOSPHERE_LOG("Deleting Named Port %s\n", name);
/* Ensure that this else case is correct. */
MESOSPHERE_AUDIT(max_sessions == 0);
/* If we're closing, there's no server handle. */
*out_server_handle = ams::svc::InvalidHandle;
/* Delete the object. */
R_TRY(KObjectName::Delete<KClientPort>(name));
}
return ResultSuccess();
}
}
@ -36,7 +90,7 @@ namespace ams::kern::svc {
}
Result ManageNamedPort64(ams::svc::Handle *out_server_handle, KUserPointer<const char *> name, int32_t max_sessions) {
MESOSPHERE_PANIC("Stubbed SvcManageNamedPort64 was called.");
return ManageNamedPort(out_server_handle, name, max_sessions);
}
Result ConnectToPort64(ams::svc::Handle *out_handle, ams::svc::Handle port) {
@ -54,7 +108,7 @@ namespace ams::kern::svc {
}
Result ManageNamedPort64From32(ams::svc::Handle *out_server_handle, KUserPointer<const char *> name, int32_t max_sessions) {
MESOSPHERE_PANIC("Stubbed SvcManageNamedPort64From32 was called.");
return ManageNamedPort(out_server_handle, name, max_sessions);
}
Result ConnectToPort64From32(ams::svc::Handle *out_handle, ams::svc::Handle port) {

View file

@ -21,6 +21,32 @@ namespace ams::kern::svc {
namespace {
Result GetProcessId(u64 *out_process_id, ams::svc::Handle handle) {
/* Get the object from the handle table. */
KScopedAutoObject obj = GetCurrentProcess().GetHandleTable().GetObject<KAutoObject>(handle);
R_UNLESS(obj.IsNotNull(), svc::ResultInvalidHandle());
/* Get the process from the object. */
KProcess *process = nullptr;
if (obj->IsDerivedFrom(KProcess::GetStaticTypeObj())) {
/* The object is a process, so we can use it directly. */
process = reinterpret_cast<KProcess *>(obj.GetPointerUnsafe());
} else if (obj->IsDerivedFrom(KThread::GetStaticTypeObj())) {
/* The object is a thread, so we want to use its parent. */
process = reinterpret_cast<KThread *>(obj.GetPointerUnsafe())->GetOwnerProcess();
} else if (obj->IsDerivedFrom(KDebug::GetStaticTypeObj())) {
/* The object is a debug, so we want to use the process it's attached to. */
MESOSPHERE_UNIMPLEMENTED();
}
/* Make sure the target process exists. */
R_UNLESS(process != nullptr, svc::ResultInvalidHandle());
/* Get the process id. */
*out_process_id = process->GetId();
return ResultSuccess();
}
}
@ -32,7 +58,7 @@ namespace ams::kern::svc {
}
Result GetProcessId64(uint64_t *out_process_id, ams::svc::Handle process_handle) {
MESOSPHERE_PANIC("Stubbed SvcGetProcessId64 was called.");
return GetProcessId(out_process_id, process_handle);
}
Result GetProcessList64(int32_t *out_num_processes, KUserPointer<uint64_t *> out_process_ids, int32_t max_out_count) {
@ -62,7 +88,7 @@ namespace ams::kern::svc {
}
Result GetProcessId64From32(uint64_t *out_process_id, ams::svc::Handle process_handle) {
MESOSPHERE_PANIC("Stubbed SvcGetProcessId64From32 was called.");
return GetProcessId(out_process_id, process_handle);
}
Result GetProcessList64From32(int32_t *out_num_processes, KUserPointer<uint64_t *> out_process_ids, int32_t max_out_count) {