From 1572c45aa05febd01b3765706d701e935a5c60f3 Mon Sep 17 00:00:00 2001 From: mailwl Date: Tue, 20 Feb 2018 19:27:49 +0300 Subject: [PATCH 1/3] IPC: add domain header to response if only it exists in request --- src/core/hle/ipc_helpers.h | 2 +- src/core/hle/kernel/hle_ipc.cpp | 10 ++++++---- src/core/hle/kernel/server_session.cpp | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 6066d8a182..97290fec55 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -118,7 +118,7 @@ public: AlignWithPadding(); - if (context.Session()->IsDomain()) { + if (context.Session()->IsDomain() && context.GetDomainMessageHeader()) { IPC::DomainMessageHeader domain_header{}; domain_header.num_objects = num_domain_objects; PushRaw(domain_header); diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 25ba26f189..3b1f3154de 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -85,9 +85,11 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { if (Session()->IsDomain() && (command_header->type == IPC::CommandType::Request || !incoming)) { // If this is an incoming message, only CommandType "Request" has a domain header - // All outgoing domain messages have the domain header - domain_message_header = - std::make_unique(rp.PopRaw()); + // All outgoing domain messages have the domain header, if only incoming has it + if (incoming || domain_message_header) { + domain_message_header = + std::make_unique(rp.PopRaw()); + } } data_payload_header = @@ -196,7 +198,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P // TODO(Subv): Translate the X/A/B/W buffers. - if (Session()->IsDomain()) { + if (domain_message_header && Session()->IsDomain()) { ASSERT(domain_message_header->num_objects == domain_objects.size()); // Write the domain objects to the command buffer, these go after the raw untranslated data. // TODO(Subv): This completely ignores C buffers. diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 5608418c3c..42c2f760be 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -96,7 +96,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr thread) { ResultCode result = RESULT_SUCCESS; // If the session has been converted to a domain, handle the domain request - if (IsDomain()) { + if (context.GetDomainMessageHeader() && IsDomain()) { result = HandleDomainSyncRequest(context); // If there is no domain header, the regular session handler is used } else if (hle_handler != nullptr) { From 827152d1fd72d13b47b331f64455fc2a641877b1 Mon Sep 17 00:00:00 2001 From: mailwl Date: Tue, 20 Feb 2018 21:59:58 +0300 Subject: [PATCH 2/3] Fix: change check for domain order and existance of domain message header --- src/core/hle/ipc_helpers.h | 3 ++- src/core/hle/kernel/hle_ipc.cpp | 2 +- src/core/hle/kernel/server_session.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 97290fec55..3f87c4297c 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -118,7 +118,8 @@ public: AlignWithPadding(); - if (context.Session()->IsDomain() && context.GetDomainMessageHeader()) { + const bool request_has_domain_header{context.GetDomainMessageHeader() != nullptr}; + if (context.Session()->IsDomain() && request_has_domain_header) { IPC::DomainMessageHeader domain_header{}; domain_header.num_objects = num_domain_objects; PushRaw(domain_header); diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 3b1f3154de..eef784f5eb 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -198,7 +198,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P // TODO(Subv): Translate the X/A/B/W buffers. - if (domain_message_header && Session()->IsDomain()) { + if (Session()->IsDomain() && domain_message_header) { ASSERT(domain_message_header->num_objects == domain_objects.size()); // Write the domain objects to the command buffer, these go after the raw untranslated data. // TODO(Subv): This completely ignores C buffers. diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 42c2f760be..5f31cf19bb 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -96,7 +96,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr thread) { ResultCode result = RESULT_SUCCESS; // If the session has been converted to a domain, handle the domain request - if (context.GetDomainMessageHeader() && IsDomain()) { + if (IsDomain() && context.GetDomainMessageHeader()) { result = HandleDomainSyncRequest(context); // If there is no domain header, the regular session handler is used } else if (hle_handler != nullptr) { From 1289a3c3c154b198e44ceff3097bd8a50039b23a Mon Sep 17 00:00:00 2001 From: mailwl Date: Tue, 20 Feb 2018 22:51:54 +0300 Subject: [PATCH 3/3] Add warning if Domain request has no domain message header --- src/core/hle/kernel/hle_ipc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index eef784f5eb..d9faf4b535 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -89,6 +89,9 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { if (incoming || domain_message_header) { domain_message_header = std::make_unique(rp.PopRaw()); + } else { + if (Session()->IsDomain()) + LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!"); } }