diff options
| author | Morph <39850852+Morph1984@users.noreply.github.com> | 2023-06-24 21:30:09 -0400 |
|---|---|---|
| committer | Morph <39850852+Morph1984@users.noreply.github.com> | 2023-07-01 16:21:22 -0400 |
| commit | b94e57665369ab1c944c51586912f758ad4b86b1 (patch) | |
| tree | c2cf3cdf519d898f510e9679d288d29dbc159e90 /src/core/hle/kernel/svc/svc_ipc.cpp | |
| parent | 9252ad4e1091eaa0d9865c6a212feaac20d13918 (diff) | |
kernel: Synchronize
Diffstat (limited to 'src/core/hle/kernel/svc/svc_ipc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc/svc_ipc.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index 60247df2e..bb94f6934 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp @@ -38,22 +38,31 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_addr, s32 num_handles, Handle reply_target, s64 timeout_ns) { + // Ensure number of handles is valid. + R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); + + // Get the synchronization context. auto& kernel = system.Kernel(); auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); - - R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); - R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( - handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), - ResultInvalidPointer); - - std::array<Handle, Svc::ArgumentHandleCountMax> handles; - GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); - - // Convert handle list to object table. - std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs; - R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(), - num_handles), - ResultInvalidHandle); + auto objs = GetCurrentThread(kernel).GetSynchronizationObjectBuffer(); + auto handles = GetCurrentThread(kernel).GetHandleBuffer(); + + // Copy user handles. + if (num_handles > 0) { + // Ensure we can try to get the handles. + R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( + handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), + ResultInvalidPointer); + + // Get the handles. + GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), + sizeof(Handle) * num_handles); + + // Convert the handles to objects. + R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>( + objs.data(), handles.data(), num_handles), + ResultInvalidHandle); + } // Ensure handles are closed when we're done. SCOPE_EXIT({ |
