service: hle: Allow to access read buffer A and X directly
This commit is contained in:
		| @@ -400,10 +400,10 @@ protected: | |||||||
|         IPC::RequestParser rp{ctx}; |         IPC::RequestParser rp{ctx}; | ||||||
|         const auto base = rp.PopRaw<ProfileBase>(); |         const auto base = rp.PopRaw<ProfileBase>(); | ||||||
|  |  | ||||||
|         const auto user_data = ctx.ReadBuffer(); |         const auto image_data = ctx.ReadBufferA(0); | ||||||
|         const auto image_data = ctx.ReadBuffer(1); |         const auto user_data = ctx.ReadBufferX(0); | ||||||
|  |  | ||||||
|         LOG_DEBUG(Service_ACC, "called, username='{}', timestamp={:016X}, uuid=0x{}", |         LOG_INFO(Service_ACC, "called, username='{}', timestamp={:016X}, uuid=0x{}", | ||||||
|                  Common::StringFromFixedZeroTerminatedBuffer( |                  Common::StringFromFixedZeroTerminatedBuffer( | ||||||
|                      reinterpret_cast<const char*>(base.username.data()), base.username.size()), |                      reinterpret_cast<const char*>(base.username.data()), base.username.size()), | ||||||
|                  base.timestamp, base.user_uuid.RawString()); |                  base.timestamp, base.user_uuid.RawString()); | ||||||
|   | |||||||
| @@ -23,6 +23,17 @@ | |||||||
| #include "core/hle/service/ipc_helpers.h" | #include "core/hle/service/ipc_helpers.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  | static thread_local std::array read_buffer_data_a{ | ||||||
|  |     Common::ScratchBuffer<u8>(), | ||||||
|  |     Common::ScratchBuffer<u8>(), | ||||||
|  | }; | ||||||
|  | static thread_local std::array read_buffer_data_x{ | ||||||
|  |     Common::ScratchBuffer<u8>(), | ||||||
|  |     Common::ScratchBuffer<u8>(), | ||||||
|  | }; | ||||||
|  | } // Anonymous namespace | ||||||
|  |  | ||||||
| namespace Service { | namespace Service { | ||||||
|  |  | ||||||
| SessionRequestHandler::SessionRequestHandler(Kernel::KernelCore& kernel_, const char* service_name_) | SessionRequestHandler::SessionRequestHandler(Kernel::KernelCore& kernel_, const char* service_name_) | ||||||
| @@ -328,26 +339,57 @@ std::vector<u8> HLERequestContext::ReadBufferCopy(std::size_t buffer_index) cons | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::span<const u8> HLERequestContext::ReadBufferA(std::size_t buffer_index) const { | ||||||
|  |     static thread_local std::array read_buffer_a{ | ||||||
|  |         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||||||
|  |         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     ASSERT_OR_EXECUTE_MSG( | ||||||
|  |         BufferDescriptorA().size() > buffer_index, { return {}; }, | ||||||
|  |         "BufferDescriptorA invalid buffer_index {}", buffer_index); | ||||||
|  |     auto& read_buffer = read_buffer_a[buffer_index]; | ||||||
|  |     return read_buffer.Read(BufferDescriptorA()[buffer_index].Address(), | ||||||
|  |                             BufferDescriptorA()[buffer_index].Size(), | ||||||
|  |                             &read_buffer_data_a[buffer_index]); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::span<const u8> HLERequestContext::ReadBufferX(std::size_t buffer_index) const { | ||||||
|  |     static thread_local std::array read_buffer_x{ | ||||||
|  |         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||||||
|  |         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     ASSERT_OR_EXECUTE_MSG( | ||||||
|  |         BufferDescriptorX().size() > buffer_index, { return {}; }, | ||||||
|  |         "BufferDescriptorX invalid buffer_index {}", buffer_index); | ||||||
|  |     auto& read_buffer = read_buffer_x[buffer_index]; | ||||||
|  |     return read_buffer.Read(BufferDescriptorX()[buffer_index].Address(), | ||||||
|  |                             BufferDescriptorX()[buffer_index].Size(), | ||||||
|  |                             &read_buffer_data_x[buffer_index]); | ||||||
|  | } | ||||||
|  |  | ||||||
| std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { | std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { | ||||||
|     static thread_local std::array read_buffer_a{ |     static thread_local std::array read_buffer_a{ | ||||||
|         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), |         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||||||
|         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), |         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||||||
|     }; |     }; | ||||||
|     static thread_local std::array read_buffer_data_a{ |  | ||||||
|         Common::ScratchBuffer<u8>(), |  | ||||||
|         Common::ScratchBuffer<u8>(), |  | ||||||
|     }; |  | ||||||
|     static thread_local std::array read_buffer_x{ |     static thread_local std::array read_buffer_x{ | ||||||
|         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), |         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||||||
|         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), |         Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||||||
|     }; |     }; | ||||||
|     static thread_local std::array read_buffer_data_x{ |  | ||||||
|         Common::ScratchBuffer<u8>(), |  | ||||||
|         Common::ScratchBuffer<u8>(), |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && |     const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && | ||||||
|                            BufferDescriptorA()[buffer_index].Size()}; |                            BufferDescriptorA()[buffer_index].Size()}; | ||||||
|  |     const bool is_buffer_x{BufferDescriptorX().size() > buffer_index && | ||||||
|  |                            BufferDescriptorX()[buffer_index].Size()}; | ||||||
|  |  | ||||||
|  |     if (is_buffer_a && is_buffer_x) { | ||||||
|  |         LOG_WARNING(Input, "Both buffer descriptors are available a.size={}, x.size={}", | ||||||
|  |                     BufferDescriptorA()[buffer_index].Size(), | ||||||
|  |                     BufferDescriptorX()[buffer_index].Size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (is_buffer_a) { |     if (is_buffer_a) { | ||||||
|         ASSERT_OR_EXECUTE_MSG( |         ASSERT_OR_EXECUTE_MSG( | ||||||
|             BufferDescriptorA().size() > buffer_index, { return {}; }, |             BufferDescriptorA().size() > buffer_index, { return {}; }, | ||||||
|   | |||||||
| @@ -253,6 +253,12 @@ public: | |||||||
|         return domain_message_header.has_value(); |         return domain_message_header.has_value(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Helper function to get a span of a buffer using the buffer descriptor A | ||||||
|  |     [[nodiscard]] std::span<const u8> ReadBufferA(std::size_t buffer_index = 0) const; | ||||||
|  |  | ||||||
|  |     /// Helper function to get a span of a buffer using the buffer descriptor X | ||||||
|  |     [[nodiscard]] std::span<const u8> ReadBufferX(std::size_t buffer_index = 0) const; | ||||||
|  |  | ||||||
|     /// Helper function to get a span of a buffer using the appropriate buffer descriptor |     /// Helper function to get a span of a buffer using the appropriate buffer descriptor | ||||||
|     [[nodiscard]] std::span<const u8> ReadBuffer(std::size_t buffer_index = 0) const; |     [[nodiscard]] std::span<const u8> ReadBuffer(std::size_t buffer_index = 0) const; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -58,14 +58,8 @@ private: | |||||||
|         IPC::RequestParser rp{ctx}; |         IPC::RequestParser rp{ctx}; | ||||||
|         const auto process_id = rp.PopRaw<u64>(); |         const auto process_id = rp.PopRaw<u64>(); | ||||||
|  |  | ||||||
|         const auto data1 = ctx.ReadBuffer(0); |         const auto data1 = ctx.ReadBufferA(0); | ||||||
|         const auto data2 = [&ctx] { |         const auto data2 = ctx.ReadBufferX(0); | ||||||
|             if (ctx.CanReadBuffer(1)) { |  | ||||||
|                 return ctx.ReadBuffer(1); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return std::span<const u8>{}; |  | ||||||
|         }(); |  | ||||||
|  |  | ||||||
|         LOG_DEBUG(Service_PREPO, |         LOG_DEBUG(Service_PREPO, | ||||||
|                   "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}", |                   "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}", | ||||||
| @@ -85,14 +79,8 @@ private: | |||||||
|         const auto user_id = rp.PopRaw<u128>(); |         const auto user_id = rp.PopRaw<u128>(); | ||||||
|         const auto process_id = rp.PopRaw<u64>(); |         const auto process_id = rp.PopRaw<u64>(); | ||||||
|  |  | ||||||
|         const auto data1 = ctx.ReadBuffer(0); |         const auto data1 = ctx.ReadBufferA(0); | ||||||
|         const auto data2 = [&ctx] { |         const auto data2 = ctx.ReadBufferX(0); | ||||||
|             if (ctx.CanReadBuffer(1)) { |  | ||||||
|                 return ctx.ReadBuffer(1); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return std::span<const u8>{}; |  | ||||||
|         }(); |  | ||||||
|  |  | ||||||
|         LOG_DEBUG(Service_PREPO, |         LOG_DEBUG(Service_PREPO, | ||||||
|                   "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, " |                   "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, " | ||||||
| @@ -137,14 +125,8 @@ private: | |||||||
|         IPC::RequestParser rp{ctx}; |         IPC::RequestParser rp{ctx}; | ||||||
|         const auto title_id = rp.PopRaw<u64>(); |         const auto title_id = rp.PopRaw<u64>(); | ||||||
|  |  | ||||||
|         const auto data1 = ctx.ReadBuffer(0); |         const auto data1 = ctx.ReadBufferA(0); | ||||||
|         const auto data2 = [&ctx] { |         const auto data2 = ctx.ReadBufferX(0); | ||||||
|             if (ctx.CanReadBuffer(1)) { |  | ||||||
|                 return ctx.ReadBuffer(1); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return std::span<const u8>{}; |  | ||||||
|         }(); |  | ||||||
|  |  | ||||||
|         LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}", |         LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}", | ||||||
|                   title_id, data1.size(), data2.size()); |                   title_id, data1.size(), data2.size()); | ||||||
| @@ -161,14 +143,8 @@ private: | |||||||
|         const auto user_id = rp.PopRaw<u128>(); |         const auto user_id = rp.PopRaw<u128>(); | ||||||
|         const auto title_id = rp.PopRaw<u64>(); |         const auto title_id = rp.PopRaw<u64>(); | ||||||
|  |  | ||||||
|         const auto data1 = ctx.ReadBuffer(0); |         const auto data1 = ctx.ReadBufferA(0); | ||||||
|         const auto data2 = [&ctx] { |         const auto data2 = ctx.ReadBufferX(0); | ||||||
|             if (ctx.CanReadBuffer(1)) { |  | ||||||
|                 return ctx.ReadBuffer(1); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return std::span<const u8>{}; |  | ||||||
|         }(); |  | ||||||
|  |  | ||||||
|         LOG_DEBUG(Service_PREPO, |         LOG_DEBUG(Service_PREPO, | ||||||
|                   "called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, " |                   "called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, " | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user