Ver Fonte

hle: kernel: hle_ipc: Fix outgoing IPC response size calculation.

bunnei há 5 anos atrás
pai
commit
12d569e483

+ 1 - 0
src/core/hle/ipc_helpers.h

@@ -108,6 +108,7 @@ public:
             header.type.Assign(ctx.GetCommandType());
             header.type.Assign(ctx.GetCommandType());
         }
         }
 
 
+        ctx.data_size = static_cast<u32>(raw_data_size);
         header.data_size.Assign(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) {
         if (num_handles_to_copy || num_handles_to_move) {
             header.enable_handle_descriptor.Assign(1);
             header.enable_handle_descriptor.Assign(1);

+ 13 - 1
src/core/hle/kernel/hle_ipc.cpp

@@ -186,6 +186,18 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_t
     auto& owner_process = *requesting_thread.GetOwnerProcess();
     auto& owner_process = *requesting_thread.GetOwnerProcess();
     auto& handle_table = owner_process.GetHandleTable();
     auto& handle_table = owner_process.GetHandleTable();
 
 
+    // The data_size already includes the payload header, the padding and the domain header.
+    std::size_t size{};
+
+    if (IsTipc()) {
+        size = cmd_buf.size();
+    } else {
+        size = data_payload_offset + data_size - sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4;
+        if (Session()->IsDomain()) {
+            size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32);
+        }
+    }
+
     for (auto& object : copy_objects) {
     for (auto& object : copy_objects) {
         Handle handle{};
         Handle handle{};
         if (object) {
         if (object) {
@@ -218,7 +230,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_t
 
 
     // Copy the translated command buffer back into the thread's command buffer area.
     // Copy the translated command buffer back into the thread's command buffer area.
     memory.WriteBlock(owner_process, requesting_thread.GetTLSAddress(), cmd_buf.data(),
     memory.WriteBlock(owner_process, requesting_thread.GetTLSAddress(), cmd_buf.data(),
-                      cmd_buf.size() * sizeof(u32));
+                      size * sizeof(u32));
 
 
     return RESULT_SUCCESS;
     return RESULT_SUCCESS;
 }
 }

+ 1 - 0
src/core/hle/kernel/hle_ipc.h

@@ -308,6 +308,7 @@ private:
     u32 data_payload_offset{};
     u32 data_payload_offset{};
     u32 handles_offset{};
     u32 handles_offset{};
     u32 domain_offset{};
     u32 domain_offset{};
+    u32 data_size{};
     u32_le command{};
     u32_le command{};
 
 
     std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers;
     std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers;