htc: implement htcmisc service object commands

This commit is contained in:
Michael Scire
2021-02-23 15:47:28 -08:00
committed by SciresM
parent 8b32b9eadf
commit b5ab491603
13 changed files with 302 additions and 41 deletions

View File

@@ -60,6 +60,9 @@ namespace ams::htcfs {
Result FlushFile(s32 handle) { return ConvertToFsResult(m_impl.FlushFile(handle)); }
Result GetPriorityForFile(s32 *out, s32 handle) { return ConvertToFsResult(m_impl.GetPriorityForFile(out, handle)); }
Result SetPriorityForFile(s32 priority, s32 handle) { return ConvertToFsResult(m_impl.SetPriorityForFile(priority, handle)); }
Result GetWorkingDirectory(char *dst, size_t dst_size) { return ConvertToFsResult(m_impl.GetWorkingDirectory(dst, dst_size)); }
Result GetWorkingDirectorySize(s32 *out) { return ConvertToFsResult(m_impl.GetWorkingDirectorySize(out)); }
};
void InitializeClient(htclow::HtclowManager *manager);

View File

@@ -1539,5 +1539,83 @@ namespace ams::htcfs {
return ResultSuccess();
}
Result ClientImpl::GetWorkingDirectory(char *dst, size_t dst_size) {
/* Lock ourselves. */
std::scoped_lock lk(m_mutex);
/* Initialize our rpc channel. */
R_TRY(this->InitializeRpcChannel());
/* Create space for request and response. */
Header request, response;
/* Create header for the request. */
m_header_factory.MakeGetWorkingDirectoryHeader(std::addressof(request));
/* Send the request to the host. */
R_TRY(this->SendRequest(request));
/* Receive response from the host. */
R_TRY(this->ReceiveFromRpcChannel(std::addressof(response), sizeof(response)));
/* Check the response header. */
R_TRY(this->CheckResponseHeader(response, request.packet_type));
/* Check that we succeeded. */
const auto htcfs_result = ConvertHtcfsResult(response.params[0]);
if (R_FAILED(htcfs_result)) {
R_UNLESS(response.body_size == 0, htcfs::ResultUnexpectedResponseBodySize());
return htcfs_result;
}
/* Check that the body size is valid. */
R_UNLESS(response.body_size < static_cast<s64>(dst_size), htcfs::ResultUnexpectedResponseBodySize());
/* Receive the response body. */
R_TRY(this->ReceiveFromRpcChannel(dst, response.body_size));
/* Null-terminate the response body. */
dst[response.body_size] = '\x00';
return ResultSuccess();
}
Result ClientImpl::GetWorkingDirectorySize(s32 *out) {
/* Lock ourselves. */
std::scoped_lock lk(m_mutex);
/* Initialize our rpc channel. */
R_TRY(this->InitializeRpcChannel());
/* Create space for request and response. */
Header request, response;
/* Create header for the request. */
m_header_factory.MakeGetWorkingDirectorySizeHeader(std::addressof(request));
/* Send the request to the host. */
R_TRY(this->SendRequest(request));
/* Receive response from the host. */
R_TRY(this->ReceiveFromRpcChannel(std::addressof(response), sizeof(response)));
/* Check the response header. */
R_TRY(this->CheckResponseHeader(response, request.packet_type));
/* Check that we succeeded. */
const auto htcfs_result = ConvertHtcfsResult(response.params[0]);
if (R_FAILED(htcfs_result)) {
R_UNLESS(response.body_size == 0, htcfs::ResultUnexpectedResponseBodySize());
return htcfs_result;
}
/* Check that the size is representable. */
R_UNLESS(util::IsIntValueRepresentable<s32>(response.params[1]), htcfs::ResultInvalidSize());
/* Set the output size. */
*out = static_cast<s32>(response.params[1]);
return ResultSuccess();
}
}

View File

@@ -90,6 +90,9 @@ namespace ams::htcfs {
Result FlushFile(s32 handle);
Result GetPriorityForFile(s32 *out, s32 handle);
Result SetPriorityForFile(s32 priority, s32 handle);
Result GetWorkingDirectory(char *dst, size_t dst_size);
Result GetWorkingDirectorySize(s32 *out);
private:
int WaitAny(htclow::ChannelState state, os::EventType *event);

View File

@@ -179,6 +179,14 @@ namespace ams::htcfs {
return this->MakeRequestHeader(out, PacketType::GetEntryCount, 0, handle);
}
void MakeGetWorkingDirectoryHeader(Header *out) {
return this->MakeRequestHeader(out, PacketType::GetWorkingDirectory, 0);
}
void MakeGetWorkingDirectorySizeHeader(Header *out) {
return this->MakeRequestHeader(out, PacketType::GetWorkingDirectorySize, 0);
}
void MakeReadDirectoryHeader(Header *out, s32 handle, size_t max_out_entries) {
return this->MakeRequestHeader(out, PacketType::ReadDirectory, 0, handle, max_out_entries);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "htcfs_client.hpp"
namespace ams::htcfs {
Result GetWorkingDirectory(char *dst, size_t dst_size) {
return htcfs::GetClient().GetWorkingDirectory(dst, dst_size);
}
Result GetWorkingDirectorySize(s32 *out) {
return htcfs::GetClient().GetWorkingDirectorySize(out);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
namespace ams::htcfs {
Result GetWorkingDirectory(char *dst, size_t dst_size);
Result GetWorkingDirectorySize(s32 *out);
}