2021-02-09 13:37:54 +00:00
|
|
|
/*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
#include <stratosphere.hpp>
|
|
|
|
#include "htc_htc_service_object.hpp"
|
2021-02-23 23:47:28 +00:00
|
|
|
#include "../../htcfs/htcfs_working_directory.hpp"
|
2021-02-09 13:37:54 +00:00
|
|
|
|
|
|
|
namespace ams::htc::server {
|
|
|
|
|
2021-02-09 14:16:43 +00:00
|
|
|
HtcServiceObject::HtcServiceObject(htclow::HtclowManager *htclow_manager) : m_set(), m_misc_impl(htclow_manager), m_observer(m_misc_impl), m_mutex(){
|
|
|
|
/* Initialize our set. */
|
|
|
|
m_set.Initialize(MaxSetElements, m_set_memory, sizeof(m_set_memory));
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HtcmiscImpl *HtcServiceObject::GetHtcmiscImpl() {
|
2021-02-09 14:16:43 +00:00
|
|
|
return std::addressof(m_misc_impl);
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::GetEnvironmentVariable(sf::Out<s32> out_size, const sf::OutBuffer &out, const sf::InBuffer &name) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* Get the variable. */
|
|
|
|
size_t var_size;
|
|
|
|
R_TRY(m_misc_impl.GetEnvironmentVariable(std::addressof(var_size), reinterpret_cast<char *>(out.GetPointer()), out.GetSize(), reinterpret_cast<const char *>(name.GetPointer()), name.GetSize()));
|
|
|
|
|
|
|
|
/* Check the output size. */
|
|
|
|
R_UNLESS(util::IsIntValueRepresentable<s32>(var_size), htc::ResultUnknown());
|
|
|
|
|
|
|
|
/* Set the output size. */
|
|
|
|
*out_size = static_cast<s32>(var_size);
|
|
|
|
return ResultSuccess();
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::GetEnvironmentVariableLength(sf::Out<s32> out_size, const sf::InBuffer &name) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* Get the variable. */
|
|
|
|
size_t var_size;
|
|
|
|
R_TRY(m_misc_impl.GetEnvironmentVariableLength(std::addressof(var_size), reinterpret_cast<const char *>(name.GetPointer()), name.GetSize()));
|
|
|
|
|
|
|
|
/* Check the output size. */
|
|
|
|
R_UNLESS(util::IsIntValueRepresentable<s32>(var_size), htc::ResultUnknown());
|
|
|
|
|
|
|
|
/* Set the output size. */
|
|
|
|
*out_size = static_cast<s32>(var_size);
|
|
|
|
return ResultSuccess();
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::GetHostConnectionEvent(sf::OutCopyHandle out) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* Set the output handle. */
|
|
|
|
*out = m_observer.GetConnectEvent()->GetReadableHandle();
|
|
|
|
return ResultSuccess();
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::GetHostDisconnectionEvent(sf::OutCopyHandle out) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* Set the output handle. */
|
|
|
|
*out = m_observer.GetDisconnectEvent()->GetReadableHandle();
|
|
|
|
return ResultSuccess();
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::GetHostConnectionEventForSystem(sf::OutCopyHandle out) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* NOTE: Nintendo presumably reserved this command in case they need it, but they haven't implemented it yet. */
|
|
|
|
AMS_ABORT("HostEventForSystem not implemented.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::GetHostDisconnectionEventForSystem(sf::OutCopyHandle out) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* NOTE: Nintendo presumably reserved this command in case they need it, but they haven't implemented it yet. */
|
|
|
|
AMS_ABORT("HostEventForSystem not implemented.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::GetWorkingDirectoryPath(const sf::OutBuffer &out, s32 max_len) {
|
|
|
|
return htcfs::GetWorkingDirectory(reinterpret_cast<char *>(out.GetPointer()), max_len);
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::GetWorkingDirectoryPathSize(sf::Out<s32> out_size) {
|
|
|
|
return htcfs::GetWorkingDirectorySize(out_size.GetPointer());
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::RunOnHostStart(sf::Out<u32> out_id, sf::OutCopyHandle out, const sf::InBuffer &args) {
|
|
|
|
/* Begin the run on host task. */
|
|
|
|
R_TRY(m_misc_impl.RunOnHostBegin(out_id.GetPointer(), out.GetHandlePointer(), reinterpret_cast<const char *>(args.GetPointer()), args.GetSize()));
|
|
|
|
|
|
|
|
/* Add the task id to our set. */
|
|
|
|
{
|
|
|
|
std::scoped_lock lk(m_mutex);
|
|
|
|
m_set.insert(*out_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Mark the output event as managed. */
|
|
|
|
out.SetManaged(true);
|
|
|
|
return ResultSuccess();
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::RunOnHostResults(sf::Out<s32> out_result, u32 id) {
|
|
|
|
/* Verify that we have the task. */
|
|
|
|
{
|
|
|
|
std::scoped_lock lk(m_mutex);
|
|
|
|
R_UNLESS(m_set.erase(id), htc::ResultInvalidTaskId());
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Finish the run on host task. */
|
|
|
|
return m_misc_impl.RunOnHostEnd(out_result.GetPointer(), id);
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::GetBridgeIpAddress(const sf::OutBuffer &out) {
|
|
|
|
/* NOTE: Atmosphere does not support HostBridge, and it's unclear if we ever will. */
|
|
|
|
AMS_ABORT("HostBridge currently not supported.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::GetBridgePort(const sf::OutBuffer &out) {
|
|
|
|
/* NOTE: Atmosphere does not support HostBridge, and it's unclear if we ever will. */
|
|
|
|
AMS_ABORT("HostBridge currently not supported.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::SetCradleAttached(bool attached) {
|
|
|
|
/* NOTE: Atmosphere does not support HostBridge, and it's unclear if we ever will. */
|
|
|
|
AMS_ABORT("HostBridge currently not supported.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::GetBridgeSubnetMask(const sf::OutBuffer &out) {
|
|
|
|
/* NOTE: Atmosphere does not support HostBridge, and it's unclear if we ever will. */
|
|
|
|
AMS_ABORT("HostBridge currently not supported.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 23:47:28 +00:00
|
|
|
Result HtcServiceObject::GetBridgeMacAddress(const sf::OutBuffer &out) {
|
|
|
|
/* NOTE: Atmosphere does not support HostBridge, and it's unclear if we ever will. */
|
|
|
|
AMS_ABORT("HostBridge currently not supported.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::SetBridgeIpAddress(const sf::InBuffer &arg) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* NOTE: Atmosphere does not support HostBridge, and it's unclear if we ever will. */
|
|
|
|
AMS_ABORT("HostBridge currently not supported.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::SetBridgeSubnetMask(const sf::InBuffer &arg) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* NOTE: Atmosphere does not support HostBridge, and it's unclear if we ever will. */
|
|
|
|
AMS_ABORT("HostBridge currently not supported.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result HtcServiceObject::SetBridgePort(const sf::InBuffer &arg) {
|
2021-02-23 23:47:28 +00:00
|
|
|
/* NOTE: Atmosphere does not support HostBridge, and it's unclear if we ever will. */
|
|
|
|
AMS_ABORT("HostBridge currently not supported.");
|
2021-02-09 13:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|