From 61929d6e21e3297c681e122d2228a61c5184a236 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 17 Feb 2021 04:08:58 -0800 Subject: [PATCH] htcs: hook service objects up to (unimplemented) manager apis --- .../include/stratosphere/sf/sf_buffers.hpp | 8 +- .../source/htcs/impl/htcs_impl.cpp | 31 +++ .../source/htcs/impl/htcs_impl.hpp | 24 ++ .../source/htcs/impl/htcs_manager.hpp | 30 +++ .../server/htcs_manager_service_object.cpp | 40 +++- ...tcs_manager_service_object_deprecated.cpp} | 0 .../server/htcs_service_object_allocator.hpp | 25 ++ .../server/htcs_socket_service_object.cpp | 224 +++++++++++++++--- .../htcs_socket_service_object_deprecated.cpp | 29 +++ .../libvapours/include/vapours/results.hpp | 1 + .../include/vapours/results/htcs_results.hpp | 25 ++ 11 files changed, 396 insertions(+), 41 deletions(-) create mode 100644 libraries/libstratosphere/source/htcs/impl/htcs_impl.cpp create mode 100644 libraries/libstratosphere/source/htcs/impl/htcs_impl.hpp rename libraries/libstratosphere/source/htcs/server/{htcs_manager_service_object_reprecated.cpp => htcs_manager_service_object_deprecated.cpp} (100%) create mode 100644 libraries/libstratosphere/source/htcs/server/htcs_service_object_allocator.hpp create mode 100644 libraries/libstratosphere/source/htcs/server/htcs_socket_service_object_deprecated.cpp create mode 100644 libraries/libvapours/include/vapours/results/htcs_results.hpp diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp index 1ae3ec12c..438e88f67 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp @@ -206,11 +206,11 @@ namespace ams::sf { } constexpr explicit operator Span() const { - return {this->GetPointer(), static_cast(this->GetSize())}; + return {this->GetPointer(), this->GetSize()}; } constexpr Span ToSpan() const { - return {this->GetPointer(), static_cast(this->GetSize())}; + return {this->GetPointer(), this->GetSize()}; } }; @@ -238,11 +238,11 @@ namespace ams::sf { } constexpr explicit operator Span() const { - return {this->GetPointer(), static_cast(this->GetSize())}; + return {this->GetPointer(), this->GetSize()}; } constexpr Span ToSpan() const { - return {this->GetPointer(), static_cast(this->GetSize())}; + return {this->GetPointer(), this->GetSize()}; } }; diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_impl.cpp b/libraries/libstratosphere/source/htcs/impl/htcs_impl.cpp new file mode 100644 index 000000000..8226fdf8d --- /dev/null +++ b/libraries/libstratosphere/source/htcs/impl/htcs_impl.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "htcs_impl.hpp" + +namespace ams::htcs::impl { + + namespace { + + constexpr const htcs::HtcsPeerName PeerNameAny = {""}; + constexpr const htcs::HtcsPeerName DefaultHostName = {""}; + + } + + const htcs::HtcsPeerName GetPeerNameAny() { return PeerNameAny; } + const htcs::HtcsPeerName GetDefaultHostName() { return DefaultHostName; } + +} diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_impl.hpp b/libraries/libstratosphere/source/htcs/impl/htcs_impl.hpp new file mode 100644 index 000000000..4ba4e3e25 --- /dev/null +++ b/libraries/libstratosphere/source/htcs/impl/htcs_impl.hpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::htcs::impl { + + const htcs::HtcsPeerName GetPeerNameAny(); + const htcs::HtcsPeerName GetDefaultHostName(); + +} diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_manager.hpp b/libraries/libstratosphere/source/htcs/impl/htcs_manager.hpp index 433fc8b7f..4fcb48984 100644 --- a/libraries/libstratosphere/source/htcs/impl/htcs_manager.hpp +++ b/libraries/libstratosphere/source/htcs/impl/htcs_manager.hpp @@ -32,6 +32,36 @@ namespace ams::htcs::impl { os::EventType *GetServiceAvailabilityEvent(); bool IsServiceAvailable(); + public: + void Socket(s32 *out_err, s32 *out_desc, bool enable_disconnection_emulation); + void Close(s32 *out_err, s32 *out_res, s32 desc); + void Connect(s32 *out_err, s32 *out_res, const SockAddrHtcs &address, s32 desc); + void Bind(s32 *out_err, s32 *out_res, const SockAddrHtcs &address, s32 desc); + void Listen(s32 *out_err, s32 *out_res, s32 backlog_count, s32 desc); + void Recv(s32 *out_err, s64 *out_size, char *buffer, size_t size, s32 flags, s32 desc); + void Send(s32 *out_err, s64 *out_size, const char *buffer, size_t size, s32 flags, s32 desc); + void Shutdown(s32 *out_err, s32 *out_res, s32 how, s32 desc); + void Fcntl(s32 *out_err, s32 *out_res, s32 command, s32 value, s32 desc); + + Result AcceptStart(u32 *out_task_id, Handle *out_handle, s32 desc); + void AcceptResults(s32 *out_err, s32 *out_desc, SockAddrHtcs *out_address, u32 task_id, s32 desc); + + Result RecvStart(u32 *out_task_id, Handle *out_handle, s64 size, s32 desc, s32 flags); + void RecvResults(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc); + + Result SendStart(u32 *out_task_id, Handle *out_handle, const char *buffer, s64 size, s32 desc, s32 flags); + Result SendLargeStart(u32 *out_task_id, Handle *out_handle, const char **buffers, const s64 *sizes, s32 count, s32 desc, s32 flags); + void SendResults(s32 *out_err, s64 *out_size, u32 task_id, s32 desc); + + Result StartSend(u32 *out_task_id, Handle *out_handle, s32 desc, s64 size, s32 flags); + Result ContinueSend(s64 *out_size, const char *buffer, s64 buffer_size, u32 task_id, s32 desc); + void EndSend(s32 *out_err, s64 *out_size, u32 task_id, s32 desc); + + Result StartRecv(u32 *out_task_id, Handle *out_handle, s64 size, s32 desc, s32 flags); + void EndRecv(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc); + + Result StartSelect(u32 *out_task_id, Handle *out_handle, Span read_handles, Span write_handles, Span exception_handles, s64 tv_sec, s64 tv_usec); + Result EndSelect(s32 *out_err, s32 *out_res, Span read_handles, Span write_handles, Span exception_handles, u32 task_id); }; } diff --git a/libraries/libstratosphere/source/htcs/server/htcs_manager_service_object.cpp b/libraries/libstratosphere/source/htcs/server/htcs_manager_service_object.cpp index e3a328f0f..7eb2ef215 100644 --- a/libraries/libstratosphere/source/htcs/server/htcs_manager_service_object.cpp +++ b/libraries/libstratosphere/source/htcs/server/htcs_manager_service_object.cpp @@ -16,15 +16,14 @@ #include #include "htcs_manager_service_object.hpp" #include "htcs_socket_service_object.hpp" +#include "htcs_service_object_allocator.hpp" +#include "../impl/htcs_manager.hpp" +#include "../impl/htcs_impl.hpp" namespace ams::htcs::server { namespace { - struct ServiceObjectAllocatorTag; - using ServiceObjectAllocator = ams::sf::ExpHeapStaticAllocator<32_KB, ServiceObjectAllocatorTag>; - using ServiceObjectFactory = ams::sf::ObjectFactory; - class StaticAllocatorInitializer { public: StaticAllocatorInitializer() { @@ -35,11 +34,13 @@ namespace ams::htcs::server { } Result ManagerServiceObject::GetPeerNameAny(sf::Out out) { - AMS_ABORT("ManagerServiceObject::GetPeerNameAny"); + *out = impl::GetPeerNameAny(); + return ResultSuccess(); } Result ManagerServiceObject::GetDefaultHostName(sf::Out out) { - AMS_ABORT("ManagerServiceObject::GetDefaultHostName"); + *out = impl::GetDefaultHostName(); + return ResultSuccess(); } Result ManagerServiceObject::CreateSocketOld(sf::Out out_err, sf::Out> out) { @@ -47,7 +48,20 @@ namespace ams::htcs::server { } Result ManagerServiceObject::CreateSocket(sf::Out out_err, sf::Out> out, bool enable_disconnection_emulation) { - AMS_ABORT("ManagerServiceObject::CreateSocket"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Create a new socket. */ + s32 desc; + manager->Socket(out_err.GetPointer(), std::addressof(desc), enable_disconnection_emulation); + + /* If an error occurred, we're done. */ + R_SUCCEED_IF(*out_err != 0); + + /* Create a new socket object. */ + *out = ServiceObjectFactory::CreateSharedEmplaced(this, desc); + + return ResultSuccess(); } Result ManagerServiceObject::RegisterProcessId(const sf::ClientProcessId &client_pid) { @@ -61,11 +75,19 @@ namespace ams::htcs::server { } Result ManagerServiceObject::StartSelect(sf::Out out_task_id, sf::OutCopyHandle out_event, const sf::InMapAliasArray &read_handles, const sf::InMapAliasArray &write_handles, const sf::InMapAliasArray &exception_handles, s64 tv_sec, s64 tv_usec) { - AMS_ABORT("ManagerServiceObject::StartSelect"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Start the select. */ + return manager->StartSelect(out_task_id.GetPointer(), out_event.GetHandlePointer(), read_handles.ToSpan(), write_handles.ToSpan(), exception_handles.ToSpan(), tv_sec, tv_usec); } Result ManagerServiceObject::EndSelect(sf::Out out_err, sf::Out out_res, const sf::OutMapAliasArray &read_handles, const sf::OutMapAliasArray &write_handles, const sf::OutMapAliasArray &exception_handles, u32 task_id) { - AMS_ABORT("ManagerServiceObject::EndSelect"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* End the select. */ + return manager->EndSelect(out_err.GetPointer(), out_res.GetPointer(), read_handles.ToSpan(), write_handles.ToSpan(), exception_handles.ToSpan(), task_id); } } diff --git a/libraries/libstratosphere/source/htcs/server/htcs_manager_service_object_reprecated.cpp b/libraries/libstratosphere/source/htcs/server/htcs_manager_service_object_deprecated.cpp similarity index 100% rename from libraries/libstratosphere/source/htcs/server/htcs_manager_service_object_reprecated.cpp rename to libraries/libstratosphere/source/htcs/server/htcs_manager_service_object_deprecated.cpp diff --git a/libraries/libstratosphere/source/htcs/server/htcs_service_object_allocator.hpp b/libraries/libstratosphere/source/htcs/server/htcs_service_object_allocator.hpp new file mode 100644 index 000000000..66cf20870 --- /dev/null +++ b/libraries/libstratosphere/source/htcs/server/htcs_service_object_allocator.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::htcs::server { + + struct ServiceObjectAllocatorTag; + using ServiceObjectAllocator = ams::sf::ExpHeapStaticAllocator<32_KB, ServiceObjectAllocatorTag>; + using ServiceObjectFactory = ams::sf::ObjectFactory; + +} diff --git a/libraries/libstratosphere/source/htcs/server/htcs_socket_service_object.cpp b/libraries/libstratosphere/source/htcs/server/htcs_socket_service_object.cpp index ebf277520..9e7e31692 100644 --- a/libraries/libstratosphere/source/htcs/server/htcs_socket_service_object.cpp +++ b/libraries/libstratosphere/source/htcs/server/htcs_socket_service_object.cpp @@ -15,6 +15,8 @@ */ #include #include "htcs_socket_service_object.hpp" +#include "htcs_service_object_allocator.hpp" +#include "../impl/htcs_manager.hpp" namespace ams::htcs::server { @@ -23,107 +25,273 @@ namespace ams::htcs::server { } SocketServiceObject::~SocketServiceObject() { - AMS_ABORT("SocketServiceObject::~SocketServiceObject"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Close the underlying socket. */ + s32 dummy_err, dummy_res; + manager->Close(std::addressof(dummy_err), std::addressof(dummy_res), m_desc); } Result SocketServiceObject::Close(sf::Out out_err, sf::Out out_res) { - AMS_ABORT("SocketServiceObject::Close"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Close the underlying socket. */ + manager->Close(out_err.GetPointer(), out_res.GetPointer(), m_desc); + + return ResultSuccess(); } Result SocketServiceObject::Connect(sf::Out out_err, sf::Out out_res, const htcs::SockAddrHtcs &address) { - AMS_ABORT("SocketServiceObject::Connect"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Perform the connect. */ + manager->Connect(out_err.GetPointer(), out_res.GetPointer(), address, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::Bind(sf::Out out_err, sf::Out out_res, const htcs::SockAddrHtcs &address) { - AMS_ABORT("SocketServiceObject::Bind"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Perform the bind. */ + manager->Bind(out_err.GetPointer(), out_res.GetPointer(), address, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::Listen(sf::Out out_err, sf::Out out_res, s32 backlog_count) { - AMS_ABORT("SocketServiceObject::Listen"); - } + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); - Result SocketServiceObject::Accept(sf::Out out_err, sf::Out> out, sf::Out out_address) { - AMS_ABORT("SocketServiceObject::Accept"); + /* Perform the listen. */ + manager->Listen(out_err.GetPointer(), out_res.GetPointer(), backlog_count, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::Recv(sf::Out out_err, sf::Out out_size, const sf::OutAutoSelectBuffer &buffer, s32 flags) { - AMS_ABORT("SocketServiceObject::Recv"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Perform the recv. */ + manager->Recv(out_err.GetPointer(), out_size.GetPointer(), reinterpret_cast(buffer.GetPointer()), buffer.GetSize(), flags, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::Send(sf::Out out_err, sf::Out out_size, const sf::InAutoSelectBuffer &buffer, s32 flags) { - AMS_ABORT("SocketServiceObject::Send"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Perform the send. */ + manager->Send(out_err.GetPointer(), out_size.GetPointer(), reinterpret_cast(buffer.GetPointer()), buffer.GetSize(), flags, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::Shutdown(sf::Out out_err, sf::Out out_res, s32 how) { - AMS_ABORT("SocketServiceObject::Shutdown"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Perform the shutdown. */ + manager->Shutdown(out_err.GetPointer(), out_res.GetPointer(), how, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::Fcntl(sf::Out out_err, sf::Out out_res, s32 command, s32 value) { - AMS_ABORT("SocketServiceObject::Fcntl"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Perform the fcntl. */ + manager->Fcntl(out_err.GetPointer(), out_res.GetPointer(), command, value, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::AcceptStart(sf::Out out_task_id, sf::OutCopyHandle out_event) { - AMS_ABORT("SocketServiceObject::AcceptStart"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Start the accept. */ + return manager->AcceptStart(out_task_id.GetPointer(), out_event.GetHandlePointer(), m_desc); } Result SocketServiceObject::AcceptResults(sf::Out out_err, sf::Out> out, sf::Out out_address, u32 task_id) { - AMS_ABORT("SocketServiceObject::AcceptResults"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Get the accept results. */ + s32 desc; + manager->AcceptResults(out_err.GetPointer(), std::addressof(desc), out_address.GetPointer(), task_id, m_desc); + + /* If an error occurred, we're done. */ + R_SUCCEED_IF(*out_err != 0); + + /* Create a new socket object. */ + *out = ServiceObjectFactory::CreateSharedEmplaced(m_manager.Get(), desc); + + return ResultSuccess(); } Result SocketServiceObject::RecvStart(sf::Out out_task_id, sf::OutCopyHandle out_event, s32 mem_size, s32 flags) { - AMS_ABORT("SocketServiceObject::RecvStart"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Start the recv. */ + return manager->RecvStart(out_task_id.GetPointer(), out_event.GetHandlePointer(), mem_size, m_desc, flags); } Result SocketServiceObject::RecvResults(sf::Out out_err, sf::Out out_size, const sf::OutAutoSelectBuffer &buffer, u32 task_id) { - AMS_ABORT("SocketServiceObject::RecvResults"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Get the recv results. */ + manager->RecvResults(out_err.GetPointer(), out_size.GetPointer(), reinterpret_cast(buffer.GetPointer()), buffer.GetSize(), task_id, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::RecvLargeStart(sf::Out out_task_id, sf::OutCopyHandle out_event, s32 unaligned_size_start, s32 unaligned_size_end, s64 aligned_size, sf::CopyHandle mem_handle, s32 flags) { - AMS_ABORT("SocketServiceObject::RecvLargeStart"); + /* Check that the transfer memory size is okay. */ + R_UNLESS(util::IsIntValueRepresentable(aligned_size), htcs::ResultInvalidSize()); + + /* Attach the transfer memory. */ + os::TransferMemoryType tmem; + R_ABORT_UNLESS(os::AttachTransferMemory(std::addressof(tmem), static_cast(aligned_size), mem_handle.GetValue(), true)); + ON_SCOPE_EXIT { os::DestroyTransferMemory(std::addressof(tmem)); }; + + /* Map the transfer memory. */ + void *address; + R_TRY(os::MapTransferMemory(std::addressof(address), std::addressof(tmem), os::MemoryPermission_None)); + ON_SCOPE_EXIT { os::UnmapTransferMemory(std::addressof(tmem)); }; + + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Start the large receive. */ + return manager->RecvStart(out_task_id.GetPointer(), out_event.GetHandlePointer(), unaligned_size_start + aligned_size + unaligned_size_end, m_desc, flags); } Result SocketServiceObject::SendStartOld(sf::Out out_task_id, sf::OutCopyHandle out_event, const sf::InAutoSelectBuffer &buffer, s32 flags) { - AMS_ABORT("SocketServiceObject::SendStartOld"); + return this->SendStart(out_task_id, out_event, sf::InNonSecureAutoSelectBuffer(buffer.GetPointer(), buffer.GetSize()), flags); } Result SocketServiceObject::SendLargeStart(sf::Out out_task_id, sf::OutCopyHandle out_event, const sf::InAutoSelectBuffer &start_buffer, const sf::InAutoSelectBuffer &end_buffer, sf::CopyHandle mem_handle, s64 aligned_size, s32 flags) { - AMS_ABORT("SocketServiceObject::SendLargeStart"); + /* Check that the sizes are okay. */ + R_UNLESS(util::IsIntValueRepresentable(start_buffer.GetSize()), htcs::ResultInvalidSize()); + R_UNLESS(util::IsIntValueRepresentable(end_buffer.GetSize()), htcs::ResultInvalidSize()); + R_UNLESS(util::IsIntValueRepresentable(aligned_size), htcs::ResultInvalidSize()); + + /* Attach the transfer memory. */ + os::TransferMemoryType tmem; + R_ABORT_UNLESS(os::AttachTransferMemory(std::addressof(tmem), static_cast(aligned_size), mem_handle.GetValue(), true)); + ON_SCOPE_EXIT { os::DestroyTransferMemory(std::addressof(tmem)); }; + + /* Map the transfer memory. */ + void *address; + R_TRY(os::MapTransferMemory(std::addressof(address), std::addressof(tmem), os::MemoryPermission_None)); + ON_SCOPE_EXIT { os::UnmapTransferMemory(std::addressof(tmem)); }; + + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Start the large send. */ + constexpr auto NumBuffers = 3; + const char *pointers[NumBuffers] = { reinterpret_cast(start_buffer.GetPointer()), static_cast(address), reinterpret_cast(end_buffer.GetPointer()) }; + s64 sizes[NumBuffers] = { static_cast(start_buffer.GetSize()), aligned_size, static_cast(end_buffer.GetSize()) }; + + return manager->SendLargeStart(out_task_id.GetPointer(), out_event.GetHandlePointer(), pointers, sizes, NumBuffers, m_desc, flags); } Result SocketServiceObject::SendResults(sf::Out out_err, sf::Out out_size, u32 task_id) { - AMS_ABORT("SocketServiceObject::SendResults"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Get the send results. */ + manager->SendResults(out_err.GetPointer(), out_size.GetPointer(), task_id, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::StartSend(sf::Out out_task_id, sf::OutCopyHandle out_event, sf::Out out_max_size, s64 size, s32 flags) { - AMS_ABORT("SocketServiceObject::StartSend"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Start the send. */ + R_TRY(manager->StartSend(out_task_id.GetPointer(), out_event.GetHandlePointer(), m_desc, size, flags)); + + /* Set the output max size to the size. */ + *out_max_size = size; + return ResultSuccess(); } Result SocketServiceObject::ContinueSendOld(sf::Out out_size, sf::Out out_wait, const sf::InAutoSelectBuffer &buffer, u32 task_id) { - AMS_ABORT("SocketServiceObject::ContinueSendOld"); + return this->ContinueSend(out_size, out_wait, sf::InNonSecureAutoSelectBuffer(buffer.GetPointer(), buffer.GetSize()), task_id); } Result SocketServiceObject::EndSend(sf::Out out_err, sf::Out out_size, u32 task_id) { - AMS_ABORT("SocketServiceObject::EndSend"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* End the send. */ + manager->EndSend(out_err.GetPointer(), out_size.GetPointer(), task_id, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::StartRecv(sf::Out out_task_id, sf::OutCopyHandle out_event, s64 size, s32 flags) { - AMS_ABORT("SocketServiceObject::StartRecv"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Start the recv. */ + return manager->StartRecv(out_task_id.GetPointer(), out_event.GetHandlePointer(), size, m_desc, flags); } Result SocketServiceObject::EndRecv(sf::Out out_err, sf::Out out_size, const sf::OutAutoSelectBuffer &buffer, u32 task_id) { - AMS_ABORT("SocketServiceObject::EndRecv"); + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* End the recv. */ + manager->EndRecv(out_err.GetPointer(), out_size.GetPointer(), reinterpret_cast(buffer.GetPointer()), buffer.GetSize(), task_id, m_desc); + + return ResultSuccess(); } Result SocketServiceObject::SendStart(sf::Out out_task_id, sf::OutCopyHandle out_event, const sf::InNonSecureAutoSelectBuffer &buffer, s32 flags) { - AMS_ABORT("SocketServiceObject::SendStart"); + /* Check that the sizes are okay. */ + R_UNLESS(util::IsIntValueRepresentable(buffer.GetSize()), htcs::ResultInvalidSize()); + + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Start the send. */ + return manager->SendStart(out_task_id.GetPointer(), out_event.GetHandlePointer(), reinterpret_cast(buffer.GetPointer()), buffer.GetSize(), m_desc, flags); } Result SocketServiceObject::ContinueSend(sf::Out out_size, sf::Out out_wait, const sf::InNonSecureAutoSelectBuffer &buffer, u32 task_id) { - AMS_ABORT("SocketServiceObject::ContinueSend"); + /* Check that the sizes are okay. */ + R_UNLESS(util::IsIntValueRepresentable(buffer.GetSize()), htcs::ResultInvalidSize()); + + /* Get the htcs manager. */ + auto *manager = impl::HtcsManagerHolder::GetHtcsManager(); + + /* Continue the send. */ + R_TRY(manager->ContinueSend(out_size.GetPointer(), reinterpret_cast(buffer.GetPointer()), buffer.GetSize(), task_id, m_desc)); + + /* We aren't doing a waiting send. */ + *out_wait = false; + return ResultSuccess(); } Result SocketServiceObject::GetPrimitive(sf::Out out) { - AMS_ABORT("SocketServiceObject::GetPrimitive"); + /* Get our descriptor. */ + *out = m_desc; + return ResultSuccess(); } } diff --git a/libraries/libstratosphere/source/htcs/server/htcs_socket_service_object_deprecated.cpp b/libraries/libstratosphere/source/htcs/server/htcs_socket_service_object_deprecated.cpp new file mode 100644 index 000000000..f4b2dd438 --- /dev/null +++ b/libraries/libstratosphere/source/htcs/server/htcs_socket_service_object_deprecated.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "htcs_manager_service_object.hpp" +#include "htcs_socket_service_object.hpp" + +namespace ams::htcs::server { + + #define AMS_HTCS_MANAGER_DEPRECATED_API() AMS_ABORT("Deprecated IHtcsManager API %s was called.\n", AMS_CURRENT_FUNCTION_NAME) + + Result SocketServiceObject::Accept(sf::Out out_err, sf::Out> out, sf::Out out_address) { + /* NOTE: This is a deprecated API, and Nintendo aborts when it is called. */ + AMS_HTCS_MANAGER_DEPRECATED_API(); + } + +} diff --git a/libraries/libvapours/include/vapours/results.hpp b/libraries/libvapours/include/vapours/results.hpp index 003bacf25..29bfbc250 100644 --- a/libraries/libvapours/include/vapours/results.hpp +++ b/libraries/libvapours/include/vapours/results.hpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libvapours/include/vapours/results/htcs_results.hpp b/libraries/libvapours/include/vapours/results/htcs_results.hpp new file mode 100644 index 000000000..68c9e7f60 --- /dev/null +++ b/libraries/libvapours/include/vapours/results/htcs_results.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::htcs { + + R_DEFINE_NAMESPACE_RESULT_MODULE(4); + + R_DEFINE_ERROR_RESULT(InvalidSize, 2014); + +}