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_info.cpp5
-rw-r--r--src/core/hle/kernel/svc/svc_port.cpp51
2 files changed, 24 insertions, 32 deletions
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp
index 58dc47508..cbed4dc8c 100644
--- a/src/core/hle/kernel/svc/svc_info.cpp
+++ b/src/core/hle/kernel/svc/svc_info.cpp
@@ -126,6 +126,11 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
126 *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource(); 126 *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource();
127 return ResultSuccess; 127 return ResultSuccess;
128 128
129 case InfoType::IsApplication:
130 LOG_WARNING(Kernel_SVC, "(STUBBED) Assuming process is application");
131 *result = true;
132 return ResultSuccess;
133
129 case InfoType::FreeThreadCount: 134 case InfoType::FreeThreadCount:
130 *result = process->GetFreeThreadCount(); 135 *result = process->GetFreeThreadCount();
131 return ResultSuccess; 136 return ResultSuccess;
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp
index 0b5b4ba2b..78c2a8d17 100644
--- a/src/core/hle/kernel/svc/svc_port.cpp
+++ b/src/core/hle/kernel/svc/svc_port.cpp
@@ -12,56 +12,40 @@
12 12
13namespace Kernel::Svc { 13namespace Kernel::Svc {
14 14
15/// Connect to an OS service given the port name, returns the handle to the port to out 15Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr user_name) {
16Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { 16 // Copy the provided name from user memory to kernel memory.
17 auto& memory = system.Memory(); 17 auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
18 if (!memory.IsValidVirtualAddress(port_name_address)) {
19 LOG_ERROR(Kernel_SVC,
20 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}",
21 port_name_address);
22 return ResultNotFound;
23 }
24 18
25 static constexpr std::size_t PortNameMaxLength = 11; 19 std::array<char, KObjectName::NameLengthMax> name{};
26 // Read 1 char beyond the max allowed port name to detect names that are too long. 20 std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1);
27 const std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1);
28 if (port_name.size() > PortNameMaxLength) {
29 LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength,
30 port_name.size());
31 return ResultOutOfRange;
32 }
33 21
34 LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); 22 // Validate that the name is valid.
23 R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange);
35 24
36 // Get the current handle table. 25 // Get the current handle table.
37 auto& kernel = system.Kernel(); 26 auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
38 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
39 27
40 // Find the client port. 28 // Find the client port.
41 auto port = kernel.CreateNamedServicePort(port_name); 29 auto port = KObjectName::Find<KClientPort>(system.Kernel(), name.data());
42 if (!port) { 30 R_UNLESS(port.IsNotNull(), ResultNotFound);
43 LOG_ERROR(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
44 return ResultNotFound;
45 }
46 31
47 // Reserve a handle for the port. 32 // Reserve a handle for the port.
48 // NOTE: Nintendo really does write directly to the output handle here. 33 // NOTE: Nintendo really does write directly to the output handle here.
49 R_TRY(handle_table.Reserve(out)); 34 R_TRY(handle_table.Reserve(out));
50 auto handle_guard = SCOPE_GUARD({ handle_table.Unreserve(*out); }); 35 ON_RESULT_FAILURE {
36 handle_table.Unreserve(*out);
37 };
51 38
52 // Create a session. 39 // Create a session.
53 KClientSession* session{}; 40 KClientSession* session;
54 R_TRY(port->CreateSession(std::addressof(session))); 41 R_TRY(port->CreateSession(std::addressof(session)));
55 42
56 kernel.RegisterNamedServiceHandler(port_name, &port->GetParent()->GetServerPort());
57
58 // Register the session in the table, close the extra reference. 43 // Register the session in the table, close the extra reference.
59 handle_table.Register(*out, session); 44 handle_table.Register(*out, session);
60 session->Close(); 45 session->Close();
61 46
62 // We succeeded. 47 // We succeeded.
63 handle_guard.Cancel(); 48 R_SUCCEED();
64 return ResultSuccess;
65} 49}
66 50
67Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, 51Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client,
@@ -78,8 +62,11 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) {
78Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, 62Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
79 int32_t max_sessions) { 63 int32_t max_sessions) {
80 // Copy the provided name from user memory to kernel memory. 64 // Copy the provided name from user memory to kernel memory.
65 auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
66
67 // Copy the provided name from user memory to kernel memory.
81 std::array<char, KObjectName::NameLengthMax> name{}; 68 std::array<char, KObjectName::NameLengthMax> name{};
82 system.Memory().ReadBlock(user_name, name.data(), sizeof(name)); 69 std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1);
83 70
84 // Validate that sessions and name are valid. 71 // Validate that sessions and name are valid.
85 R_UNLESS(max_sessions >= 0, ResultOutOfRange); 72 R_UNLESS(max_sessions >= 0, ResultOutOfRange);