Просмотр исходного кода

ipc: Add support for PopIpcInterface() method.

- This can be used for domain objects as inputs to service functions.
bunnei 8 лет назад
Родитель
Сommit
fadab1d5f3

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

@@ -167,6 +167,7 @@ struct DomainMessageHeader {
         struct {
             union {
                 BitField<0, 8, CommandType> command;
+                BitField<8, 8, u32_le> input_object_count;
                 BitField<16, 16, u32_le> size;
             };
             u32_le object_id;

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

@@ -298,6 +298,13 @@ public:
 
     template <typename T>
     Kernel::SharedPtr<T> GetCopyObject(size_t index);
+
+    template <class T>
+    std::shared_ptr<T> PopIpcInterface() {
+        ASSERT(context->Session()->IsDomain());
+        ASSERT(context->GetDomainMessageHeader()->input_object_count > 0);
+        return context->GetDomainRequestHandler<T>(Pop<u32>() - 1);
+    }
 };
 
 /// Pop ///

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

@@ -202,6 +202,16 @@ public:
         domain_objects.emplace_back(std::move(object));
     }
 
+    template <typename T>
+    std::shared_ptr<T> GetDomainRequestHandler(size_t index) const {
+        return std::static_pointer_cast<T>(domain_request_handlers[index]);
+    }
+
+    void SetDomainRequestHandlers(
+        const std::vector<std::shared_ptr<SessionRequestHandler>>& handlers) {
+        domain_request_handlers = handlers;
+    }
+
     /// Clears the list of objects so that no lingering objects are written accidentally to the
     /// response buffer.
     void ClearIncomingObjects() {
@@ -245,6 +255,8 @@ private:
     unsigned data_payload_offset{};
     unsigned buffer_c_offset{};
     u32_le command{};
+
+    std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers;
 };
 
 } // namespace Kernel

+ 3 - 0
src/core/hle/kernel/server_session.cpp

@@ -61,6 +61,9 @@ void ServerSession::Acquire(Thread* thread) {
 ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
     auto& domain_message_header = context.GetDomainMessageHeader();
     if (domain_message_header) {
+        // Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
+        context.SetDomainRequestHandlers(domain_request_handlers);
+
         // If there is a DomainMessageHeader, then this is CommandType "Request"
         const u32 object_id{context.GetDomainMessageHeader()->object_id};
         switch (domain_message_header->command) {