mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-06-29 22:42:40 +02:00
spl: update for new-ipc (fixes two bugs in sf)
This commit is contained in:
parent
f1a77be02a
commit
25ed190f4e
@ -43,7 +43,7 @@ namespace sts::sf::cmif {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result PrepareForProcess(const ServiceDispatchContext &ctx, const size_t headers_size) const override final;
|
virtual Result PrepareForProcess(const ServiceDispatchContext &ctx, size_t &headers_size) const override final;
|
||||||
virtual Result GetInObjects(ServiceObjectHolder *in_objects) const override final;
|
virtual Result GetInObjects(ServiceObjectHolder *in_objects) const override final;
|
||||||
virtual HipcRequest PrepareForReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size, size_t &num_out_object_handles) override final;
|
virtual HipcRequest PrepareForReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size, size_t &num_out_object_handles) override final;
|
||||||
virtual void PrepareForErrorReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size) override final;
|
virtual void PrepareForErrorReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size) override final;
|
||||||
|
@ -30,7 +30,7 @@ namespace sts::sf::cmif {
|
|||||||
/* Used to enabled templated message processors. */
|
/* Used to enabled templated message processors. */
|
||||||
virtual void SetImplementationProcessor(ServerMessageProcessor *impl) { /* ... */ }
|
virtual void SetImplementationProcessor(ServerMessageProcessor *impl) { /* ... */ }
|
||||||
|
|
||||||
virtual Result PrepareForProcess(const ServiceDispatchContext &ctx, const size_t headers_size) const = 0;
|
virtual Result PrepareForProcess(const ServiceDispatchContext &ctx, size_t &headers_size) const = 0;
|
||||||
virtual Result GetInObjects(ServiceObjectHolder *in_objects) const = 0;
|
virtual Result GetInObjects(ServiceObjectHolder *in_objects) const = 0;
|
||||||
virtual HipcRequest PrepareForReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size, size_t &num_out_object_handles) = 0;
|
virtual HipcRequest PrepareForReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size, size_t &num_out_object_handles) = 0;
|
||||||
virtual void PrepareForErrorReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size) = 0;
|
virtual void PrepareForErrorReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const size_t headers_size) = 0;
|
||||||
|
@ -300,7 +300,7 @@ namespace sts::sf::impl {
|
|||||||
static constexpr void StableSort(std::array<size_t, sizeof...(Ts)> &map, const std::array<size_t, sizeof...(Ts)> &values) {
|
static constexpr void StableSort(std::array<size_t, sizeof...(Ts)> &map, const std::array<size_t, sizeof...(Ts)> &values) {
|
||||||
/* Use insertion sort, which is stable and optimal for small numbers of parameters. */
|
/* Use insertion sort, which is stable and optimal for small numbers of parameters. */
|
||||||
for (size_t i = 1; i < sizeof...(Ts); i++) {
|
for (size_t i = 1; i < sizeof...(Ts); i++) {
|
||||||
for (size_t j = i; j > 0 && values[j-1] > values[j]; j--) {
|
for (size_t j = i; j > 0 && values[map[j-1]] > values[map[j]]; j--) {
|
||||||
/* std::swap is not constexpr until c++20 :( */
|
/* std::swap is not constexpr until c++20 :( */
|
||||||
/* TODO: std::swap(map[j], map[j-1]); */
|
/* TODO: std::swap(map[j], map[j-1]); */
|
||||||
const size_t tmp = map[j];
|
const size_t tmp = map[j];
|
||||||
@ -686,7 +686,7 @@ namespace sts::sf::impl {
|
|||||||
template<typename CommandMeta>
|
template<typename CommandMeta>
|
||||||
struct HipcCommandProcessor : public sf::cmif::ServerMessageProcessor {
|
struct HipcCommandProcessor : public sf::cmif::ServerMessageProcessor {
|
||||||
public:
|
public:
|
||||||
virtual Result PrepareForProcess(const cmif::ServiceDispatchContext &ctx, const size_t headers_size) const override final {
|
virtual Result PrepareForProcess(const cmif::ServiceDispatchContext &ctx, size_t &headers_size) const override final {
|
||||||
const auto &meta = ctx.request.meta;
|
const auto &meta = ctx.request.meta;
|
||||||
bool is_request_valid = true;
|
bool is_request_valid = true;
|
||||||
is_request_valid &= meta.send_pid == CommandMeta::HasInProcessIdHolder;
|
is_request_valid &= meta.send_pid == CommandMeta::HasInProcessIdHolder;
|
||||||
@ -789,7 +789,7 @@ namespace sts::sf::impl {
|
|||||||
}();
|
}();
|
||||||
|
|
||||||
template<size_t BufferIndex, size_t Index = GetIndexFromBufferIndex<BufferIndex>>
|
template<size_t BufferIndex, size_t Index = GetIndexFromBufferIndex<BufferIndex>>
|
||||||
NX_CONSTEXPR void ProcessBufferImpl(const cmif::ServiceDispatchContext &ctx, cmif::PointerAndSize &buffer, bool &is_buffer_map_alias, bool &map_alias_buffers_valid, size_t &pointer_buffer_head, size_t &pointer_buffer_tail) {
|
NX_CONSTEXPR void ProcessBufferImpl(const cmif::ServiceDispatchContext &ctx, cmif::PointerAndSize &buffer, bool &is_buffer_map_alias, bool &map_alias_buffers_valid, size_t &pointer_buffer_head, size_t &pointer_buffer_tail, size_t in_headers_size) {
|
||||||
static_assert(Index != std::numeric_limits<size_t>::max(), "Invalid Index From Buffer Index");
|
static_assert(Index != std::numeric_limits<size_t>::max(), "Invalid Index From Buffer Index");
|
||||||
constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index];
|
constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index];
|
||||||
constexpr auto Attributes = CommandMeta::BufferAttributes[BufferIndex];
|
constexpr auto Attributes = CommandMeta::BufferAttributes[BufferIndex];
|
||||||
@ -824,7 +824,7 @@ namespace sts::sf::impl {
|
|||||||
pointer_buffer_head = util::AlignDown(pointer_buffer_head - size, 0x10);
|
pointer_buffer_head = util::AlignDown(pointer_buffer_head - size, 0x10);
|
||||||
buffer = cmif::PointerAndSize(pointer_buffer_head, size);
|
buffer = cmif::PointerAndSize(pointer_buffer_head, size);
|
||||||
} else {
|
} else {
|
||||||
const u16 *recv_pointer_sizes = reinterpret_cast<const u16 *>(reinterpret_cast<uintptr_t>(ctx.request.data.data_words) + CommandMeta::InDataRawUnfixedOutPointerSizeOffset);
|
const u16 *recv_pointer_sizes = reinterpret_cast<const u16 *>(reinterpret_cast<uintptr_t>(ctx.request.data.data_words) + in_headers_size + CommandMeta::InDataRawUnfixedOutPointerSizeOffset);
|
||||||
const size_t size = size_t(recv_pointer_sizes[Info.unfixed_recv_pointer_index]);
|
const size_t size = size_t(recv_pointer_sizes[Info.unfixed_recv_pointer_index]);
|
||||||
pointer_buffer_head = util::AlignDown(pointer_buffer_head - size, 0x10);
|
pointer_buffer_head = util::AlignDown(pointer_buffer_head - size, 0x10);
|
||||||
buffer = cmif::PointerAndSize(pointer_buffer_head, size);
|
buffer = cmif::PointerAndSize(pointer_buffer_head, size);
|
||||||
@ -894,11 +894,11 @@ namespace sts::sf::impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
NX_CONSTEXPR Result ProcessBuffers(const cmif::ServiceDispatchContext &ctx, BufferArrayType &buffers, std::array<bool, CommandMeta::NumBuffers> &is_buffer_map_alias) {
|
NX_CONSTEXPR Result ProcessBuffers(const cmif::ServiceDispatchContext &ctx, BufferArrayType &buffers, std::array<bool, CommandMeta::NumBuffers> &is_buffer_map_alias, size_t in_headers_size) {
|
||||||
bool map_alias_buffers_valid = true;
|
bool map_alias_buffers_valid = true;
|
||||||
size_t pointer_buffer_tail = ctx.pointer_buffer.GetAddress();
|
size_t pointer_buffer_tail = ctx.pointer_buffer.GetAddress();
|
||||||
size_t pointer_buffer_head = pointer_buffer_tail + ctx.pointer_buffer.GetSize();
|
size_t pointer_buffer_head = pointer_buffer_tail + ctx.pointer_buffer.GetSize();
|
||||||
#define _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(n) do { if constexpr (CommandMeta::NumBuffers > n) { ProcessBufferImpl<n>(ctx, buffers[n], is_buffer_map_alias[n], map_alias_buffers_valid, pointer_buffer_head, pointer_buffer_tail); } } while (0)
|
#define _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(n) do { if constexpr (CommandMeta::NumBuffers > n) { ProcessBufferImpl<n>(ctx, buffers[n], is_buffer_map_alias[n], map_alias_buffers_valid, pointer_buffer_head, pointer_buffer_tail, in_headers_size); } } while (0)
|
||||||
_SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(0);
|
_SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(0);
|
||||||
_SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(1);
|
_SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(1);
|
||||||
_SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(2);
|
_SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(2);
|
||||||
@ -1010,7 +1010,7 @@ namespace sts::sf::impl {
|
|||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto ServiceCommandImpl, typename ClassType = typename CommandMetaInfo<ServiceCommandImpl>::ClassType>
|
template<auto ServiceCommandImpl>
|
||||||
constexpr Result InvokeServiceCommandImpl(CmifOutHeader **out_header_ptr, cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) {
|
constexpr Result InvokeServiceCommandImpl(CmifOutHeader **out_header_ptr, cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) {
|
||||||
using CommandMeta = CommandMetaInfo<ServiceCommandImpl>;
|
using CommandMeta = CommandMetaInfo<ServiceCommandImpl>;
|
||||||
using ImplProcessorType = HipcCommandProcessor<CommandMeta>;
|
using ImplProcessorType = HipcCommandProcessor<CommandMeta>;
|
||||||
@ -1018,7 +1018,7 @@ namespace sts::sf::impl {
|
|||||||
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
|
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
|
||||||
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
|
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
|
||||||
using InOutObjectHolderType = InOutObjectHolder<CommandMeta::NumInObjects, CommandMeta::NumOutObjects>;
|
using InOutObjectHolderType = InOutObjectHolder<CommandMeta::NumInObjects, CommandMeta::NumOutObjects>;
|
||||||
static_assert(std::is_base_of<typename CommandMeta::ClassType, ClassType>::value, "InvokeServiceCommandImpl: Invalid Override ClassType");
|
using ClassType = typename CommandMeta::ClassType;
|
||||||
static_assert(std::is_base_of<sf::IServiceObject, ClassType>::value, "InvokeServiceCommandImpl: Service Commands must be ServiceObject member functions");
|
static_assert(std::is_base_of<sf::IServiceObject, ClassType>::value, "InvokeServiceCommandImpl: Service Commands must be ServiceObject member functions");
|
||||||
|
|
||||||
/* Create a processor for us to work with. */
|
/* Create a processor for us to work with. */
|
||||||
@ -1032,7 +1032,8 @@ namespace sts::sf::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Validate the metadata has the expected counts. */
|
/* Validate the metadata has the expected counts. */
|
||||||
R_TRY(ctx.processor->PrepareForProcess(ctx, sizeof(CmifInHeader)));
|
size_t in_headers_size = sizeof(CmifInHeader);
|
||||||
|
R_TRY(ctx.processor->PrepareForProcess(ctx, in_headers_size));
|
||||||
|
|
||||||
/* Storage for output. */
|
/* Storage for output. */
|
||||||
BufferArrayType buffers;
|
BufferArrayType buffers;
|
||||||
@ -1042,7 +1043,7 @@ namespace sts::sf::impl {
|
|||||||
InOutObjectHolderType in_out_objects_holder;
|
InOutObjectHolderType in_out_objects_holder;
|
||||||
|
|
||||||
/* Process buffers. */
|
/* Process buffers. */
|
||||||
R_TRY(ImplProcessorType::ProcessBuffers(ctx, buffers, is_buffer_map_alias));
|
R_TRY(ImplProcessorType::ProcessBuffers(ctx, buffers, is_buffer_map_alias, in_headers_size));
|
||||||
|
|
||||||
/* Process input/output objects. */
|
/* Process input/output objects. */
|
||||||
R_TRY(in_out_objects_holder.GetInObjects(ctx.processor));
|
R_TRY(in_out_objects_holder.GetInObjects(ctx.processor));
|
||||||
@ -1095,16 +1096,16 @@ namespace sts::sf::impl {
|
|||||||
|
|
||||||
namespace sts::sf {
|
namespace sts::sf {
|
||||||
|
|
||||||
template <auto CommandId, auto CommandImpl, typename OverrideClassType, hos::Version Low = hos::Version_Min, hos::Version High = hos::Version_Max>
|
template <auto CommandId, auto CommandImpl, hos::Version Low = hos::Version_Min, hos::Version High = hos::Version_Max>
|
||||||
inline static constexpr cmif::ServiceCommandMeta MakeServiceCommandMeta() {
|
inline static constexpr cmif::ServiceCommandMeta MakeServiceCommandMeta() {
|
||||||
return {
|
return {
|
||||||
.hosver_low = Low,
|
.hosver_low = Low,
|
||||||
.hosver_high = High,
|
.hosver_high = High,
|
||||||
.cmd_id = static_cast<u32>(CommandId),
|
.cmd_id = static_cast<u32>(CommandId),
|
||||||
.handler = ::sts::sf::impl::InvokeServiceCommandImpl<CommandImpl, OverrideClassType>,
|
.handler = ::sts::sf::impl::InvokeServiceCommandImpl<CommandImpl>,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKE_SERVICE_COMMAND_META(Name, ...) ::sts::sf::MakeServiceCommandMeta<ServiceImpl::CommandId::Name, &ServiceImpl::Name, ServiceImpl, ##__VA_ARGS__>()
|
#define MAKE_SERVICE_COMMAND_META(Name, ...) ::sts::sf::MakeServiceCommandMeta<ServiceImpl::CommandId::Name, &ServiceImpl::Name, ##__VA_ARGS__>()
|
||||||
|
Loading…
Reference in New Issue
Block a user