IPC: Push domain objects as move handles when not in a domain.
This commit is contained in:
parent
1aa4cdc3c8
commit
5bc14e791a
|
@ -9,10 +9,13 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "core/hle/ipc.h"
|
#include "core/hle/ipc.h"
|
||||||
|
#include "core/hle/kernel/client_port.h"
|
||||||
|
#include "core/hle/kernel/client_session.h"
|
||||||
#include "core/hle/kernel/domain.h"
|
#include "core/hle/kernel/domain.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/hle_ipc.h"
|
#include "core/hle/kernel/hle_ipc.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
|
#include "core/hle/kernel/server_port.h"
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
|
@ -63,13 +66,20 @@ public:
|
||||||
: RequestHelperBase(context) {
|
: RequestHelperBase(context) {
|
||||||
memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);
|
memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);
|
||||||
|
|
||||||
|
context.ClearIncomingObjects();
|
||||||
|
|
||||||
IPC::CommandHeader header{};
|
IPC::CommandHeader header{};
|
||||||
|
|
||||||
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
|
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
|
||||||
// padding.
|
// padding.
|
||||||
u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
|
u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
|
||||||
if (context.IsDomain())
|
if (context.IsDomain()) {
|
||||||
raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects;
|
raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects;
|
||||||
|
} else {
|
||||||
|
// If we're not in a domain, turn the domain object parameters into move handles.
|
||||||
|
num_handles_to_move += num_domain_objects;
|
||||||
|
num_domain_objects = 0;
|
||||||
|
}
|
||||||
|
|
||||||
header.data_size.Assign(raw_data_size);
|
header.data_size.Assign(raw_data_size);
|
||||||
if (num_handles_to_copy || num_handles_to_move) {
|
if (num_handles_to_copy || num_handles_to_move) {
|
||||||
|
@ -100,7 +110,15 @@ public:
|
||||||
|
|
||||||
template <class T, class... Args>
|
template <class T, class... Args>
|
||||||
void PushIpcInterface(Args&&... args) {
|
void PushIpcInterface(Args&&... args) {
|
||||||
context->AddDomainObject(std::make_shared<T>(std::forward<Args>(args)...));
|
auto iface = std::make_shared<T>(std::forward<Args>(args)...);
|
||||||
|
if (context->IsDomain()) {
|
||||||
|
context->AddDomainObject(std::move(iface));
|
||||||
|
} else {
|
||||||
|
auto port = iface->CreatePort();
|
||||||
|
auto session = port->Connect();
|
||||||
|
ASSERT(session.Succeeded());
|
||||||
|
context->AddMoveObject(std::move(session).Unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate on destruction, as there shouldn't be any case where we don't want it
|
// Validate on destruction, as there shouldn't be any case where we don't want it
|
||||||
|
|
|
@ -175,6 +175,14 @@ public:
|
||||||
domain_objects.emplace_back(std::move(object));
|
domain_objects.emplace_back(std::move(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clears the list of objects so that no lingering objects are written accidentally to the
|
||||||
|
/// response buffer.
|
||||||
|
void ClearIncomingObjects() {
|
||||||
|
move_objects.clear();
|
||||||
|
copy_objects.clear();
|
||||||
|
domain_objects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
||||||
SharedPtr<Kernel::Domain> domain;
|
SharedPtr<Kernel::Domain> domain;
|
||||||
|
|
Loading…
Reference in a new issue