forked from eden-emu/eden
		
	ipc_helpers: Make interface domain agnostic and add header validation.
This commit is contained in:
		
							parent
							
								
									a3aadaea60
								
							
						
					
					
						commit
						2b07c87f0c
					
				
					 2 changed files with 58 additions and 25 deletions
				
			
		|  | @ -30,11 +30,6 @@ public: | ||||||
|     RequestHelperBase(Kernel::HLERequestContext& context) |     RequestHelperBase(Kernel::HLERequestContext& context) | ||||||
|         : context(&context), cmdbuf(context.CommandBuffer()) {} |         : context(&context), cmdbuf(context.CommandBuffer()) {} | ||||||
| 
 | 
 | ||||||
|     void ValidateHeader() { |  | ||||||
|         // DEBUG_ASSERT_MSG(index == TotalSize(), "Operations do not match the header (cmd 0x%x)",
 |  | ||||||
|         //                 header.raw);
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     void Skip(unsigned size_in_words, bool set_to_null) { |     void Skip(unsigned size_in_words, bool set_to_null) { | ||||||
|         if (set_to_null) |         if (set_to_null) | ||||||
|             memset(cmdbuf + index, 0, size_in_words * sizeof(u32)); |             memset(cmdbuf + index, 0, size_in_words * sizeof(u32)); | ||||||
|  | @ -63,10 +58,18 @@ class RequestBuilder : public RequestHelperBase { | ||||||
| public: | public: | ||||||
|     RequestBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {} |     RequestBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {} | ||||||
| 
 | 
 | ||||||
|     RequestBuilder(Kernel::HLERequestContext& context, unsigned normal_params_size, |     u32 normal_params_size; | ||||||
|                    u32 num_handles_to_copy = 0, u32 num_handles_to_move = 0, |     u32 num_handles_to_copy; | ||||||
|                    u32 num_domain_objects = 0) |     u32 num_objects_to_move; ///< Domain objects or move handles, context dependent
 | ||||||
|         : RequestHelperBase(context) { |     std::ptrdiff_t datapayload_index; | ||||||
|  | 
 | ||||||
|  |     RequestBuilder(Kernel::HLERequestContext& context, u32 normal_params_size, | ||||||
|  |                    u32 num_handles_to_copy = 0, u32 num_objects_to_move = 0, | ||||||
|  |                    bool always_move_handle = false) | ||||||
|  | 
 | ||||||
|  |         : RequestHelperBase(context), normal_params_size(normal_params_size), | ||||||
|  |           num_handles_to_copy(num_handles_to_copy), num_objects_to_move(num_objects_to_move) { | ||||||
|  | 
 | ||||||
|         memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); |         memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); | ||||||
| 
 | 
 | ||||||
|         context.ClearIncomingObjects(); |         context.ClearIncomingObjects(); | ||||||
|  | @ -76,12 +79,18 @@ public: | ||||||
|         // 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; | ||||||
|  | 
 | ||||||
|  |         u32 num_handles_to_move{}; | ||||||
|  |         u32 num_domain_objects{}; | ||||||
|  | 
 | ||||||
|  |         if (!context.Session()->IsDomain() || always_move_handle) { | ||||||
|  |             num_handles_to_move = num_objects_to_move; | ||||||
|  |         } else { | ||||||
|  |             num_domain_objects = num_objects_to_move; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (context.Session()->IsDomain()) { |         if (context.Session()->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); | ||||||
|  | @ -109,11 +118,12 @@ public: | ||||||
|         IPC::DataPayloadHeader data_payload_header{}; |         IPC::DataPayloadHeader data_payload_header{}; | ||||||
|         data_payload_header.magic = Common::MakeMagic('S', 'F', 'C', 'O'); |         data_payload_header.magic = Common::MakeMagic('S', 'F', 'C', 'O'); | ||||||
|         PushRaw(data_payload_header); |         PushRaw(data_payload_header); | ||||||
|  | 
 | ||||||
|  |         datapayload_index = index; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     template <class T, class... Args> |     template <class T> | ||||||
|     void PushIpcInterface(Args&&... args) { |     void PushIpcInterface(std::shared_ptr<T> iface) { | ||||||
|         auto iface = std::make_shared<T>(std::forward<Args>(args)...); |  | ||||||
|         if (context->Session()->IsDomain()) { |         if (context->Session()->IsDomain()) { | ||||||
|             context->AddDomainObject(std::move(iface)); |             context->AddDomainObject(std::move(iface)); | ||||||
|         } else { |         } else { | ||||||
|  | @ -125,6 +135,24 @@ public: | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     template <class T, class... Args> | ||||||
|  |     void PushIpcInterface(Args&&... args) { | ||||||
|  |         PushIpcInterface<T>(std::make_shared<T>(std::forward<Args>(args)...)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void ValidateHeader() { | ||||||
|  |         const size_t num_domain_objects = context->NumDomainObjects(); | ||||||
|  |         const 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, | ||||||
|  |                    "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"); | ||||||
|  |         ASSERT_MSG(context->NumCopyObjects() == num_handles_to_copy, | ||||||
|  |                    "num_handles_to_copy value is incorrect"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // 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
 | ||||||
|     ~RequestBuilder() { |     ~RequestBuilder() { | ||||||
|         ValidateHeader(); |         ValidateHeader(); | ||||||
|  | @ -227,14 +255,8 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     RequestBuilder MakeBuilder(u32 normal_params_size, u32 num_handles_to_copy, |     RequestBuilder MakeBuilder(u32 normal_params_size, u32 num_handles_to_copy, | ||||||
|                                u32 num_handles_to_move, u32 num_domain_objects, |                                u32 num_handles_to_move, bool validate_header = true) { | ||||||
|                                bool validate_header = true) { |         return {*context, normal_params_size, num_handles_to_copy, num_handles_to_move}; | ||||||
|         if (validate_header) { |  | ||||||
|             ValidateHeader(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return {*context, normal_params_size, num_handles_to_copy, num_handles_to_move, |  | ||||||
|                 num_domain_objects}; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     template <typename T> |     template <typename T> | ||||||
|  |  | ||||||
|  | @ -175,6 +175,18 @@ public: | ||||||
|         domain_objects.clear(); |         domain_objects.clear(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     size_t NumMoveObjects() const { | ||||||
|  |         return move_objects.size(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     size_t NumCopyObjects() const { | ||||||
|  |         return copy_objects.size(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     size_t NumDomainObjects() const { | ||||||
|  |         return domain_objects.size(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | ||||||
|     SharedPtr<Kernel::ServerSession> server_session; |     SharedPtr<Kernel::ServerSession> server_session; | ||||||
|  | @ -196,7 +208,6 @@ private: | ||||||
|     unsigned data_payload_offset{}; |     unsigned data_payload_offset{}; | ||||||
|     unsigned buffer_c_offset{}; |     unsigned buffer_c_offset{}; | ||||||
|     u32_le command{}; |     u32_le command{}; | ||||||
|     bool is_domain{}; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace Kernel
 | } // namespace Kernel
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei