From d940974789b1b8ff473440883d8c506a275b9b3b Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 12 Jan 2024 09:35:08 -0500 Subject: [PATCH] audio: fetch process object from handle table --- src/audio_core/device/device_session.cpp | 14 +++++++-- src/audio_core/device/device_session.h | 12 +++++--- src/audio_core/in/audio_in_system.cpp | 2 +- src/audio_core/in/audio_in_system.h | 13 +++++---- src/audio_core/out/audio_out_system.cpp | 4 +-- src/audio_core/out/audio_out_system.h | 13 +++++---- src/core/hle/service/audio/audin_u.cpp | 36 +++++++++++++++++++----- src/core/hle/service/audio/audout_u.cpp | 26 +++++++++++++---- 8 files changed, 85 insertions(+), 35 deletions(-) diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp index ee42ae529d..3c214ec005 100644 --- a/src/audio_core/device/device_session.cpp +++ b/src/audio_core/device/device_session.cpp @@ -10,6 +10,8 @@ #include "core/core_timing.h" #include "core/memory.h" +#include "core/hle/kernel/k_process.h" + namespace AudioCore { using namespace std::literals; @@ -25,7 +27,7 @@ DeviceSession::~DeviceSession() { } Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_format_, - u16 channel_count_, size_t session_id_, u32 handle_, + u16 channel_count_, size_t session_id_, Kernel::KProcess* handle_, u64 applet_resource_user_id_, Sink::StreamType type_) { if (stream) { Finalize(); @@ -36,6 +38,7 @@ Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_for channel_count = channel_count_; session_id = session_id_; handle = handle_; + handle->Open(); applet_resource_user_id = applet_resource_user_id_; if (type == Sink::StreamType::In) { @@ -54,6 +57,11 @@ void DeviceSession::Finalize() { sink->CloseStream(stream); stream = nullptr; } + + if (handle) { + handle->Close(); + handle = nullptr; + } } void DeviceSession::Start() { @@ -91,7 +99,7 @@ void DeviceSession::AppendBuffers(std::span buffers) { stream->AppendBuffer(new_buffer, tmp_samples); } else { Core::Memory::CpuGuestMemory samples( - system.ApplicationMemory(), buffer.samples, buffer.size / sizeof(s16)); + handle->GetMemory(), buffer.samples, buffer.size / sizeof(s16)); stream->AppendBuffer(new_buffer, samples); } } @@ -100,7 +108,7 @@ void DeviceSession::AppendBuffers(std::span buffers) { void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const { if (type == Sink::StreamType::In) { auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))}; - system.ApplicationMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size); + handle->GetMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size); } } diff --git a/src/audio_core/device/device_session.h b/src/audio_core/device/device_session.h index 7d52f362d9..f3fae26175 100644 --- a/src/audio_core/device/device_session.h +++ b/src/audio_core/device/device_session.h @@ -20,6 +20,10 @@ struct EventType; } // namespace Timing } // namespace Core +namespace Kernel { +class KProcess; +} // namespace Kernel + namespace AudioCore { namespace Sink { @@ -44,13 +48,13 @@ public: * @param sample_format - Sample format for this device's output. * @param channel_count - Number of channels for this device (2 or 6). * @param session_id - This session's id. - * @param handle - Handle for this device session (unused). + * @param handle - Process handle for this device session. * @param applet_resource_user_id - Applet resource user id for this device session (unused). * @param type - Type of this stream (Render, In, Out). * @return Result code for this call. */ Result Initialize(std::string_view name, SampleFormat sample_format, u16 channel_count, - size_t session_id, u32 handle, u64 applet_resource_user_id, + size_t session_id, Kernel::KProcess* handle, u64 applet_resource_user_id, Sink::StreamType type); /** @@ -137,8 +141,8 @@ private: u16 channel_count{}; /// Session id of this device session size_t session_id{}; - /// Handle of this device session - u32 handle{}; + /// Process handle of device memory owner + Kernel::KProcess* handle{}; /// Applet resource user id of this device session u64 applet_resource_user_id{}; /// Total number of samples played by this device session diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp index 5791291213..b2dd3ef9f7 100644 --- a/src/audio_core/in/audio_in_system.cpp +++ b/src/audio_core/in/audio_in_system.cpp @@ -57,7 +57,7 @@ Result System::IsConfigValid(const std::string_view device_name, } Result System::Initialize(std::string device_name, const AudioInParameter& in_params, - const u32 handle_, const u64 applet_resource_user_id_) { + Kernel::KProcess* handle_, const u64 applet_resource_user_id_) { auto result{IsConfigValid(device_name, in_params)}; if (result.IsError()) { return result; diff --git a/src/audio_core/in/audio_in_system.h b/src/audio_core/in/audio_in_system.h index 1c51546381..ee048190c3 100644 --- a/src/audio_core/in/audio_in_system.h +++ b/src/audio_core/in/audio_in_system.h @@ -19,7 +19,8 @@ class System; namespace Kernel { class KEvent; -} +class KProcess; +} // namespace Kernel namespace AudioCore::AudioIn { @@ -93,12 +94,12 @@ public: * * @param device_name - The name of the requested input device. * @param in_params - Input parameters, see AudioInParameter. - * @param handle - Unused. + * @param handle - Process handle. * @param applet_resource_user_id - Unused. * @return Result code. */ - Result Initialize(std::string device_name, const AudioInParameter& in_params, u32 handle, - u64 applet_resource_user_id); + Result Initialize(std::string device_name, const AudioInParameter& in_params, + Kernel::KProcess* handle, u64 applet_resource_user_id); /** * Start this system. @@ -244,8 +245,8 @@ public: private: /// Core system Core::System& system; - /// (Unused) - u32 handle{}; + /// Process handle + Kernel::KProcess* handle{}; /// (Unused) u64 applet_resource_user_id{}; /// Buffer event, signalled when a buffer is ready diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp index 0adf64bd34..7b3ff4e881 100644 --- a/src/audio_core/out/audio_out_system.cpp +++ b/src/audio_core/out/audio_out_system.cpp @@ -48,8 +48,8 @@ Result System::IsConfigValid(std::string_view device_name, return Service::Audio::ResultInvalidChannelCount; } -Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_, - u64 applet_resource_user_id_) { +Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, + Kernel::KProcess* handle_, u64 applet_resource_user_id_) { auto result = IsConfigValid(device_name, in_params); if (result.IsError()) { return result; diff --git a/src/audio_core/out/audio_out_system.h b/src/audio_core/out/audio_out_system.h index b95cb91bec..82aada1855 100644 --- a/src/audio_core/out/audio_out_system.h +++ b/src/audio_core/out/audio_out_system.h @@ -19,7 +19,8 @@ class System; namespace Kernel { class KEvent; -} +class KProcess; +} // namespace Kernel namespace AudioCore::AudioOut { @@ -84,12 +85,12 @@ public: * * @param device_name - The name of the requested output device. * @param in_params - Input parameters, see AudioOutParameter. - * @param handle - Unused. + * @param handle - Process handle. * @param applet_resource_user_id - Unused. * @return Result code. */ - Result Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle, - u64 applet_resource_user_id); + Result Initialize(std::string device_name, const AudioOutParameter& in_params, + Kernel::KProcess* handle, u64 applet_resource_user_id); /** * Start this system. @@ -228,8 +229,8 @@ public: private: /// Core system Core::System& system; - /// (Unused) - u32 handle{}; + /// Process handle + Kernel::KProcess* handle{}; /// (Unused) u64 applet_resource_user_id{}; /// Buffer event, signalled when a buffer is ready diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index 56fee45919..de2aa6906a 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp @@ -18,11 +18,11 @@ using namespace AudioCore::AudioIn; class IAudioIn final : public ServiceFramework { public: explicit IAudioIn(Core::System& system_, Manager& manager, size_t session_id, - const std::string& device_name, const AudioInParameter& in_params, u32 handle, - u64 applet_resource_user_id) + const std::string& device_name, const AudioInParameter& in_params, + Kernel::KProcess* handle, u64 applet_resource_user_id) : ServiceFramework{system_, "IAudioIn"}, service_context{system_, "IAudioIn"}, event{service_context.CreateEvent("AudioInEvent")}, - impl{std::make_shared(system_, manager, event, session_id)} { + process{handle}, impl{std::make_shared(system_, manager, event, session_id)} { // clang-format off static const FunctionInfo functions[] = { {0, &IAudioIn::GetAudioInState, "GetAudioInState"}, @@ -45,6 +45,8 @@ public: RegisterHandlers(functions); + process->Open(); + if (impl->GetSystem() .Initialize(device_name, in_params, handle, applet_resource_user_id) .IsError()) { @@ -55,6 +57,7 @@ public: ~IAudioIn() override { impl->Free(); service_context.CloseEvent(event); + process->Close(); } [[nodiscard]] std::shared_ptr GetImpl() { @@ -196,6 +199,7 @@ private: KernelHelpers::ServiceContext service_context; Kernel::KEvent* event; + Kernel::KProcess* process; std::shared_ptr impl; Common::ScratchBuffer released_buffer; }; @@ -267,6 +271,14 @@ void AudInU::OpenAudioIn(HLERequestContext& ctx) { auto device_name = Common::StringFromBuffer(device_name_data); auto handle{ctx.GetCopyHandle(0)}; + auto process{ctx.GetObjectFromHandle(handle)}; + if (process.IsNull()) { + LOG_ERROR(Service_Audio, "Failed to get process handle"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + std::scoped_lock l{impl->mutex}; auto link{impl->LinkToManager()}; if (link.IsError()) { @@ -287,8 +299,9 @@ void AudInU::OpenAudioIn(HLERequestContext& ctx) { LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id, impl->num_free_sessions); - auto audio_in = std::make_shared(system, *impl, new_session_id, device_name, - in_params, handle, applet_resource_user_id); + auto audio_in = + std::make_shared(system, *impl, new_session_id, device_name, in_params, + process.GetPointerUnsafe(), applet_resource_user_id); impl->sessions[new_session_id] = audio_in->GetImpl(); impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; @@ -318,6 +331,14 @@ void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) { auto device_name = Common::StringFromBuffer(device_name_data); auto handle{ctx.GetCopyHandle(0)}; + auto process{ctx.GetObjectFromHandle(handle)}; + if (process.IsNull()) { + LOG_ERROR(Service_Audio, "Failed to get process handle"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + std::scoped_lock l{impl->mutex}; auto link{impl->LinkToManager()}; if (link.IsError()) { @@ -338,8 +359,9 @@ void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) { LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id, impl->num_free_sessions); - auto audio_in = std::make_shared(system, *impl, new_session_id, device_name, - in_params, handle, applet_resource_user_id); + auto audio_in = + std::make_shared(system, *impl, new_session_id, device_name, in_params, + process.GetPointerUnsafe(), applet_resource_user_id); impl->sessions[new_session_id] = audio_in->GetImpl(); impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index ca683d72c7..8cc7b69f4b 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -26,9 +26,10 @@ class IAudioOut final : public ServiceFramework { public: explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, size_t session_id, const std::string& device_name, - const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) + const AudioOutParameter& in_params, Kernel::KProcess* handle, + u64 applet_resource_user_id) : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"}, - event{service_context.CreateEvent("AudioOutEvent")}, + event{service_context.CreateEvent("AudioOutEvent")}, process{handle}, impl{std::make_shared(system_, manager, event, session_id)} { // clang-format off @@ -50,11 +51,14 @@ public: }; // clang-format on RegisterHandlers(functions); + + process->Open(); } ~IAudioOut() override { impl->Free(); service_context.CloseEvent(event); + process->Close(); } [[nodiscard]] std::shared_ptr GetImpl() { @@ -206,6 +210,7 @@ private: KernelHelpers::ServiceContext service_context; Kernel::KEvent* event; + Kernel::KProcess* process; std::shared_ptr impl; Common::ScratchBuffer released_buffer; }; @@ -257,6 +262,14 @@ void AudOutU::OpenAudioOut(HLERequestContext& ctx) { auto device_name = Common::StringFromBuffer(device_name_data); auto handle{ctx.GetCopyHandle(0)}; + auto process{ctx.GetObjectFromHandle(handle)}; + if (process.IsNull()) { + LOG_ERROR(Service_Audio, "Failed to get process handle"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + auto link{impl->LinkToManager()}; if (link.IsError()) { LOG_ERROR(Service_Audio, "Failed to link Audio Out to Audio Manager"); @@ -276,10 +289,11 @@ void AudOutU::OpenAudioOut(HLERequestContext& ctx) { LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id, impl->num_free_sessions); - auto audio_out = std::make_shared(system, *impl, new_session_id, device_name, - in_params, handle, applet_resource_user_id); - result = audio_out->GetImpl()->GetSystem().Initialize(device_name, in_params, handle, - applet_resource_user_id); + auto audio_out = + std::make_shared(system, *impl, new_session_id, device_name, in_params, + process.GetPointerUnsafe(), applet_resource_user_id); + result = audio_out->GetImpl()->GetSystem().Initialize( + device_name, in_params, process.GetPointerUnsafe(), applet_resource_user_id); if (result.IsError()) { LOG_ERROR(Service_Audio, "Failed to initialize the AudioOut System!"); IPC::ResponseBuilder rb{ctx, 2};