/* * Copyright (c) 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 #include "htc_rpc_tasks.hpp" namespace ams::htc::server::rpc { enum class HtcmiscTaskType { GetEnvironmentVariable = 0, GetEnvironmentVariableLength = 1, SetTargetStatus = 2, RunOnHost = 3, }; enum class HtcmiscResult { Success = 0, UnknownError = 1, UnsupportedVersion = 2, InvalidRequest = 3, }; enum class HtcmiscPacketCategory : s16 { Request = 0, Response = 1, }; enum class HtcmiscPacketType : s16 { GetMaxProtocolVersion = 0, SetProtocolVersion = 1, GetEnvironmentVariable = 16, GetEnvironmentVariableLength = 17, SetTargetStatus = 18, RunOnHost = 19, GetWorkingDirectory = 20, GetWorkingDirectorySize = 21, SetTargetName = 22, }; constexpr inline s16 HtcmiscProtocol = 4; constexpr inline s16 HtcmiscMaxVersion = 2; struct HtcmiscRpcPacket { s16 protocol; s16 version; HtcmiscPacketCategory category; HtcmiscPacketType type; s64 body_size; u32 task_id{}; u64 params[5]; char data[]; }; static_assert(sizeof(HtcmiscRpcPacket) == 0x40); class HtcmiscTask : public Task { private: HtcmiscTaskType m_task_type; public: HtcmiscTask(HtcmiscTaskType type) : m_task_type(type) { /* ... */ } HtcmiscTaskType GetTaskType() const { return m_task_type; } }; class GetEnvironmentVariableTask : public HtcmiscTask { public: static constexpr inline HtcmiscTaskType TaskType = HtcmiscTaskType::GetEnvironmentVariable; private: char m_name[0x800]; int m_name_size; Result m_result; size_t m_value_size; char m_value[0x8000]; public: GetEnvironmentVariableTask() : HtcmiscTask(HtcmiscTaskType::GetEnvironmentVariable) { /* ... */ } Result SetArguments(const char *args, size_t size); void Complete(HtcmiscResult result, const char *data, size_t size); Result GetResult(size_t *out, char *dst, size_t size) const; const char *GetName() const { return m_name; } int GetNameSize() const { return m_name_size; } public: virtual Result ProcessResponse(const char *data, size_t size) override; virtual Result CreateRequest(size_t *out, char *data, size_t size, u32 task_id) override; }; class GetEnvironmentVariableLengthTask : public HtcmiscTask { public: static constexpr inline HtcmiscTaskType TaskType = HtcmiscTaskType::GetEnvironmentVariableLength; private: char m_name[0x800]; int m_name_size; Result m_result; size_t m_value_size; public: GetEnvironmentVariableLengthTask() : HtcmiscTask(HtcmiscTaskType::GetEnvironmentVariableLength) { /* ... */ } Result SetArguments(const char *args, size_t size); void Complete(HtcmiscResult result, const char *data, size_t size); Result GetResult(size_t *out) const; const char *GetName() const { return m_name; } int GetNameSize() const { return m_name_size; } public: virtual Result ProcessResponse(const char *data, size_t size) override; virtual Result CreateRequest(size_t *out, char *data, size_t size, u32 task_id) override; }; class RunOnHostTask : public HtcmiscTask { public: static constexpr inline HtcmiscTaskType TaskType = HtcmiscTaskType::RunOnHost; private: char m_command[0x2000]; int m_command_size; Result m_result; int m_host_result; os::SystemEvent m_system_event; public: RunOnHostTask() : HtcmiscTask(HtcmiscTaskType::RunOnHost), m_system_event(os::EventClearMode_ManualClear, true) { /* ... */ } Result SetArguments(const char *args, size_t size); void Complete(int host_result); Result GetResult(int *out) const; const char *GetCommand() const { return m_command; } int GetCommandSize() const { return m_command_size; } public: virtual void Cancel(RpcTaskCancelReason reason) override; virtual Result ProcessResponse(const char *data, size_t size) override; virtual Result CreateRequest(size_t *out, char *data, size_t size, u32 task_id) override; virtual os::SystemEventType *GetSystemEvent() override; }; }