summaryrefslogtreecommitdiffstats
path: root/src/core/hle/ipc_helpers.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/ipc_helpers.h74
1 files changed, 47 insertions, 27 deletions
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index 0906b8cfb..5fed3dbf5 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -15,6 +15,8 @@
#include "core/hle/ipc.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_client_port.h"
+#include "core/hle/kernel/k_process.h"
+#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_session.h"
#include "core/hle/result.h"
@@ -26,7 +28,7 @@ class RequestHelperBase {
protected:
Kernel::HLERequestContext* context = nullptr;
u32* cmdbuf;
- ptrdiff_t index = 0;
+ u32 index = 0;
public:
explicit RequestHelperBase(u32* command_buffer) : cmdbuf(command_buffer) {}
@@ -38,7 +40,7 @@ public:
if (set_to_null) {
memset(cmdbuf + index, 0, size_in_words * sizeof(u32));
}
- index += static_cast<ptrdiff_t>(size_in_words);
+ index += size_in_words;
}
/**
@@ -51,11 +53,11 @@ public:
}
u32 GetCurrentOffset() const {
- return static_cast<u32>(index);
+ return index;
}
void SetCurrentOffset(u32 offset) {
- index = static_cast<ptrdiff_t>(offset);
+ index = offset;
}
};
@@ -69,37 +71,44 @@ public:
AlwaysMoveHandles = 1,
};
- explicit ResponseBuilder(Kernel::HLERequestContext& context, u32 normal_params_size,
+ explicit ResponseBuilder(Kernel::HLERequestContext& ctx, u32 normal_params_size,
u32 num_handles_to_copy = 0, u32 num_objects_to_move = 0,
Flags flags = Flags::None)
- : RequestHelperBase(context), normal_params_size(normal_params_size),
+ : RequestHelperBase(ctx), normal_params_size(normal_params_size),
num_handles_to_copy(num_handles_to_copy),
- num_objects_to_move(num_objects_to_move), kernel{context.kernel} {
+ num_objects_to_move(num_objects_to_move), kernel{ctx.kernel} {
memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);
- context.ClearIncomingObjects();
+ ctx.ClearIncomingObjects();
IPC::CommandHeader header{};
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
// padding.
- u64 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
+ u32 raw_data_size = ctx.IsTipc()
+ ? normal_params_size - 1
+ : sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
u32 num_handles_to_move{};
u32 num_domain_objects{};
const bool always_move_handles{
(static_cast<u32>(flags) & static_cast<u32>(Flags::AlwaysMoveHandles)) != 0};
- if (!context.Session()->IsDomain() || always_move_handles) {
+ if (!ctx.Session()->IsDomain() || always_move_handles) {
num_handles_to_move = num_objects_to_move;
} else {
num_domain_objects = num_objects_to_move;
}
- if (context.Session()->IsDomain()) {
- raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects;
+ if (ctx.Session()->IsDomain()) {
+ raw_data_size += static_cast<u32>(sizeof(DomainMessageHeader) / 4 + num_domain_objects);
}
+ if (ctx.IsTipc()) {
+ header.type.Assign(ctx.GetCommandType());
+ }
+
+ ctx.data_size = static_cast<u32>(raw_data_size);
header.data_size.Assign(static_cast<u32>(raw_data_size));
if (num_handles_to_copy || num_handles_to_move) {
header.enable_handle_descriptor.Assign(1);
@@ -111,22 +120,30 @@ public:
handle_descriptor_header.num_handles_to_copy.Assign(num_handles_to_copy);
handle_descriptor_header.num_handles_to_move.Assign(num_handles_to_move);
PushRaw(handle_descriptor_header);
+
+ ctx.handles_offset = index;
+
Skip(num_handles_to_copy + num_handles_to_move, true);
}
- AlignWithPadding();
+ if (!ctx.IsTipc()) {
+ AlignWithPadding();
- if (context.Session()->IsDomain() && context.HasDomainMessageHeader()) {
- IPC::DomainMessageHeader domain_header{};
- domain_header.num_objects = num_domain_objects;
- PushRaw(domain_header);
+ if (ctx.Session()->IsDomain() && ctx.HasDomainMessageHeader()) {
+ IPC::DomainMessageHeader domain_header{};
+ domain_header.num_objects = num_domain_objects;
+ PushRaw(domain_header);
+ }
+
+ IPC::DataPayloadHeader data_payload_header{};
+ data_payload_header.magic = Common::MakeMagic('S', 'F', 'C', 'O');
+ PushRaw(data_payload_header);
}
- IPC::DataPayloadHeader data_payload_header{};
- data_payload_header.magic = Common::MakeMagic('S', 'F', 'C', 'O');
- PushRaw(data_payload_header);
+ data_payload_index = index;
- datapayload_index = index;
+ ctx.data_payload_offset = index;
+ ctx.domain_offset = index + raw_data_size / 4;
}
template <class T>
@@ -134,6 +151,9 @@ public:
if (context->Session()->IsDomain()) {
context->AddDomainObject(std::move(iface));
} else {
+ // kernel.CurrentProcess()->GetResourceLimit()->Reserve(
+ // Kernel::LimitableResource::Sessions, 1);
+
auto* session = Kernel::KSession::Create(kernel);
session->Initialize(nullptr, iface->GetServiceName());
@@ -152,7 +172,7 @@ public:
const std::size_t num_move_objects = context->NumMoveObjects();
ASSERT_MSG(!num_domain_objects || !num_move_objects,
"cannot move normal handles and domain objects");
- ASSERT_MSG((index - datapayload_index) == normal_params_size,
+ ASSERT_MSG((index - data_payload_index) == normal_params_size,
"normal_params_size value is incorrect");
ASSERT_MSG((num_domain_objects + num_move_objects) == num_objects_to_move,
"num_objects_to_move value is incorrect");
@@ -229,14 +249,14 @@ private:
u32 normal_params_size{};
u32 num_handles_to_copy{};
u32 num_objects_to_move{}; ///< Domain objects or move handles, context dependent
- std::ptrdiff_t datapayload_index{};
+ u32 data_payload_index{};
Kernel::KernelCore& kernel;
};
/// Push ///
inline void ResponseBuilder::PushImpl(s32 value) {
- cmdbuf[index++] = static_cast<u32>(value);
+ cmdbuf[index++] = value;
}
inline void ResponseBuilder::PushImpl(u32 value) {
@@ -341,9 +361,9 @@ class RequestParser : public RequestHelperBase {
public:
explicit RequestParser(u32* command_buffer) : RequestHelperBase(command_buffer) {}
- explicit RequestParser(Kernel::HLERequestContext& context) : RequestHelperBase(context) {
- ASSERT_MSG(context.GetDataPayloadOffset(), "context is incomplete");
- Skip(context.GetDataPayloadOffset(), false);
+ explicit RequestParser(Kernel::HLERequestContext& ctx) : RequestHelperBase(ctx) {
+ ASSERT_MSG(ctx.GetDataPayloadOffset(), "context is incomplete");
+ Skip(ctx.GetDataPayloadOffset(), false);
// Skip the u64 command id, it's already stored in the context
static constexpr u32 CommandIdSize = 2;
Skip(CommandIdSize, false);