diff options
Diffstat (limited to 'src/core/hle/kernel/svc')
| -rw-r--r-- | src/core/hle/kernel/svc/svc_info.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_port.cpp | 51 |
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 | ||
| 13 | namespace Kernel::Svc { | 13 | namespace Kernel::Svc { |
| 14 | 14 | ||
| 15 | /// Connect to an OS service given the port name, returns the handle to the port to out | 15 | Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr user_name) { |
| 16 | Result 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 | ||
| 67 | Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, | 51 | Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, |
| @@ -78,8 +62,11 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) { | |||
| 78 | Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, | 62 | Result 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); |