mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
os: remove ManagedHandle, refactor to use NativeHandle typename
This commit is contained in:
parent
a774833790
commit
6f76066d24
71 changed files with 473 additions and 397 deletions
|
@ -15,10 +15,11 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/os.hpp>
|
||||||
|
|
||||||
namespace ams::dd {
|
namespace ams::dd {
|
||||||
|
|
||||||
using ProcessHandle = ::Handle;
|
using ProcessHandle = os::NativeHandle;
|
||||||
|
|
||||||
using MemoryPermission = os::MemoryPermission;
|
using MemoryPermission = os::MemoryPermission;
|
||||||
using enum os::MemoryPermission;
|
using enum os::MemoryPermission;
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
#include <stratosphere/os/os_memory_permission.hpp>
|
#include <stratosphere/os/os_memory_permission.hpp>
|
||||||
#include <stratosphere/os/os_memory_heap_api.hpp>
|
#include <stratosphere/os/os_memory_heap_api.hpp>
|
||||||
#include <stratosphere/os/os_memory_virtual_address_api.hpp>
|
#include <stratosphere/os/os_memory_virtual_address_api.hpp>
|
||||||
#include <stratosphere/os/os_managed_handle.hpp>
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
#include <stratosphere/os/os_process_handle.hpp>
|
#include <stratosphere/os/os_process_handle_api.hpp>
|
||||||
#include <stratosphere/os/os_random.hpp>
|
#include <stratosphere/os/os_random.hpp>
|
||||||
#include <stratosphere/os/os_mutex.hpp>
|
#include <stratosphere/os/os_mutex.hpp>
|
||||||
#include <stratosphere/os/os_condition_variable.hpp>
|
#include <stratosphere/os/os_condition_variable.hpp>
|
||||||
|
|
|
@ -44,16 +44,6 @@ namespace ams::os {
|
||||||
|
|
||||||
inline constexpr const ProcessId InvalidProcessId = ProcessId::Invalid;
|
inline constexpr const ProcessId InvalidProcessId = ProcessId::Invalid;
|
||||||
|
|
||||||
NX_INLINE Result TryGetProcessId(os::ProcessId *out, ::Handle process_handle) {
|
|
||||||
return svcGetProcessId(&out->value, process_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
NX_INLINE os::ProcessId GetProcessId(::Handle process_handle) {
|
|
||||||
os::ProcessId process_id;
|
|
||||||
R_ABORT_UNLESS(TryGetProcessId(&process_id, process_handle));
|
|
||||||
return process_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline constexpr bool operator==(const ProcessId &lhs, const ProcessId &rhs) {
|
inline constexpr bool operator==(const ProcessId &lhs, const ProcessId &rhs) {
|
||||||
return lhs.value == rhs.value;
|
return lhs.value == rhs.value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/impl/os_internal_critical_section.hpp>
|
#include <stratosphere/os/impl/os_internal_critical_section.hpp>
|
||||||
#include <stratosphere/os/impl/os_internal_condition_variable.hpp>
|
#include <stratosphere/os/impl/os_internal_condition_variable.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ namespace ams::os {
|
||||||
u8 clear_mode;
|
u8 clear_mode;
|
||||||
u8 state;
|
u8 state;
|
||||||
|
|
||||||
util::TypedStorage<impl::InterruptEventImpl, sizeof(svc::Handle) * 2, alignof(svc::Handle)> impl;
|
util::TypedStorage<impl::InterruptEventImpl, sizeof(NativeHandle) * 2, alignof(NativeHandle)> impl;
|
||||||
};
|
};
|
||||||
static_assert(std::is_trivial<InterruptEventType>::value);
|
static_assert(std::is_trivial<InterruptEventType>::value);
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,11 @@ namespace ams::os {
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
IoRegion(Handle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission) {
|
IoRegion(NativeHandle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission) {
|
||||||
R_ABORT_UNLESS(CreateIoRegion(std::addressof(m_io_region), io_pool_handle, address, size, mapping, permission));
|
R_ABORT_UNLESS(CreateIoRegion(std::addressof(m_io_region), io_pool_handle, address, size, mapping, permission));
|
||||||
}
|
}
|
||||||
|
|
||||||
IoRegion(size_t size, Handle handle, bool managed) {
|
IoRegion(size_t size, NativeHandle handle, bool managed) {
|
||||||
this->AttachHandle(size, handle, managed);
|
this->AttachHandle(size, handle, managed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +51,11 @@ namespace ams::os {
|
||||||
DestroyIoRegion(std::addressof(m_io_region));
|
DestroyIoRegion(std::addressof(m_io_region));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachHandle(size_t size, Handle handle, bool managed) {
|
void AttachHandle(size_t size, NativeHandle handle, bool managed) {
|
||||||
AttachIoRegionHandle(std::addressof(m_io_region), size, handle, managed);
|
AttachIoRegionHandle(std::addressof(m_io_region), size, handle, managed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetHandle() const {
|
NativeHandle GetHandle() const {
|
||||||
return GetIoRegionHandle(std::addressof(m_io_region));
|
return GetIoRegionHandle(std::addressof(m_io_region));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,18 +17,19 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/os_memory_permission.hpp>
|
#include <stratosphere/os/os_memory_permission.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
struct IoRegionType;
|
struct IoRegionType;
|
||||||
|
|
||||||
Result CreateIoRegion(IoRegionType *io_region, Handle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission);
|
Result CreateIoRegion(IoRegionType *io_region, NativeHandle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission);
|
||||||
|
|
||||||
void AttachIoRegionHandle(IoRegionType *io_region, size_t size, Handle handle, bool managed);
|
void AttachIoRegionHandle(IoRegionType *io_region, size_t size, NativeHandle handle, bool managed);
|
||||||
|
|
||||||
void DestroyIoRegion(IoRegionType *io_region);
|
void DestroyIoRegion(IoRegionType *io_region);
|
||||||
|
|
||||||
Handle GetIoRegionHandle(const IoRegionType *io_region);
|
NativeHandle GetIoRegionHandle(const IoRegionType *io_region);
|
||||||
|
|
||||||
Result MapIoRegion(void **out, IoRegionType *io_region, MemoryPermission perm);
|
Result MapIoRegion(void **out, IoRegionType *io_region, MemoryPermission perm);
|
||||||
void UnmapIoRegion(IoRegionType *io_region);
|
void UnmapIoRegion(IoRegionType *io_region);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/impl/os_internal_critical_section.hpp>
|
#include <stratosphere/os/impl/os_internal_critical_section.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ namespace ams::os {
|
||||||
State_Mapped = 2,
|
State_Mapped = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
Handle handle;
|
NativeHandle handle;
|
||||||
u8 state;
|
u8 state;
|
||||||
size_t size;
|
size_t size;
|
||||||
void *mapped_address;
|
void *mapped_address;
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/os/os_common_types.hpp>
|
|
||||||
|
|
||||||
namespace ams::os {
|
|
||||||
|
|
||||||
class ManagedHandle {
|
|
||||||
NON_COPYABLE(ManagedHandle);
|
|
||||||
private:
|
|
||||||
Handle hnd;
|
|
||||||
public:
|
|
||||||
constexpr ManagedHandle() : hnd(INVALID_HANDLE) { /* ... */ }
|
|
||||||
constexpr ManagedHandle(Handle h) : hnd(h) { /* ... */ }
|
|
||||||
~ManagedHandle() {
|
|
||||||
if (this->hnd != INVALID_HANDLE) {
|
|
||||||
R_ABORT_UNLESS(svcCloseHandle(this->hnd));
|
|
||||||
this->hnd = INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ManagedHandle(ManagedHandle&& rhs) {
|
|
||||||
this->hnd = rhs.hnd;
|
|
||||||
rhs.hnd = INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ManagedHandle &operator=(ManagedHandle&& rhs) {
|
|
||||||
rhs.Swap(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit operator bool() const {
|
|
||||||
return this->hnd != INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Swap(ManagedHandle &rhs) {
|
|
||||||
std::swap(this->hnd, rhs.hnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle Get() const {
|
|
||||||
return this->hnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle *GetPointer() {
|
|
||||||
return &this->hnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle *GetPointerAndClear() {
|
|
||||||
this->Clear();
|
|
||||||
return this->GetPointer();
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle Move() {
|
|
||||||
const Handle h = this->hnd;
|
|
||||||
this->hnd = INVALID_HANDLE;
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Detach() {
|
|
||||||
const Handle h = this->Move();
|
|
||||||
AMS_UNUSED(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset(Handle h) {
|
|
||||||
ManagedHandle(h).Swap(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear() {
|
|
||||||
this->Reset(INVALID_HANDLE);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -16,6 +16,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/os_message_queue_common.hpp>
|
#include <stratosphere/os/os_message_queue_common.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -40,6 +41,6 @@ namespace ams::os {
|
||||||
void SetMultiWaitHolderUserData(MultiWaitHolderType *holder, uintptr_t user_data);
|
void SetMultiWaitHolderUserData(MultiWaitHolderType *holder, uintptr_t user_data);
|
||||||
uintptr_t GetMultiWaitHolderUserData(const MultiWaitHolderType *holder);
|
uintptr_t GetMultiWaitHolderUserData(const MultiWaitHolderType *holder);
|
||||||
|
|
||||||
void InitializeMultiWaitHolder(MultiWaitHolderType *holder, Handle handle);
|
void InitializeMultiWaitHolder(MultiWaitHolderType *holder, NativeHandle handle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,5 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere/os/os_native_handle_types.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle_api.hpp>
|
||||||
namespace ams::os::impl {
|
|
||||||
|
|
||||||
ncm::ProgramId GetCurrentProgramId();
|
|
||||||
|
|
||||||
}
|
|
|
@ -15,18 +15,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere/os/os_managed_handle.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/ncm/ncm_program_id.hpp>
|
#include <stratosphere/os/os_native_handle_types.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
::Handle GetCurrentProcessHandle();
|
void CloseNativeHandle(NativeHandle handle);
|
||||||
|
|
||||||
ALWAYS_INLINE ProcessId GetCurrentProcessId() {
|
NativeHandle GetCurrentProcessHandle();
|
||||||
return GetProcessId(GetCurrentProcessHandle());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Another header? */
|
|
||||||
ncm::ProgramId GetCurrentProgramId();
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
|
||||||
|
namespace ams::os {
|
||||||
|
|
||||||
|
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||||
|
using NativeHandle = svc::Handle;
|
||||||
|
static_assert(std::unsigned_integral<NativeHandle>);
|
||||||
|
|
||||||
|
constexpr inline NativeHandle InvalidNativeHandle = svc::InvalidHandle;
|
||||||
|
#else
|
||||||
|
#error "Unknown OS for os::NativeHandle"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
#include <stratosphere/ncm/ncm_program_id.hpp>
|
||||||
|
|
||||||
|
namespace ams::os {
|
||||||
|
|
||||||
|
Result GetProcessId(os::ProcessId *out, NativeHandle handle);
|
||||||
|
|
||||||
|
ALWAYS_INLINE ProcessId GetProcessId(NativeHandle handle) {
|
||||||
|
ProcessId process_id;
|
||||||
|
R_ABORT_UNLESS(GetProcessId(std::addressof(process_id), handle));
|
||||||
|
return process_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE ProcessId GetCurrentProcessId() {
|
||||||
|
return GetProcessId(GetCurrentProcessHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetProgramId(ncm::ProgramId *out, NativeHandle handle);
|
||||||
|
|
||||||
|
ALWAYS_INLINE ncm::ProgramId GetProgramId(NativeHandle handle) {
|
||||||
|
ncm::ProgramId program_id;
|
||||||
|
R_ABORT_UNLESS(GetProgramId(std::addressof(program_id), handle));
|
||||||
|
return program_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE ncm::ProgramId GetCurrentProgramId() {
|
||||||
|
return GetProgramId(GetCurrentProcessHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,12 +15,13 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
struct MultiWaitHolderType;
|
struct MultiWaitHolderType;
|
||||||
struct MultiWaitType;
|
struct MultiWaitType;
|
||||||
|
|
||||||
Result SdkReplyAndReceive(os::MultiWaitHolderType **out, Handle reply_target, MultiWaitType *multi_wait);
|
Result SdkReplyAndReceive(os::MultiWaitHolderType **out, NativeHandle reply_target, MultiWaitType *multi_wait);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace ams::os {
|
||||||
R_ABORT_UNLESS(CreateSharedMemory(std::addressof(m_shared_memory), size, my_perm, other_perm));
|
R_ABORT_UNLESS(CreateSharedMemory(std::addressof(m_shared_memory), size, my_perm, other_perm));
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedMemory(size_t size, Handle handle, bool managed) {
|
SharedMemory(size_t size, NativeHandle handle, bool managed) {
|
||||||
this->Attach(size, handle, managed);
|
this->Attach(size, handle, managed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ namespace ams::os {
|
||||||
DestroySharedMemory(std::addressof(m_shared_memory));
|
DestroySharedMemory(std::addressof(m_shared_memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attach(size_t size, Handle handle, bool managed) {
|
void Attach(size_t size, NativeHandle handle, bool managed) {
|
||||||
return AttachSharedMemory(std::addressof(m_shared_memory), size, handle, managed);
|
return AttachSharedMemory(std::addressof(m_shared_memory), size, handle, managed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace ams::os {
|
||||||
return GetSharedMemorySize(std::addressof(m_shared_memory));
|
return GetSharedMemorySize(std::addressof(m_shared_memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetHandle() const {
|
NativeHandle GetHandle() const {
|
||||||
return GetSharedMemoryHandle(std::addressof(m_shared_memory));
|
return GetSharedMemoryHandle(std::addressof(m_shared_memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/os_memory_permission.hpp>
|
#include <stratosphere/os/os_memory_permission.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ namespace ams::os {
|
||||||
|
|
||||||
Result CreateSharedMemory(SharedMemoryType *shared_memory, size_t size, MemoryPermission my_perm, MemoryPermission other_perm);
|
Result CreateSharedMemory(SharedMemoryType *shared_memory, size_t size, MemoryPermission my_perm, MemoryPermission other_perm);
|
||||||
|
|
||||||
void AttachSharedMemory(SharedMemoryType *shared_memory, size_t size, Handle handle, bool managed);
|
void AttachSharedMemory(SharedMemoryType *shared_memory, size_t size, NativeHandle handle, bool managed);
|
||||||
|
|
||||||
void DestroySharedMemory(SharedMemoryType *shared_memory);
|
void DestroySharedMemory(SharedMemoryType *shared_memory);
|
||||||
|
|
||||||
|
@ -33,6 +34,6 @@ namespace ams::os {
|
||||||
|
|
||||||
void *GetSharedMemoryAddress(const SharedMemoryType *shared_memory);
|
void *GetSharedMemoryAddress(const SharedMemoryType *shared_memory);
|
||||||
size_t GetSharedMemorySize(const SharedMemoryType *shared_memory);
|
size_t GetSharedMemorySize(const SharedMemoryType *shared_memory);
|
||||||
Handle GetSharedMemoryHandle(const SharedMemoryType *shared_memory);
|
NativeHandle GetSharedMemoryHandle(const SharedMemoryType *shared_memory);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/impl/os_internal_critical_section.hpp>
|
#include <stratosphere/os/impl/os_internal_critical_section.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ namespace ams::os {
|
||||||
|
|
||||||
void *address;
|
void *address;
|
||||||
size_t size;
|
size_t size;
|
||||||
Handle handle;
|
NativeHandle handle;
|
||||||
|
|
||||||
mutable impl::InternalCriticalSectionStorage cs_shared_memory;
|
mutable impl::InternalCriticalSectionStorage cs_shared_memory;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace ams::os {
|
||||||
R_ABORT_UNLESS(CreateSystemEvent(std::addressof(this->system_event), clear_mode, inter_process));
|
R_ABORT_UNLESS(CreateSystemEvent(std::addressof(this->system_event), clear_mode, inter_process));
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit SystemEvent(Handle read_handle, bool manage_read_handle, Handle write_handle, bool manage_write_handle, EventClearMode clear_mode) {
|
explicit SystemEvent(NativeHandle read_handle, bool manage_read_handle, NativeHandle write_handle, bool manage_write_handle, EventClearMode clear_mode) {
|
||||||
AttachSystemEvent(std::addressof(this->system_event), read_handle, manage_read_handle, write_handle, manage_write_handle, clear_mode);
|
AttachSystemEvent(std::addressof(this->system_event), read_handle, manage_read_handle, write_handle, manage_write_handle, clear_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,26 +46,26 @@ namespace ams::os {
|
||||||
DestroySystemEvent(std::addressof(this->system_event));
|
DestroySystemEvent(std::addressof(this->system_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attach(Handle read_handle, bool manage_read_handle, Handle write_handle, bool manage_write_handle, EventClearMode clear_mode) {
|
void Attach(NativeHandle read_handle, bool manage_read_handle, NativeHandle write_handle, bool manage_write_handle, EventClearMode clear_mode) {
|
||||||
AMS_ABORT_UNLESS(this->system_event.state == SystemEventType::State_NotInitialized);
|
AMS_ABORT_UNLESS(this->system_event.state == SystemEventType::State_NotInitialized);
|
||||||
return AttachSystemEvent(std::addressof(this->system_event), read_handle, manage_read_handle, write_handle, manage_write_handle, clear_mode);
|
return AttachSystemEvent(std::addressof(this->system_event), read_handle, manage_read_handle, write_handle, manage_write_handle, clear_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachReadableHandle(Handle read_handle, bool manage_read_handle, EventClearMode clear_mode) {
|
void AttachReadableHandle(NativeHandle read_handle, bool manage_read_handle, EventClearMode clear_mode) {
|
||||||
AMS_ABORT_UNLESS(this->system_event.state == SystemEventType::State_NotInitialized);
|
AMS_ABORT_UNLESS(this->system_event.state == SystemEventType::State_NotInitialized);
|
||||||
return AttachReadableHandleToSystemEvent(std::addressof(this->system_event), read_handle, manage_read_handle, clear_mode);
|
return AttachReadableHandleToSystemEvent(std::addressof(this->system_event), read_handle, manage_read_handle, clear_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachWritableHandle(Handle write_handle, bool manage_write_handle, EventClearMode clear_mode) {
|
void AttachWritableHandle(NativeHandle write_handle, bool manage_write_handle, EventClearMode clear_mode) {
|
||||||
AMS_ABORT_UNLESS(this->system_event.state == SystemEventType::State_NotInitialized);
|
AMS_ABORT_UNLESS(this->system_event.state == SystemEventType::State_NotInitialized);
|
||||||
return AttachWritableHandleToSystemEvent(std::addressof(this->system_event), write_handle, manage_write_handle, clear_mode);
|
return AttachWritableHandleToSystemEvent(std::addressof(this->system_event), write_handle, manage_write_handle, clear_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle DetachReadableHandle() {
|
NativeHandle DetachReadableHandle() {
|
||||||
return DetachReadableHandleOfSystemEvent(std::addressof(this->system_event));
|
return DetachReadableHandleOfSystemEvent(std::addressof(this->system_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle DetachWritableHandle() {
|
NativeHandle DetachWritableHandle() {
|
||||||
return DetachWritableHandleOfSystemEvent(std::addressof(this->system_event));
|
return DetachWritableHandleOfSystemEvent(std::addressof(this->system_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,11 +89,11 @@ namespace ams::os {
|
||||||
return ClearSystemEvent(std::addressof(this->system_event));
|
return ClearSystemEvent(std::addressof(this->system_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetReadableHandle() const {
|
NativeHandle GetReadableHandle() const {
|
||||||
return GetReadableHandleOfSystemEvent(std::addressof(this->system_event));
|
return GetReadableHandleOfSystemEvent(std::addressof(this->system_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetWritableHandle() const {
|
NativeHandle GetWritableHandle() const {
|
||||||
return GetWritableHandleOfSystemEvent(std::addressof(this->system_event));
|
return GetWritableHandleOfSystemEvent(std::addressof(this->system_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/os_event_common.hpp>
|
#include <stratosphere/os/os_event_common.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -26,15 +27,15 @@ namespace ams::os {
|
||||||
Result CreateSystemEvent(SystemEventType *event, EventClearMode clear_mode, bool inter_process);
|
Result CreateSystemEvent(SystemEventType *event, EventClearMode clear_mode, bool inter_process);
|
||||||
void DestroySystemEvent(SystemEventType *event);
|
void DestroySystemEvent(SystemEventType *event);
|
||||||
|
|
||||||
void AttachSystemEvent(SystemEventType *event, Handle read_handle, bool read_handle_managed, Handle write_handle, bool write_handle_managed, EventClearMode clear_mode);
|
void AttachSystemEvent(SystemEventType *event, NativeHandle read_handle, bool read_handle_managed, NativeHandle write_handle, bool write_handle_managed, EventClearMode clear_mode);
|
||||||
void AttachReadableHandleToSystemEvent(SystemEventType *event, Handle read_handle, bool manage_read_handle, EventClearMode clear_mode);
|
void AttachReadableHandleToSystemEvent(SystemEventType *event, NativeHandle read_handle, bool manage_read_handle, EventClearMode clear_mode);
|
||||||
void AttachWritableHandleToSystemEvent(SystemEventType *event, Handle write_handle, bool manage_write_handle, EventClearMode clear_mode);
|
void AttachWritableHandleToSystemEvent(SystemEventType *event, NativeHandle write_handle, bool manage_write_handle, EventClearMode clear_mode);
|
||||||
|
|
||||||
Handle DetachReadableHandleOfSystemEvent(SystemEventType *event);
|
NativeHandle DetachReadableHandleOfSystemEvent(SystemEventType *event);
|
||||||
Handle DetachWritableHandleOfSystemEvent(SystemEventType *event);
|
NativeHandle DetachWritableHandleOfSystemEvent(SystemEventType *event);
|
||||||
|
|
||||||
Handle GetReadableHandleOfSystemEvent(const SystemEventType *event);
|
NativeHandle GetReadableHandleOfSystemEvent(const SystemEventType *event);
|
||||||
Handle GetWritableHandleOfSystemEvent(const SystemEventType *event);
|
NativeHandle GetWritableHandleOfSystemEvent(const SystemEventType *event);
|
||||||
|
|
||||||
void SignalSystemEvent(SystemEventType *event);
|
void SignalSystemEvent(SystemEventType *event);
|
||||||
void WaitSystemEvent(SystemEventType *event);
|
void WaitSystemEvent(SystemEventType *event);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/os_event_types.hpp>
|
#include <stratosphere/os/os_event_types.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -34,8 +35,8 @@ namespace ams::os {
|
||||||
u8 state;
|
u8 state;
|
||||||
bool is_readable_handle_managed;
|
bool is_readable_handle_managed;
|
||||||
bool is_writable_handle_managed;
|
bool is_writable_handle_managed;
|
||||||
Handle readable_handle;
|
NativeHandle readable_handle;
|
||||||
Handle writable_handle;
|
NativeHandle writable_handle;
|
||||||
};
|
};
|
||||||
static_assert(std::is_trivial<InterProcessEventType>::value);
|
static_assert(std::is_trivial<InterProcessEventType>::value);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace ams::os {
|
||||||
R_ABORT_UNLESS(CreateTransferMemory(std::addressof(this->tmem), address, size, perm));
|
R_ABORT_UNLESS(CreateTransferMemory(std::addressof(this->tmem), address, size, perm));
|
||||||
}
|
}
|
||||||
|
|
||||||
TransferMemory(size_t size, Handle handle, bool managed) {
|
TransferMemory(size_t size, NativeHandle handle, bool managed) {
|
||||||
this->Attach(size, handle, managed);
|
this->Attach(size, handle, managed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +46,11 @@ namespace ams::os {
|
||||||
DestroyTransferMemory(std::addressof(this->tmem));
|
DestroyTransferMemory(std::addressof(this->tmem));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attach(size_t size, Handle handle, bool managed) {
|
void Attach(size_t size, NativeHandle handle, bool managed) {
|
||||||
AttachTransferMemory(std::addressof(this->tmem), size, handle, managed);
|
AttachTransferMemory(std::addressof(this->tmem), size, handle, managed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle Detach() {
|
NativeHandle Detach() {
|
||||||
return DetachTransferMemory(std::addressof(this->tmem));
|
return DetachTransferMemory(std::addressof(this->tmem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/os_memory_permission.hpp>
|
#include <stratosphere/os/os_memory_permission.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -24,8 +25,8 @@ namespace ams::os {
|
||||||
|
|
||||||
Result CreateTransferMemory(TransferMemoryType *tmem, void *address, size_t size, MemoryPermission perm);
|
Result CreateTransferMemory(TransferMemoryType *tmem, void *address, size_t size, MemoryPermission perm);
|
||||||
|
|
||||||
void AttachTransferMemory(TransferMemoryType *tmem, size_t size, Handle handle, bool managed);
|
void AttachTransferMemory(TransferMemoryType *tmem, size_t size, NativeHandle handle, bool managed);
|
||||||
Handle DetachTransferMemory(TransferMemoryType *tmem);
|
NativeHandle DetachTransferMemory(TransferMemoryType *tmem);
|
||||||
|
|
||||||
void DestroyTransferMemory(TransferMemoryType *tmem);
|
void DestroyTransferMemory(TransferMemoryType *tmem);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <stratosphere/os/impl/os_internal_critical_section.hpp>
|
#include <stratosphere/os/impl/os_internal_critical_section.hpp>
|
||||||
|
#include <stratosphere/os/os_native_handle.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
namespace ams::os {
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ namespace ams::os {
|
||||||
|
|
||||||
void *address;
|
void *address;
|
||||||
size_t size;
|
size_t size;
|
||||||
Handle handle;
|
NativeHandle handle;
|
||||||
|
|
||||||
mutable impl::InternalCriticalSectionStorage cs_transfer_memory;
|
mutable impl::InternalCriticalSectionStorage cs_transfer_memory;
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace ams::fssystem {
|
||||||
constexpr inline size_t MaxExternalCodeFileSystem = 0x10;
|
constexpr inline size_t MaxExternalCodeFileSystem = 0x10;
|
||||||
|
|
||||||
util::BoundedMap<ncm::ProgramId, fs::RemoteFileSystem, MaxExternalCodeFileSystem> g_ecs_map;
|
util::BoundedMap<ncm::ProgramId, fs::RemoteFileSystem, MaxExternalCodeFileSystem> g_ecs_map;
|
||||||
util::BoundedMap<ncm::ProgramId, os::ManagedHandle, MaxExternalCodeFileSystem> g_hnd_map;
|
util::BoundedMap<ncm::ProgramId, os::NativeHandle, MaxExternalCodeFileSystem> g_hnd_map;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace ams::fssystem {
|
||||||
if (auto *hnd = g_hnd_map.Find(program_id); hnd != nullptr) {
|
if (auto *hnd = g_hnd_map.Find(program_id); hnd != nullptr) {
|
||||||
/* Create a service using libnx bindings. */
|
/* Create a service using libnx bindings. */
|
||||||
Service srv;
|
Service srv;
|
||||||
serviceCreate(std::addressof(srv), hnd->Move());
|
serviceCreate(std::addressof(srv), *hnd);
|
||||||
g_hnd_map.Remove(program_id);
|
g_hnd_map.Remove(program_id);
|
||||||
|
|
||||||
/* Create a remote filesystem. */
|
/* Create a remote filesystem. */
|
||||||
|
@ -66,7 +66,11 @@ namespace ams::fssystem {
|
||||||
|
|
||||||
void DestroyExternalCode(ncm::ProgramId program_id) {
|
void DestroyExternalCode(ncm::ProgramId program_id) {
|
||||||
g_ecs_map.Remove(program_id);
|
g_ecs_map.Remove(program_id);
|
||||||
g_hnd_map.Remove(program_id);
|
|
||||||
|
if (auto *hnd = g_hnd_map.Find(program_id); hnd != nullptr) {
|
||||||
|
os::CloseNativeHandle(*hnd);
|
||||||
|
g_hnd_map.Remove(program_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
inline void SetupInterProcessEventType(InterProcessEventType *event, Handle read_handle, bool read_handle_managed, Handle write_handle, bool write_handle_managed, EventClearMode clear_mode) {
|
inline void SetupInterProcessEventType(InterProcessEventType *event, NativeHandle read_handle, bool read_handle_managed, NativeHandle write_handle, bool write_handle_managed, EventClearMode clear_mode) {
|
||||||
/* Set handles. */
|
/* Set handles. */
|
||||||
event->readable_handle = read_handle;
|
event->readable_handle = read_handle;
|
||||||
event->is_readable_handle_managed = read_handle_managed;
|
event->is_readable_handle_managed = read_handle_managed;
|
||||||
|
@ -42,7 +42,7 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateInterProcessEvent(InterProcessEventType *event, EventClearMode clear_mode) {
|
Result CreateInterProcessEvent(InterProcessEventType *event, EventClearMode clear_mode) {
|
||||||
Handle rh, wh;
|
NativeHandle rh, wh;
|
||||||
R_TRY(impl::InterProcessEventImpl::Create(std::addressof(wh), std::addressof(rh)));
|
R_TRY(impl::InterProcessEventImpl::Create(std::addressof(wh), std::addressof(rh)));
|
||||||
|
|
||||||
SetupInterProcessEventType(event, rh, true, wh, true, clear_mode);
|
SetupInterProcessEventType(event, rh, true, wh, true, clear_mode);
|
||||||
|
@ -57,14 +57,14 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
/* Close handles if required. */
|
/* Close handles if required. */
|
||||||
if (event->is_readable_handle_managed) {
|
if (event->is_readable_handle_managed) {
|
||||||
if (event->readable_handle != svc::InvalidHandle) {
|
if (event->readable_handle != os::InvalidNativeHandle) {
|
||||||
impl::InterProcessEventImpl::Close(event->readable_handle);
|
impl::InterProcessEventImpl::Close(event->readable_handle);
|
||||||
}
|
}
|
||||||
event->is_readable_handle_managed = false;
|
event->is_readable_handle_managed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->is_writable_handle_managed) {
|
if (event->is_writable_handle_managed) {
|
||||||
if (event->writable_handle != svc::InvalidHandle) {
|
if (event->writable_handle != os::InvalidNativeHandle) {
|
||||||
impl::InterProcessEventImpl::Close(event->writable_handle);
|
impl::InterProcessEventImpl::Close(event->writable_handle);
|
||||||
}
|
}
|
||||||
event->is_writable_handle_managed = false;
|
event->is_writable_handle_managed = false;
|
||||||
|
@ -74,28 +74,29 @@ namespace ams::os::impl {
|
||||||
util::DestroyAt(event->multi_wait_object_list_storage);
|
util::DestroyAt(event->multi_wait_object_list_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachInterProcessEvent(InterProcessEventType *event, Handle read_handle, bool read_handle_managed, Handle write_handle, bool write_handle_managed, EventClearMode clear_mode) {
|
void AttachInterProcessEvent(InterProcessEventType *event, NativeHandle read_handle, bool read_handle_managed, NativeHandle write_handle, bool write_handle_managed, EventClearMode clear_mode) {
|
||||||
AMS_ASSERT(read_handle != svc::InvalidHandle || write_handle != svc::InvalidHandle);
|
AMS_ASSERT(read_handle != os::InvalidNativeHandle || write_handle != os::InvalidNativeHandle);
|
||||||
|
|
||||||
return SetupInterProcessEventType(event, read_handle, read_handle_managed, write_handle, write_handle_managed, clear_mode);
|
return SetupInterProcessEventType(event, read_handle, read_handle_managed, write_handle, write_handle_managed, clear_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle DetachReadableHandleOfInterProcessEvent(InterProcessEventType *event) {
|
NativeHandle DetachReadableHandleOfInterProcessEvent(InterProcessEventType *event) {
|
||||||
AMS_ASSERT(event->state == InterProcessEventType::State_Initialized);
|
AMS_ASSERT(event->state == InterProcessEventType::State_Initialized);
|
||||||
|
|
||||||
const Handle handle = event->readable_handle;
|
const NativeHandle handle = event->readable_handle;
|
||||||
|
|
||||||
event->readable_handle = svc::InvalidHandle;
|
event->readable_handle = os::InvalidNativeHandle;
|
||||||
event->is_readable_handle_managed = false;
|
event->is_readable_handle_managed = false;
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
Handle DetachWritableHandleOfInterProcessEvent(InterProcessEventType *event) {
|
|
||||||
|
NativeHandle DetachWritableHandleOfInterProcessEvent(InterProcessEventType *event) {
|
||||||
AMS_ASSERT(event->state == InterProcessEventType::State_Initialized);
|
AMS_ASSERT(event->state == InterProcessEventType::State_Initialized);
|
||||||
|
|
||||||
const Handle handle = event->writable_handle;
|
const NativeHandle handle = event->writable_handle;
|
||||||
|
|
||||||
event->writable_handle = svc::InvalidHandle;
|
event->writable_handle = os::InvalidNativeHandle;
|
||||||
event->is_writable_handle_managed = false;
|
event->is_writable_handle_managed = false;
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
|
@ -130,19 +131,19 @@ namespace ams::os::impl {
|
||||||
AMS_ASSERT(event->state != InterProcessEventType::State_NotInitialized);
|
AMS_ASSERT(event->state != InterProcessEventType::State_NotInitialized);
|
||||||
|
|
||||||
auto handle = event->readable_handle;
|
auto handle = event->readable_handle;
|
||||||
if (handle == svc::InvalidHandle) {
|
if (handle == os::InvalidNativeHandle) {
|
||||||
handle = event->writable_handle;
|
handle = event->writable_handle;
|
||||||
}
|
}
|
||||||
return impl::InterProcessEventImpl::Clear(handle);
|
return impl::InterProcessEventImpl::Clear(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetReadableHandleOfInterProcessEvent(const InterProcessEventType *event) {
|
NativeHandle GetReadableHandleOfInterProcessEvent(const InterProcessEventType *event) {
|
||||||
AMS_ASSERT(event->state != InterProcessEventType::State_NotInitialized);
|
AMS_ASSERT(event->state != InterProcessEventType::State_NotInitialized);
|
||||||
|
|
||||||
return event->readable_handle;
|
return event->readable_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetWritableHandleOfInterProcessEvent(const InterProcessEventType *event) {
|
NativeHandle GetWritableHandleOfInterProcessEvent(const InterProcessEventType *event) {
|
||||||
AMS_ASSERT(event->state != InterProcessEventType::State_NotInitialized);
|
AMS_ASSERT(event->state != InterProcessEventType::State_NotInitialized);
|
||||||
|
|
||||||
return event->writable_handle;
|
return event->writable_handle;
|
||||||
|
|
|
@ -21,10 +21,10 @@ namespace ams::os::impl {
|
||||||
Result CreateInterProcessEvent(InterProcessEventType *event, EventClearMode clear_mode);
|
Result CreateInterProcessEvent(InterProcessEventType *event, EventClearMode clear_mode);
|
||||||
void DestroyInterProcessEvent(InterProcessEventType *event);
|
void DestroyInterProcessEvent(InterProcessEventType *event);
|
||||||
|
|
||||||
void AttachInterProcessEvent(InterProcessEventType *event, Handle read_handle, bool read_handle_managed, Handle write_handle, bool write_handle_managed, EventClearMode clear_mode);
|
void AttachInterProcessEvent(InterProcessEventType *event, NativeHandle read_handle, bool read_handle_managed, NativeHandle write_handle, bool write_handle_managed, EventClearMode clear_mode);
|
||||||
|
|
||||||
Handle DetachReadableHandleOfInterProcessEvent(InterProcessEventType *event);
|
NativeHandle DetachReadableHandleOfInterProcessEvent(InterProcessEventType *event);
|
||||||
Handle DetachWritableHandleOfInterProcessEvent(InterProcessEventType *event);
|
NativeHandle DetachWritableHandleOfInterProcessEvent(InterProcessEventType *event);
|
||||||
|
|
||||||
void WaitInterProcessEvent(InterProcessEventType *event);
|
void WaitInterProcessEvent(InterProcessEventType *event);
|
||||||
bool TryWaitInterProcessEvent(InterProcessEventType *event);
|
bool TryWaitInterProcessEvent(InterProcessEventType *event);
|
||||||
|
@ -33,8 +33,8 @@ namespace ams::os::impl {
|
||||||
void SignalInterProcessEvent(InterProcessEventType *event);
|
void SignalInterProcessEvent(InterProcessEventType *event);
|
||||||
void ClearInterProcessEvent(InterProcessEventType *event);
|
void ClearInterProcessEvent(InterProcessEventType *event);
|
||||||
|
|
||||||
Handle GetReadableHandleOfInterProcessEvent(const InterProcessEventType *event);
|
NativeHandle GetReadableHandleOfInterProcessEvent(const InterProcessEventType *event);
|
||||||
Handle GetWritableHandleOfInterProcessEvent(const InterProcessEventType *event);
|
NativeHandle GetWritableHandleOfInterProcessEvent(const InterProcessEventType *event);
|
||||||
|
|
||||||
void InitializeMultiWaitHolder(MultiWaitHolderType *multi_wait_holder, InterProcessEventType *event);
|
void InitializeMultiWaitHolder(MultiWaitHolderType *multi_wait_holder, InterProcessEventType *event);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
namespace ams::os::impl {
|
namespace ams::os::impl {
|
||||||
|
|
||||||
Result InterProcessEventImpl::Create(Handle *out_write, Handle *out_read) {
|
Result InterProcessEventImpl::Create(NativeHandle *out_write, NativeHandle *out_read) {
|
||||||
/* Create the event handles. */
|
/* Create the event handles. */
|
||||||
svc::Handle wh, rh;
|
svc::Handle wh, rh;
|
||||||
R_TRY_CATCH(svc::CreateEvent(std::addressof(wh), std::addressof(rh))) {
|
R_TRY_CATCH(svc::CreateEvent(std::addressof(wh), std::addressof(rh))) {
|
||||||
|
@ -32,29 +32,29 @@ namespace ams::os::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterProcessEventImpl::Close(Handle handle) {
|
void InterProcessEventImpl::Close(NativeHandle handle) {
|
||||||
if (handle != svc::InvalidHandle) {
|
if (handle != os::InvalidNativeHandle) {
|
||||||
R_ABORT_UNLESS(svc::CloseHandle(svc::Handle(handle)));
|
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterProcessEventImpl::Signal(Handle handle) {
|
void InterProcessEventImpl::Signal(NativeHandle handle) {
|
||||||
R_ABORT_UNLESS(svc::SignalEvent(svc::Handle(handle)));
|
R_ABORT_UNLESS(svc::SignalEvent(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterProcessEventImpl::Clear(Handle handle) {
|
void InterProcessEventImpl::Clear(NativeHandle handle) {
|
||||||
R_ABORT_UNLESS(svc::ClearEvent(svc::Handle(handle)));
|
R_ABORT_UNLESS(svc::ClearEvent(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterProcessEventImpl::Wait(Handle handle, bool auto_clear) {
|
void InterProcessEventImpl::Wait(NativeHandle handle, bool auto_clear) {
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Continuously wait, until success. */
|
/* Continuously wait, until success. */
|
||||||
s32 index;
|
s32 index;
|
||||||
Result res = svc::WaitSynchronization(std::addressof(index), reinterpret_cast<svc::Handle *>(std::addressof(handle)), 1, svc::WaitInfinite);
|
Result res = svc::WaitSynchronization(std::addressof(index), static_cast<svc::Handle *>(std::addressof(handle)), 1, svc::WaitInfinite);
|
||||||
if (R_SUCCEEDED(res)) {
|
if (R_SUCCEEDED(res)) {
|
||||||
/* Clear, if we must. */
|
/* Clear, if we must. */
|
||||||
if (auto_clear) {
|
if (auto_clear) {
|
||||||
R_TRY_CATCH(svc::ResetSignal(svc::Handle(handle))) {
|
R_TRY_CATCH(svc::ResetSignal(handle)) {
|
||||||
/* Some other thread might have caught this before we did. */
|
/* Some other thread might have caught this before we did. */
|
||||||
R_CATCH(svc::ResultInvalidState) { continue; }
|
R_CATCH(svc::ResultInvalidState) { continue; }
|
||||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||||
|
@ -67,17 +67,17 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InterProcessEventImpl::TryWait(Handle handle, bool auto_clear) {
|
bool InterProcessEventImpl::TryWait(NativeHandle handle, bool auto_clear) {
|
||||||
/* If we're auto clear, just try to reset. */
|
/* If we're auto clear, just try to reset. */
|
||||||
if (auto_clear) {
|
if (auto_clear) {
|
||||||
return R_SUCCEEDED(svc::ResetSignal(svc::Handle(handle)));
|
return R_SUCCEEDED(svc::ResetSignal(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not auto-clear. */
|
/* Not auto-clear. */
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Continuously wait, until success or timeout. */
|
/* Continuously wait, until success or timeout. */
|
||||||
s32 index;
|
s32 index;
|
||||||
Result res = svc::WaitSynchronization(std::addressof(index), reinterpret_cast<svc::Handle *>(std::addressof(handle)), 1, 0);
|
Result res = svc::WaitSynchronization(std::addressof(index), static_cast<svc::Handle *>(std::addressof(handle)), 1, 0);
|
||||||
|
|
||||||
/* If we succeeded, we're signaled. */
|
/* If we succeeded, we're signaled. */
|
||||||
if (R_SUCCEEDED(res)) {
|
if (R_SUCCEEDED(res)) {
|
||||||
|
@ -93,17 +93,17 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InterProcessEventImpl::TimedWait(Handle handle, bool auto_clear, TimeSpan timeout) {
|
bool InterProcessEventImpl::TimedWait(NativeHandle handle, bool auto_clear, TimeSpan timeout) {
|
||||||
TimeoutHelper timeout_helper(timeout);
|
TimeoutHelper timeout_helper(timeout);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Continuously wait, until success. */
|
/* Continuously wait, until success. */
|
||||||
s32 index;
|
s32 index;
|
||||||
Result res = svc::WaitSynchronization(std::addressof(index), reinterpret_cast<svc::Handle *>(std::addressof(handle)), 1, timeout_helper.GetTimeLeftOnTarget().GetNanoSeconds());
|
Result res = svc::WaitSynchronization(std::addressof(index), static_cast<svc::Handle *>(std::addressof(handle)), 1, timeout_helper.GetTimeLeftOnTarget().GetNanoSeconds());
|
||||||
if (R_SUCCEEDED(res)) {
|
if (R_SUCCEEDED(res)) {
|
||||||
/* Clear, if we must. */
|
/* Clear, if we must. */
|
||||||
if (auto_clear) {
|
if (auto_clear) {
|
||||||
R_TRY_CATCH(svc::ResetSignal(svc::Handle(handle))) {
|
R_TRY_CATCH(svc::ResetSignal(handle)) {
|
||||||
/* Some other thread might have caught this before we did. */
|
/* Some other thread might have caught this before we did. */
|
||||||
R_CATCH(svc::ResultInvalidState) { continue; }
|
R_CATCH(svc::ResultInvalidState) { continue; }
|
||||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||||
|
|
|
@ -20,13 +20,13 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
class InterProcessEventImpl {
|
class InterProcessEventImpl {
|
||||||
public:
|
public:
|
||||||
static Result Create(Handle *out_write, Handle *out_read);
|
static Result Create(NativeHandle *out_write, NativeHandle *out_read);
|
||||||
static void Close(Handle handle);
|
static void Close(NativeHandle handle);
|
||||||
static void Signal(Handle handle);
|
static void Signal(NativeHandle handle);
|
||||||
static void Clear(Handle handle);
|
static void Clear(NativeHandle handle);
|
||||||
static void Wait(Handle handle, bool auto_clear);
|
static void Wait(NativeHandle handle, bool auto_clear);
|
||||||
static bool TryWait(Handle handle, bool auto_clear);
|
static bool TryWait(NativeHandle handle, bool auto_clear);
|
||||||
static bool TimedWait(Handle handle, bool auto_clear, TimeSpan timeout);
|
static bool TimedWait(NativeHandle handle, bool auto_clear, TimeSpan timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -50,7 +50,7 @@ namespace ams::os::impl {
|
||||||
return this->impl.IsSignaled();
|
return this->impl.IsSignaled();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetHandle() const {
|
NativeHandle GetHandle() const {
|
||||||
return this->impl.GetHandle();
|
return this->impl.GetHandle();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace ams::os::impl {
|
||||||
return TriBool::Undefined;
|
return TriBool::Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetHandle() const {
|
NativeHandle GetHandle() const {
|
||||||
return this->handle;
|
return this->handle;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,10 +20,10 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
class IoRegionImpl {
|
class IoRegionImpl {
|
||||||
public:
|
public:
|
||||||
static Result CreateIoRegion(Handle *out, Handle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission);
|
static Result CreateIoRegion(NativeHandle *out, NativeHandle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission);
|
||||||
|
|
||||||
static Result MapIoRegion(void **out, Handle handle, size_t size, MemoryPermission perm);
|
static Result MapIoRegion(void **out, NativeHandle handle, size_t size, MemoryPermission perm);
|
||||||
static void UnmapIoRegion(Handle handle, void *address, size_t size);
|
static void UnmapIoRegion(NativeHandle handle, void *address, size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,7 +39,7 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IoRegionImpl::CreateIoRegion(Handle *out, Handle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission) {
|
Result IoRegionImpl::CreateIoRegion(NativeHandle *out, NativeHandle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission) {
|
||||||
/* Convert mapping/permission. */
|
/* Convert mapping/permission. */
|
||||||
const auto svc_mapping = ConvertToSvcMemoryMapping(mapping);
|
const auto svc_mapping = ConvertToSvcMemoryMapping(mapping);
|
||||||
const auto svc_perm = ConvertToSvcMemoryPermission(permission);
|
const auto svc_perm = ConvertToSvcMemoryPermission(permission);
|
||||||
|
@ -53,7 +53,7 @@ namespace ams::os::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IoRegionImpl::MapIoRegion(void **out, Handle handle, size_t size, MemoryPermission perm) {
|
Result IoRegionImpl::MapIoRegion(void **out, NativeHandle handle, size_t size, MemoryPermission perm) {
|
||||||
/* Convert permission. */
|
/* Convert permission. */
|
||||||
const auto svc_perm = ConvertToSvcMemoryPermission(perm);
|
const auto svc_perm = ConvertToSvcMemoryPermission(perm);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace ams::os::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IoRegionImpl::UnmapIoRegion(Handle handle, void *address, size_t size) {
|
void IoRegionImpl::UnmapIoRegion(NativeHandle handle, void *address, size_t size) {
|
||||||
R_ABORT_UNLESS(svc::UnmapIoRegion(handle, reinterpret_cast<uintptr_t>(address), size));
|
R_ABORT_UNLESS(svc::UnmapIoRegion(handle, reinterpret_cast<uintptr_t>(address), size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ namespace ams::os::impl {
|
||||||
virtual TriBool LinkToObjectList() = 0;
|
virtual TriBool LinkToObjectList() = 0;
|
||||||
/* Removes from the multi wait's object list. */
|
/* Removes from the multi wait's object list. */
|
||||||
virtual void UnlinkFromObjectList() = 0;
|
virtual void UnlinkFromObjectList() = 0;
|
||||||
/* Gets handle to output, returns INVALID_HANDLE on failure. */
|
/* Gets handle to output, returns os::InvalidNativeHandle on failure. */
|
||||||
virtual Handle GetHandle() const = 0;
|
virtual NativeHandle GetHandle() const = 0;
|
||||||
/* Gets the amount of time remaining until this wakes up. */
|
/* Gets the amount of time remaining until this wakes up. */
|
||||||
virtual TimeSpan GetAbsoluteWakeupTime() const {
|
virtual TimeSpan GetAbsoluteWakeupTime() const {
|
||||||
return TimeSpan::FromNanoSeconds(std::numeric_limits<s64>::max());
|
return TimeSpan::FromNanoSeconds(std::numeric_limits<s64>::max());
|
||||||
|
@ -58,8 +58,8 @@ namespace ams::os::impl {
|
||||||
class MultiWaitHolderOfUserObject : public MultiWaitHolderBase {
|
class MultiWaitHolderOfUserObject : public MultiWaitHolderBase {
|
||||||
public:
|
public:
|
||||||
/* All user objects have no handle to wait on. */
|
/* All user objects have no handle to wait on. */
|
||||||
virtual Handle GetHandle() const override final {
|
virtual NativeHandle GetHandle() const override final {
|
||||||
return svc::InvalidHandle;
|
return os::InvalidNativeHandle;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,16 +20,16 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
class MultiWaitHolderOfHandle : public MultiWaitHolderOfKernelObject {
|
class MultiWaitHolderOfHandle : public MultiWaitHolderOfKernelObject {
|
||||||
private:
|
private:
|
||||||
Handle handle;
|
NativeHandle handle;
|
||||||
public:
|
public:
|
||||||
explicit MultiWaitHolderOfHandle(Handle h) : handle(h) { /* ... */ }
|
explicit MultiWaitHolderOfHandle(NativeHandle h) : handle(h) { /* ... */ }
|
||||||
|
|
||||||
/* IsSignaled, GetHandle both implemented. */
|
/* IsSignaled, GetHandle both implemented. */
|
||||||
virtual TriBool IsSignaled() const override {
|
virtual TriBool IsSignaled() const override {
|
||||||
return TriBool::Undefined;
|
return TriBool::Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Handle GetHandle() const override {
|
virtual NativeHandle GetHandle() const override {
|
||||||
return this->handle;
|
return this->handle;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace ams::os::impl {
|
||||||
return TriBool::Undefined;
|
return TriBool::Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Handle GetHandle() const override {
|
virtual NativeHandle GetHandle() const override {
|
||||||
return this->event->readable_handle;
|
return this->event->readable_handle;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
namespace ams::os::impl {
|
namespace ams::os::impl {
|
||||||
|
|
||||||
Handle MultiWaitHolderOfInterruptEvent::GetHandle() const {
|
NativeHandle MultiWaitHolderOfInterruptEvent::GetHandle() const {
|
||||||
return GetReference(event->impl).GetHandle();
|
return GetReference(event->impl).GetHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace ams::os::impl {
|
||||||
return TriBool::Undefined;
|
return TriBool::Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Handle GetHandle() const override;
|
virtual NativeHandle GetHandle() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
namespace ams::os::impl {
|
namespace ams::os::impl {
|
||||||
|
|
||||||
Result MultiWaitImpl::WaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target) {
|
Result MultiWaitImpl::WaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, NativeHandle reply_target) {
|
||||||
/* Prepare for processing. */
|
/* Prepare for processing. */
|
||||||
this->signaled_holder = nullptr;
|
this->signaled_holder = nullptr;
|
||||||
this->target_impl.SetCurrentThreadHandleForCancelWait();
|
this->target_impl.SetCurrentThreadHandleForCancelWait();
|
||||||
|
@ -37,7 +37,7 @@ namespace ams::os::impl {
|
||||||
/* Process object array. */
|
/* Process object array. */
|
||||||
Result wait_result = ResultSuccess();
|
Result wait_result = ResultSuccess();
|
||||||
if (holder != nullptr) {
|
if (holder != nullptr) {
|
||||||
if (reply && reply_target != svc::InvalidHandle) {
|
if (reply && reply_target != os::InvalidNativeHandle) {
|
||||||
s32 index;
|
s32 index;
|
||||||
wait_result = this->target_impl.TimedReplyAndReceive(std::addressof(index), nullptr, 0, 0, reply_target, TimeSpan::FromNanoSeconds(0));
|
wait_result = this->target_impl.TimedReplyAndReceive(std::addressof(index), nullptr, 0, 0, reply_target, TimeSpan::FromNanoSeconds(0));
|
||||||
if (R_FAILED(wait_result)) {
|
if (R_FAILED(wait_result)) {
|
||||||
|
@ -59,8 +59,8 @@ namespace ams::os::impl {
|
||||||
return wait_result;
|
return wait_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MultiWaitImpl::WaitAnyHandleImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target) {
|
Result MultiWaitImpl::WaitAnyHandleImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, NativeHandle reply_target) {
|
||||||
Handle object_handles[MaximumHandleCount];
|
NativeHandle object_handles[MaximumHandleCount];
|
||||||
MultiWaitHolderBase *objects[MaximumHandleCount];
|
MultiWaitHolderBase *objects[MaximumHandleCount];
|
||||||
|
|
||||||
const s32 count = this->BuildHandleArray(object_handles, objects, MaximumHandleCount);
|
const s32 count = this->BuildHandleArray(object_handles, objects, MaximumHandleCount);
|
||||||
|
@ -132,15 +132,15 @@ namespace ams::os::impl {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_target = svc::InvalidHandle;
|
reply_target = os::InvalidNativeHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 MultiWaitImpl::BuildHandleArray(Handle out_handles[], MultiWaitHolderBase *out_objects[], s32 num) {
|
s32 MultiWaitImpl::BuildHandleArray(NativeHandle out_handles[], MultiWaitHolderBase *out_objects[], s32 num) {
|
||||||
s32 count = 0;
|
s32 count = 0;
|
||||||
|
|
||||||
for (MultiWaitHolderBase &holder_base : this->multi_wait_list) {
|
for (MultiWaitHolderBase &holder_base : this->multi_wait_list) {
|
||||||
if (Handle handle = holder_base.GetHandle(); handle != svc::InvalidHandle) {
|
if (auto handle = holder_base.GetHandle(); handle != os::InvalidNativeHandle) {
|
||||||
AMS_ASSERT(count < num);
|
AMS_ASSERT(count < num);
|
||||||
|
|
||||||
out_handles[count] = handle;
|
out_handles[count] = handle;
|
||||||
|
|
|
@ -38,9 +38,9 @@ namespace ams::os::impl {
|
||||||
InternalCriticalSection cs_wait;
|
InternalCriticalSection cs_wait;
|
||||||
MultiWaitTargetImpl target_impl;
|
MultiWaitTargetImpl target_impl;
|
||||||
private:
|
private:
|
||||||
Result WaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target);
|
Result WaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, NativeHandle reply_target);
|
||||||
Result WaitAnyHandleImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target);
|
Result WaitAnyHandleImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, NativeHandle reply_target);
|
||||||
s32 BuildHandleArray(Handle out_handles[], MultiWaitHolderBase *out_objects[], s32 num);
|
s32 BuildHandleArray(NativeHandle out_handles[], MultiWaitHolderBase *out_objects[], s32 num);
|
||||||
|
|
||||||
MultiWaitHolderBase *LinkHoldersToObjectList();
|
MultiWaitHolderBase *LinkHoldersToObjectList();
|
||||||
void UnlinkHoldersFromObjectList();
|
void UnlinkHoldersFromObjectList();
|
||||||
|
@ -50,7 +50,7 @@ namespace ams::os::impl {
|
||||||
MultiWaitHolderBase *WaitAnyImpl(bool infinite, TimeSpan timeout) {
|
MultiWaitHolderBase *WaitAnyImpl(bool infinite, TimeSpan timeout) {
|
||||||
MultiWaitHolderBase *holder = nullptr;
|
MultiWaitHolderBase *holder = nullptr;
|
||||||
|
|
||||||
const Result wait_result = this->WaitAnyImpl(std::addressof(holder), infinite, timeout, false, svc::InvalidHandle);
|
const Result wait_result = this->WaitAnyImpl(std::addressof(holder), infinite, timeout, false, os::InvalidNativeHandle);
|
||||||
R_ASSERT(wait_result);
|
R_ASSERT(wait_result);
|
||||||
AMS_UNUSED(wait_result);
|
AMS_UNUSED(wait_result);
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ namespace ams::os::impl {
|
||||||
return this->WaitAnyImpl(false, ts);
|
return this->WaitAnyImpl(false, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReplyAndReceive(MultiWaitHolderBase **out, Handle reply_target) {
|
Result ReplyAndReceive(MultiWaitHolderBase **out, NativeHandle reply_target) {
|
||||||
return this->WaitAnyImpl(out, true, TimeSpan::FromNanoSeconds(std::numeric_limits<s64>::max()), true, reply_target);
|
return this->WaitAnyImpl(out, true, TimeSpan::FromNanoSeconds(std::numeric_limits<s64>::max()), true, reply_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
namespace ams::os::impl {
|
namespace ams::os::impl {
|
||||||
|
|
||||||
Result MultiWaitHorizonImpl::WaitSynchronizationN(s32 *out_index, s32 num, Handle arr[], s32 array_size, s64 ns) {
|
Result MultiWaitHorizonImpl::WaitSynchronizationN(s32 *out_index, s32 num, NativeHandle arr[], s32 array_size, s64 ns) {
|
||||||
AMS_ASSERT(!(num == 0 && ns == 0));
|
AMS_ASSERT(!(num == 0 && ns == 0));
|
||||||
s32 index = MultiWaitImpl::WaitInvalid;
|
s32 index = MultiWaitImpl::WaitInvalid;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace ams::os::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MultiWaitHorizonImpl::ReplyAndReceiveN(s32 *out_index, s32 num, Handle arr[], s32 array_size, s64 ns, Handle reply_target) {
|
Result MultiWaitHorizonImpl::ReplyAndReceiveN(s32 *out_index, s32 num, NativeHandle arr[], s32 array_size, s64 ns, NativeHandle reply_target) {
|
||||||
/* NOTE: Nintendo does not initialize this value, which seems like it can cause incorrect behavior. */
|
/* NOTE: Nintendo does not initialize this value, which seems like it can cause incorrect behavior. */
|
||||||
s32 index = MultiWaitImpl::WaitInvalid;
|
s32 index = MultiWaitImpl::WaitInvalid;
|
||||||
static_assert(MultiWaitImpl::WaitInvalid != -1);
|
static_assert(MultiWaitImpl::WaitInvalid != -1);
|
||||||
|
|
|
@ -23,22 +23,22 @@ namespace ams::os::impl {
|
||||||
public:
|
public:
|
||||||
static constexpr size_t MaximumHandleCount = static_cast<size_t>(ams::svc::ArgumentHandleCountMax);
|
static constexpr size_t MaximumHandleCount = static_cast<size_t>(ams::svc::ArgumentHandleCountMax);
|
||||||
private:
|
private:
|
||||||
Handle handle;
|
NativeHandle handle;
|
||||||
private:
|
private:
|
||||||
Result WaitSynchronizationN(s32 *out_index, s32 num, Handle arr[], s32 array_size, s64 ns);
|
Result WaitSynchronizationN(s32 *out_index, s32 num, NativeHandle arr[], s32 array_size, s64 ns);
|
||||||
Result ReplyAndReceiveN(s32 *out_index, s32 num, Handle arr[], s32 array_size, s64 ns, Handle reply_target);
|
Result ReplyAndReceiveN(s32 *out_index, s32 num, NativeHandle arr[], s32 array_size, s64 ns, NativeHandle reply_target);
|
||||||
public:
|
public:
|
||||||
void CancelWait();
|
void CancelWait();
|
||||||
|
|
||||||
Result WaitAny(s32 *out_index, Handle arr[], s32 array_size, s32 num) {
|
Result WaitAny(s32 *out_index, NativeHandle arr[], s32 array_size, s32 num) {
|
||||||
return this->WaitSynchronizationN(out_index, num, arr, array_size, svc::WaitInfinite);
|
return this->WaitSynchronizationN(out_index, num, arr, array_size, svc::WaitInfinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result TryWaitAny(s32 *out_index, Handle arr[], s32 array_size, s32 num) {
|
Result TryWaitAny(s32 *out_index, NativeHandle arr[], s32 array_size, s32 num) {
|
||||||
return this->WaitSynchronizationN(out_index, num, arr, array_size, 0);
|
return this->WaitSynchronizationN(out_index, num, arr, array_size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result TimedWaitAny(s32 *out_index, Handle arr[], s32 array_size, s32 num, TimeSpan ts) {
|
Result TimedWaitAny(s32 *out_index, NativeHandle arr[], s32 array_size, s32 num, TimeSpan ts) {
|
||||||
s64 timeout = ts.GetNanoSeconds();
|
s64 timeout = ts.GetNanoSeconds();
|
||||||
if (timeout < 0) {
|
if (timeout < 0) {
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
|
@ -46,11 +46,11 @@ namespace ams::os::impl {
|
||||||
return this->WaitSynchronizationN(out_index, num, arr, array_size, timeout);
|
return this->WaitSynchronizationN(out_index, num, arr, array_size, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReplyAndReceive(s32 *out_index, Handle arr[], s32 array_size, s32 num, Handle reply_target) {
|
Result ReplyAndReceive(s32 *out_index, NativeHandle arr[], s32 array_size, s32 num, NativeHandle reply_target) {
|
||||||
return this->ReplyAndReceiveN(out_index, num, arr, array_size, std::numeric_limits<s64>::max(), reply_target);
|
return this->ReplyAndReceiveN(out_index, num, arr, array_size, std::numeric_limits<s64>::max(), reply_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result TimedReplyAndReceive(s32 *out_index, Handle arr[], s32 array_size, s32 num, Handle reply_target, TimeSpan ts) {
|
Result TimedReplyAndReceive(s32 *out_index, NativeHandle arr[], s32 array_size, s32 num, NativeHandle reply_target, TimeSpan ts) {
|
||||||
return this->ReplyAndReceiveN(out_index, num, arr, array_size, ts.GetNanoSeconds(), reply_target);
|
return this->ReplyAndReceiveN(out_index, num, arr, array_size, ts.GetNanoSeconds(), reply_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearCurrentThreadHandleForCancelWait() {
|
void ClearCurrentThreadHandleForCancelWait() {
|
||||||
this->handle = svc::InvalidHandle;
|
this->handle = os::InvalidNativeHandle;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "impl/os_program_id_impl.hpp"
|
|
||||||
|
|
||||||
namespace ams::os {
|
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||||
|
#include "os_native_handle_impl.os.horizon.hpp"
|
||||||
ncm::ProgramId GetCurrentProgramId() {
|
#else
|
||||||
return ::ams::os::impl::GetCurrentProgramId();
|
#error "Unknown OS for ams::os::NativeHandleImpl"
|
||||||
}
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -13,15 +13,18 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "os_program_id_impl.hpp"
|
|
||||||
|
|
||||||
namespace ams::os::impl {
|
namespace ams::os::impl {
|
||||||
|
|
||||||
ncm::ProgramId GetCurrentProgramId() {
|
class NativeHandleHorizonImpl {
|
||||||
u64 value;
|
public:
|
||||||
R_ABORT_UNLESS(svc::GetInfo(std::addressof(value), svc::InfoType_ProgramId, svc::PseudoHandle::CurrentProcess, 0));
|
static ALWAYS_INLINE void Close(NativeHandle handle) {
|
||||||
return {value};
|
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using NativeHandleImpl = NativeHandleHorizonImpl;
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||||
|
#include "os_process_handle_impl.os.horizon.hpp"
|
||||||
|
#else
|
||||||
|
#error "Unknown OS for ams::os::ProcessHandleImpl"
|
||||||
|
#endif
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::os::impl {
|
||||||
|
|
||||||
|
class ProcessHandleHorizonImpl {
|
||||||
|
public:
|
||||||
|
static consteval NativeHandle GetCurrentProcessHandle() {
|
||||||
|
return svc::PseudoHandle::CurrentProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE Result GetProcessId(ProcessId *out, NativeHandle handle) {
|
||||||
|
return svc::GetProcessId(std::addressof(out->value), handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE Result GetProgramId(ncm::ProgramId *out, NativeHandle handle) {
|
||||||
|
return svc::GetInfo(std::addressof(out->value), svc::InfoType_ProgramId, svc::PseudoHandle::CurrentProcess, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using ProcessHandleImpl = ProcessHandleHorizonImpl;
|
||||||
|
|
||||||
|
}
|
|
@ -20,11 +20,11 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
class SharedMemoryImpl {
|
class SharedMemoryImpl {
|
||||||
public:
|
public:
|
||||||
static Result Create(Handle *out, size_t size, MemoryPermission my_perm, MemoryPermission other_perm);
|
static Result Create(NativeHandle *out, size_t size, MemoryPermission my_perm, MemoryPermission other_perm);
|
||||||
static void Close(Handle handle);
|
static void Close(NativeHandle handle);
|
||||||
|
|
||||||
static Result Map(void **out, Handle handle, size_t size, MemoryPermission perm);
|
static Result Map(void **out, NativeHandle handle, size_t size, MemoryPermission perm);
|
||||||
static void Unmap(Handle handle, void *address, size_t size);
|
static void Unmap(NativeHandle handle, void *address, size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -33,7 +33,7 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SharedMemoryImpl::Create(Handle *out, size_t size, MemoryPermission my_perm, MemoryPermission other_perm) {
|
Result SharedMemoryImpl::Create(NativeHandle *out, size_t size, MemoryPermission my_perm, MemoryPermission other_perm) {
|
||||||
/* Convert memory permissions. */
|
/* Convert memory permissions. */
|
||||||
const auto svc_my_perm = ConvertToSvcMemoryPermission(my_perm);
|
const auto svc_my_perm = ConvertToSvcMemoryPermission(my_perm);
|
||||||
const auto svc_other_perm = ConvertToSvcMemoryPermission(other_perm);
|
const auto svc_other_perm = ConvertToSvcMemoryPermission(other_perm);
|
||||||
|
@ -49,11 +49,11 @@ namespace ams::os::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedMemoryImpl::Close(Handle handle) {
|
void SharedMemoryImpl::Close(NativeHandle handle) {
|
||||||
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SharedMemoryImpl::Map(void **out, Handle handle, size_t size, MemoryPermission perm) {
|
Result SharedMemoryImpl::Map(void **out, NativeHandle handle, size_t size, MemoryPermission perm) {
|
||||||
/* Convert memory permission. */
|
/* Convert memory permission. */
|
||||||
const auto svc_perm = ConvertToSvcMemoryPermission(perm);
|
const auto svc_perm = ConvertToSvcMemoryPermission(perm);
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ namespace ams::os::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedMemoryImpl::Unmap(Handle handle, void *address, size_t size) {
|
void SharedMemoryImpl::Unmap(NativeHandle handle, void *address, size_t size) {
|
||||||
R_ABORT_UNLESS(svc::UnmapSharedMemory(handle, reinterpret_cast<uintptr_t>(address), size));
|
R_ABORT_UNLESS(svc::UnmapSharedMemory(handle, reinterpret_cast<uintptr_t>(address), size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace ams::os::impl {
|
||||||
return GetThreadManager().GetCurrentThread();
|
return GetThreadManager().GetCurrentThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE Handle GetCurrentThreadHandle() {
|
ALWAYS_INLINE NativeHandle GetCurrentThreadHandle() {
|
||||||
/* return GetCurrentThread()->thread_impl->handle; */
|
/* return GetCurrentThread()->thread_impl->handle; */
|
||||||
return ::threadGetCurHandle();
|
return ::threadGetCurHandle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
/* Set the thread's id. */
|
/* Set the thread's id. */
|
||||||
u64 thread_id;
|
u64 thread_id;
|
||||||
R_ABORT_UNLESS(svc::GetThreadId(std::addressof(thread_id), svc::Handle(thread->thread_impl->handle)));
|
R_ABORT_UNLESS(svc::GetThreadId(std::addressof(thread_id), thread->thread_impl->handle));
|
||||||
thread->thread_id = thread_id;
|
thread->thread_id = thread_id;
|
||||||
|
|
||||||
/* Invoke the thread. */
|
/* Invoke the thread. */
|
||||||
|
@ -60,7 +60,7 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
/* Set the thread id. */
|
/* Set the thread id. */
|
||||||
u64 thread_id;
|
u64 thread_id;
|
||||||
R_ABORT_UNLESS(svc::GetThreadId(std::addressof(thread_id), svc::Handle(thread_impl->handle)));
|
R_ABORT_UNLESS(svc::GetThreadId(std::addressof(thread_id), thread_impl->handle));
|
||||||
main_thread->thread_id = thread_id;
|
main_thread->thread_id = thread_id;
|
||||||
|
|
||||||
/* NOTE: Here Nintendo would set the thread pointer in TLS. */
|
/* NOTE: Here Nintendo would set the thread pointer in TLS. */
|
||||||
|
@ -94,7 +94,7 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadManagerHorizonImpl::WaitForThreadExit(ThreadType *thread) {
|
void ThreadManagerHorizonImpl::WaitForThreadExit(ThreadType *thread) {
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
const svc::Handle handle = thread->thread_impl->handle;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
s32 index;
|
s32 index;
|
||||||
|
@ -107,7 +107,7 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThreadManagerHorizonImpl::TryWaitForThreadExit(ThreadType *thread) {
|
bool ThreadManagerHorizonImpl::TryWaitForThreadExit(ThreadType *thread) {
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
const svc::Handle handle = thread->thread_impl->handle;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Continuously wait, until success or timeout. */
|
/* Continuously wait, until success or timeout. */
|
||||||
|
@ -137,9 +137,7 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThreadManagerHorizonImpl::ChangePriority(ThreadType *thread, s32 priority) {
|
bool ThreadManagerHorizonImpl::ChangePriority(ThreadType *thread, s32 priority) {
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
auto res = svc::SetThreadPriority(thread->thread_impl->handle, ConvertToHorizonPriority(priority));
|
||||||
|
|
||||||
auto res = svc::SetThreadPriority(handle, ConvertToHorizonPriority(priority));
|
|
||||||
if (svc::ResultInvalidPriority::Includes(res)) {
|
if (svc::ResultInvalidPriority::Includes(res)) {
|
||||||
AMS_ABORT("Invalid thread priority");
|
AMS_ABORT("Invalid thread priority");
|
||||||
}
|
}
|
||||||
|
@ -148,10 +146,8 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 ThreadManagerHorizonImpl::GetCurrentPriority(const ThreadType *thread) const {
|
s32 ThreadManagerHorizonImpl::GetCurrentPriority(const ThreadType *thread) const {
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
|
||||||
s32 priority;
|
s32 priority;
|
||||||
|
R_ABORT_UNLESS(svc::GetThreadPriority(std::addressof(priority), thread->thread_impl->handle));
|
||||||
R_ABORT_UNLESS(svc::GetThreadPriority(std::addressof(priority), handle));
|
|
||||||
|
|
||||||
return ConvertToUserPriority(priority);
|
return ConvertToUserPriority(priority);
|
||||||
}
|
}
|
||||||
|
@ -161,21 +157,15 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadManagerHorizonImpl::SuspendThreadUnsafe(ThreadType *thread) {
|
void ThreadManagerHorizonImpl::SuspendThreadUnsafe(ThreadType *thread) {
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
R_ABORT_UNLESS(svc::SetThreadActivity(thread->thread_impl->handle, svc::ThreadActivity_Paused));
|
||||||
|
|
||||||
R_ABORT_UNLESS(svc::SetThreadActivity(handle, svc::ThreadActivity_Paused));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadManagerHorizonImpl::ResumeThreadUnsafe(ThreadType *thread) {
|
void ThreadManagerHorizonImpl::ResumeThreadUnsafe(ThreadType *thread) {
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
R_ABORT_UNLESS(svc::SetThreadActivity(thread->thread_impl->handle, svc::ThreadActivity_Runnable));
|
||||||
|
|
||||||
R_ABORT_UNLESS(svc::SetThreadActivity(handle, svc::ThreadActivity_Runnable));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadManagerHorizonImpl::CancelThreadSynchronizationUnsafe(ThreadType *thread) {
|
void ThreadManagerHorizonImpl::CancelThreadSynchronizationUnsafe(ThreadType *thread) {
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
R_ABORT_UNLESS(svc::CancelSynchronization(thread->thread_impl->handle));
|
||||||
|
|
||||||
R_ABORT_UNLESS(svc::CancelSynchronization(handle));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: void GetThreadContextUnsafe(ThreadContextInfo *out_context, const ThreadType *thread); */
|
/* TODO: void GetThreadContextUnsafe(ThreadContextInfo *out_context, const ThreadType *thread); */
|
||||||
|
@ -185,16 +175,14 @@ namespace ams::os::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadManagerHorizonImpl::SetThreadCoreMask(ThreadType *thread, s32 ideal_core, u64 affinity_mask) const {
|
void ThreadManagerHorizonImpl::SetThreadCoreMask(ThreadType *thread, s32 ideal_core, u64 affinity_mask) const {
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
R_ABORT_UNLESS(svc::SetThreadCoreMask(thread->thread_impl->handle, ideal_core, affinity_mask));
|
||||||
R_ABORT_UNLESS(svc::SetThreadCoreMask(handle, ideal_core, affinity_mask));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadManagerHorizonImpl::GetThreadCoreMask(s32 *out_ideal_core, u64 *out_affinity_mask, const ThreadType *thread) const {
|
void ThreadManagerHorizonImpl::GetThreadCoreMask(s32 *out_ideal_core, u64 *out_affinity_mask, const ThreadType *thread) const {
|
||||||
s32 ideal_core;
|
s32 ideal_core;
|
||||||
u64 affinity_mask;
|
u64 affinity_mask;
|
||||||
|
|
||||||
const svc::Handle handle(thread->thread_impl->handle);
|
R_ABORT_UNLESS(svc::GetThreadCoreMask(std::addressof(ideal_core), std::addressof(affinity_mask), thread->thread_impl->handle));
|
||||||
R_ABORT_UNLESS(svc::GetThreadCoreMask(std::addressof(ideal_core), std::addressof(affinity_mask), handle));
|
|
||||||
|
|
||||||
if (out_ideal_core) {
|
if (out_ideal_core) {
|
||||||
*out_ideal_core = ideal_core;
|
*out_ideal_core = ideal_core;
|
||||||
|
|
|
@ -20,11 +20,11 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
class TransferMemoryImpl {
|
class TransferMemoryImpl {
|
||||||
public:
|
public:
|
||||||
static Result Create(Handle *out, void *address, size_t size, MemoryPermission perm);
|
static Result Create(NativeHandle *out, void *address, size_t size, MemoryPermission perm);
|
||||||
static void Close(Handle handle);
|
static void Close(NativeHandle handle);
|
||||||
|
|
||||||
static Result Map(void **out, Handle handle, size_t size, MemoryPermission owner_perm);
|
static Result Map(void **out, NativeHandle handle, size_t size, MemoryPermission owner_perm);
|
||||||
static void Unmap(Handle handle, void *address, size_t size);
|
static void Unmap(NativeHandle handle, void *address, size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -33,7 +33,7 @@ namespace ams::os::impl {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result TransferMemoryImpl::Create(Handle *out, void *address, size_t size, MemoryPermission perm) {
|
Result TransferMemoryImpl::Create(NativeHandle *out, void *address, size_t size, MemoryPermission perm) {
|
||||||
/* Convert memory permission. */
|
/* Convert memory permission. */
|
||||||
const auto svc_perm = ConvertToSvcMemoryPermission(perm);
|
const auto svc_perm = ConvertToSvcMemoryPermission(perm);
|
||||||
|
|
||||||
|
@ -48,11 +48,11 @@ namespace ams::os::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransferMemoryImpl::Close(Handle handle) {
|
void TransferMemoryImpl::Close(NativeHandle handle) {
|
||||||
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result TransferMemoryImpl::Map(void **out, Handle handle, size_t size, MemoryPermission owner_perm) {
|
Result TransferMemoryImpl::Map(void **out, NativeHandle handle, size_t size, MemoryPermission owner_perm) {
|
||||||
/* Convert memory permission. */
|
/* Convert memory permission. */
|
||||||
const auto svc_owner_perm = ConvertToSvcMemoryPermission(owner_perm);
|
const auto svc_owner_perm = ConvertToSvcMemoryPermission(owner_perm);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ namespace ams::os::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransferMemoryImpl::Unmap(Handle handle, void *address, size_t size) {
|
void TransferMemoryImpl::Unmap(NativeHandle handle, void *address, size_t size) {
|
||||||
R_ABORT_UNLESS(svc::UnmapTransferMemory(handle, reinterpret_cast<uintptr_t>(address), size));
|
R_ABORT_UNLESS(svc::UnmapTransferMemory(handle, reinterpret_cast<uintptr_t>(address), size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace ams::os {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void InitializeIoRegion(IoRegionType *io_region, Handle handle, size_t size, bool managed) {
|
void InitializeIoRegion(IoRegionType *io_region, NativeHandle handle, size_t size, bool managed) {
|
||||||
/* Set state. */
|
/* Set state. */
|
||||||
io_region->state = IoRegionType::State_Initialized;
|
io_region->state = IoRegionType::State_Initialized;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ namespace ams::os {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateIoRegion(IoRegionType *io_region, Handle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission) {
|
Result CreateIoRegion(IoRegionType *io_region, NativeHandle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission) {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(io_region != nullptr);
|
AMS_ASSERT(io_region != nullptr);
|
||||||
AMS_ASSERT(io_pool_handle != svc::InvalidHandle);
|
AMS_ASSERT(io_pool_handle != svc::InvalidHandle);
|
||||||
|
@ -49,7 +49,7 @@ namespace ams::os {
|
||||||
auto state_guard = SCOPE_GUARD { io_region->state = IoRegionType::State_NotInitialized; };
|
auto state_guard = SCOPE_GUARD { io_region->state = IoRegionType::State_NotInitialized; };
|
||||||
|
|
||||||
/* Create the io region. */
|
/* Create the io region. */
|
||||||
Handle handle;
|
NativeHandle handle;
|
||||||
R_TRY(impl::IoRegionImpl::CreateIoRegion(std::addressof(handle), io_pool_handle, address, size, mapping, permission));
|
R_TRY(impl::IoRegionImpl::CreateIoRegion(std::addressof(handle), io_pool_handle, address, size, mapping, permission));
|
||||||
|
|
||||||
/* Setup the object. */
|
/* Setup the object. */
|
||||||
|
@ -59,7 +59,7 @@ namespace ams::os {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachIoRegionHandle(IoRegionType *io_region, size_t size, Handle handle, bool managed) {
|
void AttachIoRegionHandle(IoRegionType *io_region, size_t size, NativeHandle handle, bool managed) {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(io_region != nullptr);
|
AMS_ASSERT(io_region != nullptr);
|
||||||
AMS_ASSERT(util::IsAligned(size, os::MemoryPageSize));
|
AMS_ASSERT(util::IsAligned(size, os::MemoryPageSize));
|
||||||
|
@ -81,8 +81,7 @@ namespace ams::os {
|
||||||
|
|
||||||
/* If managed, close the handle. */
|
/* If managed, close the handle. */
|
||||||
if (io_region->handle_managed) {
|
if (io_region->handle_managed) {
|
||||||
/* TODO: os::CloseNativeHandle */
|
os::CloseNativeHandle(io_region->handle);
|
||||||
R_ABORT_UNLESS(svc::CloseHandle(io_region->handle));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear members. */
|
/* Clear members. */
|
||||||
|
@ -95,7 +94,7 @@ namespace ams::os {
|
||||||
io_region->state = IoRegionType::State_NotInitialized;
|
io_region->state = IoRegionType::State_NotInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetIoRegionHandle(const IoRegionType *io_region) {
|
NativeHandle GetIoRegionHandle(const IoRegionType *io_region) {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(io_region->state != IoRegionType::State_NotInitialized);
|
AMS_ASSERT(io_region->state != IoRegionType::State_NotInitialized);
|
||||||
|
|
||||||
|
|
|
@ -141,8 +141,8 @@ namespace ams::os {
|
||||||
return holder->user_data;
|
return holder->user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeMultiWaitHolder(MultiWaitHolderType *holder, Handle handle) {
|
void InitializeMultiWaitHolder(MultiWaitHolderType *holder, NativeHandle handle) {
|
||||||
AMS_ASSERT(handle != svc::InvalidHandle);
|
AMS_ASSERT(handle != os::InvalidNativeHandle);
|
||||||
|
|
||||||
util::ConstructAt(GetReference(holder->impl_storage).holder_of_handle_storage, handle);
|
util::ConstructAt(GetReference(holder->impl_storage).holder_of_handle_storage, handle);
|
||||||
|
|
||||||
|
|
27
libraries/libstratosphere/source/os/os_native_handle_api.cpp
Normal file
27
libraries/libstratosphere/source/os/os_native_handle_api.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "impl/os_native_handle_impl.hpp"
|
||||||
|
|
||||||
|
namespace ams::os {
|
||||||
|
|
||||||
|
void CloseNativeHandle(NativeHandle handle) {
|
||||||
|
if (handle != os::InvalidNativeHandle) {
|
||||||
|
impl::NativeHandleImpl::Close(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,29 +14,30 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#include "impl/os_process_handle_impl.hpp"
|
||||||
|
|
||||||
namespace ams {
|
namespace ams {
|
||||||
|
|
||||||
namespace {
|
namespace dd {
|
||||||
|
|
||||||
constexpr inline ::Handle GetCurrentProcessHandleImpl() {
|
dd::ProcessHandle __attribute__((const)) GetCurrentProcessHandle() {
|
||||||
return CUR_PROCESS_HANDLE;
|
return ::ams::os::impl::ProcessHandleImpl::GetCurrentProcessHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace os {
|
namespace os {
|
||||||
|
|
||||||
::Handle __attribute__((const)) GetCurrentProcessHandle() {
|
NativeHandle __attribute__((const)) GetCurrentProcessHandle() {
|
||||||
return GetCurrentProcessHandleImpl();
|
return ::ams::os::impl::ProcessHandleImpl::GetCurrentProcessHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
Result GetProcessId(os::ProcessId *out, NativeHandle handle) {
|
||||||
|
return ::ams::os::impl::ProcessHandleImpl::GetProcessId(out, handle);
|
||||||
|
}
|
||||||
|
|
||||||
namespace dd {
|
Result GetProgramId(ncm::ProgramId *out, NativeHandle handle) {
|
||||||
|
return ::ams::os::impl::ProcessHandleImpl::GetProgramId(out, handle);
|
||||||
::Handle __attribute__((const)) GetCurrentProcessHandle() {
|
|
||||||
return GetCurrentProcessHandleImpl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -32,7 +32,7 @@ namespace ams::os {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SdkReplyAndReceive(os::MultiWaitHolderType **out, Handle reply_target, MultiWaitType *multi_wait) {
|
Result SdkReplyAndReceive(os::MultiWaitHolderType **out, NativeHandle reply_target, MultiWaitType *multi_wait) {
|
||||||
auto &impl = GetMultiWaitImpl(multi_wait);
|
auto &impl = GetMultiWaitImpl(multi_wait);
|
||||||
|
|
||||||
AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized);
|
AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized);
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace ams::os {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void SetupSharedMemoryType(SharedMemoryType *shared_memory, size_t size, Handle handle, bool managed) {
|
void SetupSharedMemoryType(SharedMemoryType *shared_memory, size_t size, NativeHandle handle, bool managed) {
|
||||||
/* Set members. */
|
/* Set members. */
|
||||||
shared_memory->handle = handle;
|
shared_memory->handle = handle;
|
||||||
shared_memory->size = size;
|
shared_memory->size = size;
|
||||||
|
@ -43,7 +43,7 @@ namespace ams::os {
|
||||||
AMS_ASSERT(util::IsAligned(size, MemoryPageSize));
|
AMS_ASSERT(util::IsAligned(size, MemoryPageSize));
|
||||||
|
|
||||||
/* Create the memory. */
|
/* Create the memory. */
|
||||||
Handle handle;
|
NativeHandle handle;
|
||||||
R_TRY(impl::SharedMemoryImpl::Create(std::addressof(handle), size, my_perm, other_perm));
|
R_TRY(impl::SharedMemoryImpl::Create(std::addressof(handle), size, my_perm, other_perm));
|
||||||
|
|
||||||
/* Setup the object. */
|
/* Setup the object. */
|
||||||
|
@ -52,11 +52,11 @@ namespace ams::os {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachSharedMemory(SharedMemoryType *shared_memory, size_t size, Handle handle, bool managed) {
|
void AttachSharedMemory(SharedMemoryType *shared_memory, size_t size, NativeHandle handle, bool managed) {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(size > 0);
|
AMS_ASSERT(size > 0);
|
||||||
AMS_ASSERT(util::IsAligned(size, MemoryPageSize));
|
AMS_ASSERT(util::IsAligned(size, MemoryPageSize));
|
||||||
AMS_ASSERT(handle != svc::InvalidHandle);
|
AMS_ASSERT(handle != os::InvalidNativeHandle);
|
||||||
|
|
||||||
/* Setup the object. */
|
/* Setup the object. */
|
||||||
SetupSharedMemoryType(shared_memory, size, handle, managed);
|
SetupSharedMemoryType(shared_memory, size, handle, managed);
|
||||||
|
@ -83,7 +83,7 @@ namespace ams::os {
|
||||||
/* Clear members. */
|
/* Clear members. */
|
||||||
shared_memory->address = nullptr;
|
shared_memory->address = nullptr;
|
||||||
shared_memory->size = 0;
|
shared_memory->size = 0;
|
||||||
shared_memory->handle = svc::InvalidHandle;
|
shared_memory->handle = os::InvalidNativeHandle;
|
||||||
|
|
||||||
/* Destroy the critical section. */
|
/* Destroy the critical section. */
|
||||||
util::DestroyAt(shared_memory->cs_shared_memory);
|
util::DestroyAt(shared_memory->cs_shared_memory);
|
||||||
|
@ -147,7 +147,7 @@ namespace ams::os {
|
||||||
return shared_memory->size;
|
return shared_memory->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetSharedMemoryHandle(const SharedMemoryType *shared_memory) {
|
NativeHandle GetSharedMemoryHandle(const SharedMemoryType *shared_memory) {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(shared_memory->state == SharedMemoryType::State_Initialized || shared_memory->state == SharedMemoryType::State_Mapped);
|
AMS_ASSERT(shared_memory->state == SharedMemoryType::State_Initialized || shared_memory->state == SharedMemoryType::State_Mapped);
|
||||||
|
|
||||||
|
|
|
@ -42,36 +42,36 @@ namespace ams::os {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachSystemEvent(SystemEventType *event, Handle read_handle, bool read_handle_managed, Handle write_handle, bool write_handle_managed, EventClearMode clear_mode) {
|
void AttachSystemEvent(SystemEventType *event, NativeHandle read_handle, bool read_handle_managed, NativeHandle write_handle, bool write_handle_managed, EventClearMode clear_mode) {
|
||||||
AMS_ASSERT(read_handle != svc::InvalidHandle || write_handle != svc::InvalidHandle);
|
AMS_ASSERT(read_handle != svc::InvalidHandle || write_handle != svc::InvalidHandle);
|
||||||
impl::AttachInterProcessEvent(std::addressof(event->inter_process_event), read_handle, read_handle_managed, write_handle, write_handle_managed, clear_mode);
|
impl::AttachInterProcessEvent(std::addressof(event->inter_process_event), read_handle, read_handle_managed, write_handle, write_handle_managed, clear_mode);
|
||||||
event->state = SystemEventType::State_InitializedAsInterProcessEvent;
|
event->state = SystemEventType::State_InitializedAsInterProcessEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachReadableHandleToSystemEvent(SystemEventType *event, Handle read_handle, bool manage_read_handle, EventClearMode clear_mode) {
|
void AttachReadableHandleToSystemEvent(SystemEventType *event, NativeHandle read_handle, bool manage_read_handle, EventClearMode clear_mode) {
|
||||||
return AttachSystemEvent(event, read_handle, manage_read_handle, svc::InvalidHandle, false, clear_mode);
|
return AttachSystemEvent(event, read_handle, manage_read_handle, svc::InvalidHandle, false, clear_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachWritableHandleToSystemEvent(SystemEventType *event, Handle write_handle, bool manage_write_handle, EventClearMode clear_mode) {
|
void AttachWritableHandleToSystemEvent(SystemEventType *event, NativeHandle write_handle, bool manage_write_handle, EventClearMode clear_mode) {
|
||||||
return AttachSystemEvent(event, svc::InvalidHandle, false, write_handle, manage_write_handle, clear_mode);
|
return AttachSystemEvent(event, svc::InvalidHandle, false, write_handle, manage_write_handle, clear_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle DetachReadableHandleOfSystemEvent(SystemEventType *event) {
|
NativeHandle DetachReadableHandleOfSystemEvent(SystemEventType *event) {
|
||||||
AMS_ASSERT(event->state == SystemEventType::State_InitializedAsInterProcessEvent);
|
AMS_ASSERT(event->state == SystemEventType::State_InitializedAsInterProcessEvent);
|
||||||
return impl::DetachReadableHandleOfInterProcessEvent(std::addressof(event->inter_process_event));
|
return impl::DetachReadableHandleOfInterProcessEvent(std::addressof(event->inter_process_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle DetachWritableHandleOfSystemEvent(SystemEventType *event) {
|
NativeHandle DetachWritableHandleOfSystemEvent(SystemEventType *event) {
|
||||||
AMS_ASSERT(event->state == SystemEventType::State_InitializedAsInterProcessEvent);
|
AMS_ASSERT(event->state == SystemEventType::State_InitializedAsInterProcessEvent);
|
||||||
return impl::DetachWritableHandleOfInterProcessEvent(std::addressof(event->inter_process_event));
|
return impl::DetachWritableHandleOfInterProcessEvent(std::addressof(event->inter_process_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetReadableHandleOfSystemEvent(const SystemEventType *event) {
|
NativeHandle GetReadableHandleOfSystemEvent(const SystemEventType *event) {
|
||||||
AMS_ASSERT(event->state == SystemEventType::State_InitializedAsInterProcessEvent);
|
AMS_ASSERT(event->state == SystemEventType::State_InitializedAsInterProcessEvent);
|
||||||
return impl::GetReadableHandleOfInterProcessEvent(std::addressof(event->inter_process_event));
|
return impl::GetReadableHandleOfInterProcessEvent(std::addressof(event->inter_process_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetWritableHandleOfSystemEvent(const SystemEventType *event) {
|
NativeHandle GetWritableHandleOfSystemEvent(const SystemEventType *event) {
|
||||||
AMS_ASSERT(event->state == SystemEventType::State_InitializedAsInterProcessEvent);
|
AMS_ASSERT(event->state == SystemEventType::State_InitializedAsInterProcessEvent);
|
||||||
return impl::GetWritableHandleOfInterProcessEvent(std::addressof(event->inter_process_event));
|
return impl::GetWritableHandleOfInterProcessEvent(std::addressof(event->inter_process_event));
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace ams::os {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
inline void SetupTransferMemoryType(TransferMemoryType *tmem, size_t size, Handle handle, bool managed) {
|
inline void SetupTransferMemoryType(TransferMemoryType *tmem, size_t size, NativeHandle handle, bool managed) {
|
||||||
/* Set members. */
|
/* Set members. */
|
||||||
tmem->handle = handle;
|
tmem->handle = handle;
|
||||||
tmem->size = size;
|
tmem->size = size;
|
||||||
|
@ -45,7 +45,7 @@ namespace ams::os {
|
||||||
AMS_ASSERT(util::IsAligned(reinterpret_cast<uintptr_t>(address), os::MemoryPageSize));
|
AMS_ASSERT(util::IsAligned(reinterpret_cast<uintptr_t>(address), os::MemoryPageSize));
|
||||||
|
|
||||||
/* Create the memory. */
|
/* Create the memory. */
|
||||||
Handle handle;
|
NativeHandle handle;
|
||||||
R_TRY(impl::TransferMemoryImpl::Create(std::addressof(handle), address, size, perm));
|
R_TRY(impl::TransferMemoryImpl::Create(std::addressof(handle), address, size, perm));
|
||||||
|
|
||||||
/* Setup the object. */
|
/* Setup the object. */
|
||||||
|
@ -54,7 +54,7 @@ namespace ams::os {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachTransferMemory(TransferMemoryType *tmem, size_t size, Handle handle, bool managed) {
|
void AttachTransferMemory(TransferMemoryType *tmem, size_t size, NativeHandle handle, bool managed) {
|
||||||
AMS_ASSERT(size > 0);
|
AMS_ASSERT(size > 0);
|
||||||
AMS_ASSERT(util::IsAligned(size, os::MemoryPageSize));
|
AMS_ASSERT(util::IsAligned(size, os::MemoryPageSize));
|
||||||
AMS_ASSERT(handle != svc::InvalidHandle);
|
AMS_ASSERT(handle != svc::InvalidHandle);
|
||||||
|
@ -63,16 +63,16 @@ namespace ams::os {
|
||||||
SetupTransferMemoryType(tmem, size, handle, managed);
|
SetupTransferMemoryType(tmem, size, handle, managed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle DetachTransferMemory(TransferMemoryType *tmem) {
|
NativeHandle DetachTransferMemory(TransferMemoryType *tmem) {
|
||||||
AMS_ASSERT(tmem->state == TransferMemoryType::State_Created);
|
AMS_ASSERT(tmem->state == TransferMemoryType::State_Created);
|
||||||
|
|
||||||
/* Set state to detached. */
|
/* Set state to detached. */
|
||||||
tmem->state = TransferMemoryType::State_Detached;
|
tmem->state = TransferMemoryType::State_Detached;
|
||||||
|
|
||||||
/* Clear handle. */
|
/* Clear handle. */
|
||||||
Handle handle = tmem->handle;
|
const NativeHandle handle = tmem->handle;
|
||||||
|
|
||||||
tmem->handle = svc::InvalidHandle;
|
tmem->handle = os::InvalidNativeHandle;
|
||||||
tmem->handle_managed = false;
|
tmem->handle_managed = false;
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
|
@ -99,7 +99,7 @@ namespace ams::os {
|
||||||
/* Clear members. */
|
/* Clear members. */
|
||||||
tmem->address = nullptr;
|
tmem->address = nullptr;
|
||||||
tmem->size = 0;
|
tmem->size = 0;
|
||||||
tmem->handle = svc::InvalidHandle;
|
tmem->handle = os::InvalidNativeHandle;
|
||||||
|
|
||||||
/* Destroy the critical section. */
|
/* Destroy the critical section. */
|
||||||
util::DestroyAt(tmem->cs_transfer_memory);
|
util::DestroyAt(tmem->cs_transfer_memory);
|
||||||
|
|
|
@ -469,7 +469,10 @@ namespace ams::mitm::sysupdater {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SystemUpdateService::SetupUpdateImpl(os::ManagedHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id) {
|
Result SystemUpdateService::SetupUpdateImpl(os::NativeHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id) {
|
||||||
|
/* Ensure the transfer memory handle is closed, if we exit before creating the management object. */
|
||||||
|
auto handle_guard = SCOPE_GUARD { os::CloseNativeHandle(transfer_memory); };
|
||||||
|
|
||||||
/* Ensure we don't already have an update set up. */
|
/* Ensure we don't already have an update set up. */
|
||||||
R_UNLESS(!this->setup_update, ns::ResultCardUpdateAlreadySetup());
|
R_UNLESS(!this->setup_update, ns::ResultCardUpdateAlreadySetup());
|
||||||
|
|
||||||
|
@ -481,6 +484,7 @@ namespace ams::mitm::sysupdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the update task. */
|
/* Initialize the update task. */
|
||||||
|
handle_guard.Cancel();
|
||||||
R_TRY(InitializeUpdateTask(transfer_memory, transfer_memory_size, path, exfat, firmware_variation_id));
|
R_TRY(InitializeUpdateTask(transfer_memory, transfer_memory_size, path, exfat, firmware_variation_id));
|
||||||
|
|
||||||
/* The update is now set up. */
|
/* The update is now set up. */
|
||||||
|
@ -488,10 +492,10 @@ namespace ams::mitm::sysupdater {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SystemUpdateService::InitializeUpdateTask(os::ManagedHandle &transfer_memory_handle, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id) {
|
Result SystemUpdateService::InitializeUpdateTask(os::NativeHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id) {
|
||||||
/* Map the transfer memory. */
|
/* Map the transfer memory. */
|
||||||
const size_t tmem_buffer_size = static_cast<size_t>(transfer_memory_size);
|
const size_t tmem_buffer_size = static_cast<size_t>(transfer_memory_size);
|
||||||
this->update_transfer_memory.emplace(tmem_buffer_size, transfer_memory_handle.Get(), true);
|
this->update_transfer_memory.emplace(tmem_buffer_size, transfer_memory, true);
|
||||||
|
|
||||||
void *tmem_buffer;
|
void *tmem_buffer;
|
||||||
R_TRY(this->update_transfer_memory->Map(std::addressof(tmem_buffer), os::MemoryPermission_None));
|
R_TRY(this->update_transfer_memory->Map(std::addressof(tmem_buffer), os::MemoryPermission_None));
|
||||||
|
@ -500,9 +504,6 @@ namespace ams::mitm::sysupdater {
|
||||||
this->update_transfer_memory = util::nullopt;
|
this->update_transfer_memory = util::nullopt;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Now that the memory is mapped, the input handle is managed and can be released. */
|
|
||||||
transfer_memory_handle.Detach();
|
|
||||||
|
|
||||||
/* Adjust the package root. */
|
/* Adjust the package root. */
|
||||||
ncm::Path package_root;
|
ncm::Path package_root;
|
||||||
R_TRY(FormatUserPackagePath(std::addressof(package_root), path));
|
R_TRY(FormatUserPackagePath(std::addressof(package_root), path));
|
||||||
|
|
|
@ -64,8 +64,8 @@ namespace ams::mitm::sysupdater {
|
||||||
public:
|
public:
|
||||||
constexpr SystemUpdateService() : apply_manager(), update_task(), update_transfer_memory(), setup_update(false), requested_update(false) { /* ... */ }
|
constexpr SystemUpdateService() : apply_manager(), update_task(), update_transfer_memory(), setup_update(false), requested_update(false) { /* ... */ }
|
||||||
private:
|
private:
|
||||||
Result SetupUpdateImpl(os::ManagedHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
Result SetupUpdateImpl(os::NativeHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
||||||
Result InitializeUpdateTask(os::ManagedHandle &transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
Result InitializeUpdateTask(os::NativeHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
||||||
public:
|
public:
|
||||||
Result GetUpdateInformation(sf::Out<UpdateInformation> out, const ncm::Path &path);
|
Result GetUpdateInformation(sf::Out<UpdateInformation> out, const ncm::Path &path);
|
||||||
Result ValidateUpdate(sf::Out<Result> out_validate_result, sf::Out<Result> out_validate_exfat_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path);
|
Result ValidateUpdate(sf::Out<Result> out_validate_result, sf::Out<Result> out_validate_exfat_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path);
|
||||||
|
|
|
@ -219,7 +219,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
/* Note: This function *MUST* be called only with the cheat lock held. */
|
/* Note: This function *MUST* be called only with the cheat lock held. */
|
||||||
os::ProcessId pid;
|
os::ProcessId pid;
|
||||||
bool has_cheat_process = this->cheat_process_debug_handle != svc::InvalidHandle;
|
bool has_cheat_process = this->cheat_process_debug_handle != svc::InvalidHandle;
|
||||||
has_cheat_process &= R_SUCCEEDED(os::TryGetProcessId(&pid, this->cheat_process_debug_handle));
|
has_cheat_process &= R_SUCCEEDED(os::GetProcessId(&pid, this->cheat_process_debug_handle));
|
||||||
has_cheat_process &= R_SUCCEEDED(pm::dmnt::GetApplicationProcessId(&pid));
|
has_cheat_process &= R_SUCCEEDED(pm::dmnt::GetApplicationProcessId(&pid));
|
||||||
has_cheat_process &= (pid == this->cheat_process_metadata.process_id);
|
has_cheat_process &= (pid == this->cheat_process_metadata.process_id);
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,9 @@ namespace ams::ldr {
|
||||||
|
|
||||||
/* Official commands. */
|
/* Official commands. */
|
||||||
Result LoaderService::CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h) {
|
Result LoaderService::CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h) {
|
||||||
os::ManagedHandle reslimit_holder(reslimit_h.GetValue());
|
/* Ensure we close the input handle when we're done. */
|
||||||
|
ON_SCOPE_EXIT { os::CloseNativeHandle(reslimit_h.GetValue()); };
|
||||||
|
|
||||||
ncm::ProgramLocation loc;
|
ncm::ProgramLocation loc;
|
||||||
cfg::OverrideStatus override_status;
|
cfg::OverrideStatus override_status;
|
||||||
char path[FS_MAX_PATH];
|
char path[FS_MAX_PATH];
|
||||||
|
@ -69,7 +71,7 @@ namespace ams::ldr {
|
||||||
R_TRY(ResolveContentPath(path, loc));
|
R_TRY(ResolveContentPath(path, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ldr::CreateProcess(proc_h.GetHandlePointer(), id, loc, override_status, path, flags, reslimit_holder.Get());
|
return ldr::CreateProcess(proc_h.GetHandlePointer(), id, loc, override_status, path, flags, reslimit_h.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoaderService::GetProgramInfo(sf::Out<ProgramInfo> out, const ncm::ProgramLocation &loc) {
|
Result LoaderService::GetProgramInfo(sf::Out<ProgramInfo> out, const ncm::ProgramLocation &loc) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace ams::ldr {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProcessInfo {
|
struct ProcessInfo {
|
||||||
os::ManagedHandle process_handle;
|
os::NativeHandle process_handle;
|
||||||
uintptr_t args_address;
|
uintptr_t args_address;
|
||||||
size_t args_size;
|
size_t args_size;
|
||||||
uintptr_t nso_address[Nso_Count];
|
uintptr_t nso_address[Nso_Count];
|
||||||
|
@ -465,11 +465,12 @@ namespace ams::ldr {
|
||||||
R_TRY(DecideAddressSpaceLayout(out, std::addressof(param), nso_headers, has_nso, arg_info));
|
R_TRY(DecideAddressSpaceLayout(out, std::addressof(param), nso_headers, has_nso, arg_info));
|
||||||
|
|
||||||
/* Actually create process. */
|
/* Actually create process. */
|
||||||
Handle process_handle;
|
svc::Handle process_handle;
|
||||||
R_TRY(svc::CreateProcess(std::addressof(process_handle), std::addressof(param), static_cast<const u32 *>(meta->aci_kac), meta->aci->kac_size / sizeof(u32)));
|
R_TRY(svc::CreateProcess(std::addressof(process_handle), std::addressof(param), static_cast<const u32 *>(meta->aci_kac), meta->aci->kac_size / sizeof(u32)));
|
||||||
|
|
||||||
/* Set the output handle. */
|
/* Set the output handle. */
|
||||||
*out->process_handle.GetPointer() = process_handle;
|
out->process_handle = process_handle;
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,8 +555,6 @@ namespace ams::ldr {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoadNsosIntoProcessMemory(const ProcessInfo *process_info, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info) {
|
Result LoadNsosIntoProcessMemory(const ProcessInfo *process_info, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info) {
|
||||||
const Handle process_handle = process_info->process_handle.Get();
|
|
||||||
|
|
||||||
/* Load each NSO. */
|
/* Load each NSO. */
|
||||||
for (size_t i = 0; i < Nso_Count; i++) {
|
for (size_t i = 0; i < Nso_Count; i++) {
|
||||||
if (has_nso[i]) {
|
if (has_nso[i]) {
|
||||||
|
@ -566,7 +565,7 @@ namespace ams::ldr {
|
||||||
uintptr_t map_address = 0;
|
uintptr_t map_address = 0;
|
||||||
R_TRY(map::LocateMappableSpace(&map_address, process_info->nso_size[i]));
|
R_TRY(map::LocateMappableSpace(&map_address, process_info->nso_size[i]));
|
||||||
|
|
||||||
R_TRY(LoadNsoIntoProcessMemory(process_handle, file, map_address, nso_headers + i, process_info->nso_address[i], process_info->nso_size[i]));
|
R_TRY(LoadNsoIntoProcessMemory(process_info->process_handle, file, map_address, nso_headers + i, process_info->nso_address[i], process_info->nso_size[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +576,7 @@ namespace ams::ldr {
|
||||||
uintptr_t map_address = 0;
|
uintptr_t map_address = 0;
|
||||||
R_TRY(map::LocateMappableSpace(&map_address, process_info->args_size));
|
R_TRY(map::LocateMappableSpace(&map_address, process_info->args_size));
|
||||||
|
|
||||||
map::AutoCloseMap mapper(map_address, process_handle, process_info->args_address, process_info->args_size);
|
map::AutoCloseMap mapper(map_address, process_info->process_handle, process_info->args_address, process_info->args_size);
|
||||||
R_TRY(mapper.GetResult());
|
R_TRY(mapper.GetResult());
|
||||||
|
|
||||||
ProgramArguments *args = reinterpret_cast<ProgramArguments *>(map_address);
|
ProgramArguments *args = reinterpret_cast<ProgramArguments *>(map_address);
|
||||||
|
@ -588,7 +587,7 @@ namespace ams::ldr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set argument region permissions. */
|
/* Set argument region permissions. */
|
||||||
R_TRY(svcSetProcessMemoryPermission(process_handle, process_info->args_address, process_info->args_size, Perm_Rw));
|
R_TRY(svcSetProcessMemoryPermission(process_info->process_handle, process_info->args_address, process_info->args_size, Perm_Rw));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -623,13 +622,16 @@ namespace ams::ldr {
|
||||||
ProcessInfo info;
|
ProcessInfo info;
|
||||||
R_TRY(CreateProcessImpl(&info, &meta, nso_headers, has_nso, arg_info, flags, reslimit_h));
|
R_TRY(CreateProcessImpl(&info, &meta, nso_headers, has_nso, arg_info, flags, reslimit_h));
|
||||||
|
|
||||||
|
/* Ensure we close the process handle, if we fail. */
|
||||||
|
ON_SCOPE_EXIT { os::CloseNativeHandle(info.process_handle); };
|
||||||
|
|
||||||
/* Load NSOs into process memory. */
|
/* Load NSOs into process memory. */
|
||||||
R_TRY(LoadNsosIntoProcessMemory(&info, nso_headers, has_nso, arg_info));
|
R_TRY(LoadNsosIntoProcessMemory(&info, nso_headers, has_nso, arg_info));
|
||||||
|
|
||||||
/* Register NSOs with ro manager. */
|
/* Register NSOs with ro manager. */
|
||||||
{
|
{
|
||||||
/* Nintendo doesn't validate this get, but we do. */
|
/* Nintendo doesn't validate this get, but we do. */
|
||||||
os::ProcessId process_id = os::GetProcessId(info.process_handle.Get());
|
os::ProcessId process_id = os::GetProcessId(info.process_handle);
|
||||||
|
|
||||||
/* Register new process. */
|
/* Register new process. */
|
||||||
ldr::ro::RegisterProcess(pin_id, process_id, loc.program_id);
|
ldr::ro::RegisterProcess(pin_id, process_id, loc.program_id);
|
||||||
|
@ -655,7 +657,8 @@ namespace ams::ldr {
|
||||||
SetLaunchedBootProgram(loc.program_id);
|
SetLaunchedBootProgram(loc.program_id);
|
||||||
|
|
||||||
/* Move the process handle to output. */
|
/* Move the process handle to output. */
|
||||||
*out = info.process_handle.Move();
|
*out = info.process_handle;
|
||||||
|
info.process_handle = os::InvalidNativeHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace ams::ro::impl {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MapNro(u64 *out_base_address, Handle process_handle, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size) {
|
Result MapNro(u64 *out_base_address, os::NativeHandle process_handle, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size) {
|
||||||
map::MappedCodeMemory nro_mcm(ResultInternalError{});
|
map::MappedCodeMemory nro_mcm(ResultInternalError{});
|
||||||
map::MappedCodeMemory bss_mcm(ResultInternalError{});
|
map::MappedCodeMemory bss_mcm(ResultInternalError{});
|
||||||
u64 base_address;
|
u64 base_address;
|
||||||
|
@ -67,7 +67,7 @@ namespace ams::ro::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetNroPerms(Handle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size) {
|
Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size) {
|
||||||
const u64 rx_offset = 0;
|
const u64 rx_offset = 0;
|
||||||
const u64 ro_offset = rx_offset + rx_size;
|
const u64 ro_offset = rx_offset + rx_size;
|
||||||
const u64 rw_offset = ro_offset + ro_size;
|
const u64 rw_offset = ro_offset + ro_size;
|
||||||
|
@ -79,7 +79,7 @@ namespace ams::ro::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnmapNro(Handle process_handle, u64 base_address, u64 nro_heap_address, u64 bss_heap_address, u64 bss_heap_size, u64 code_size, u64 rw_size) {
|
Result UnmapNro(os::NativeHandle process_handle, u64 base_address, u64 nro_heap_address, u64 bss_heap_address, u64 bss_heap_size, u64 code_size, u64 rw_size) {
|
||||||
/* First, unmap bss. */
|
/* First, unmap bss. */
|
||||||
if (bss_heap_size > 0) {
|
if (bss_heap_size > 0) {
|
||||||
R_TRY(svcUnmapProcessCodeMemory(process_handle, base_address + code_size + rw_size, bss_heap_address, bss_heap_size));
|
R_TRY(svcUnmapProcessCodeMemory(process_handle, base_address + code_size + rw_size, bss_heap_address, bss_heap_size));
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
namespace ams::ro::impl {
|
namespace ams::ro::impl {
|
||||||
|
|
||||||
/* Utilities for working with NROs. */
|
/* Utilities for working with NROs. */
|
||||||
Result MapNro(u64 *out_base_address, Handle process_handle, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size);
|
Result MapNro(u64 *out_base_address, os::NativeHandle process_handle, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size);
|
||||||
Result SetNroPerms(Handle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size);
|
Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size);
|
||||||
Result UnmapNro(Handle process_handle, u64 base_address, u64 nro_heap_address, u64 bss_heap_address, u64 bss_heap_size, u64 code_size, u64 rw_size);
|
Result UnmapNro(os::NativeHandle process_handle, u64 base_address, u64 nro_heap_address, u64 bss_heap_address, u64 bss_heap_size, u64 code_size, u64 rw_size);
|
||||||
|
|
||||||
}
|
}
|
|
@ -194,7 +194,7 @@ namespace ams::ro::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Utilities for working with NRRs. */
|
/* Utilities for working with NRRs. */
|
||||||
Result MapAndValidateNrr(NrrHeader **out_header, u64 *out_mapped_code_address, void *out_hash, size_t out_hash_size, Handle process_handle, ncm::ProgramId program_id, u64 nrr_heap_address, u64 nrr_heap_size, NrrKind nrr_kind, bool enforce_nrr_kind) {
|
Result MapAndValidateNrr(NrrHeader **out_header, u64 *out_mapped_code_address, void *out_hash, size_t out_hash_size, os::NativeHandle process_handle, ncm::ProgramId program_id, u64 nrr_heap_address, u64 nrr_heap_size, NrrKind nrr_kind, bool enforce_nrr_kind) {
|
||||||
map::MappedCodeMemory nrr_mcm(ResultInternalError{});
|
map::MappedCodeMemory nrr_mcm(ResultInternalError{});
|
||||||
|
|
||||||
/* First, map the NRR. */
|
/* First, map the NRR. */
|
||||||
|
@ -223,7 +223,7 @@ namespace ams::ro::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnmapNrr(Handle process_handle, const NrrHeader *header, u64 nrr_heap_address, u64 nrr_heap_size, u64 mapped_code_address) {
|
Result UnmapNrr(os::NativeHandle process_handle, const NrrHeader *header, u64 nrr_heap_address, u64 nrr_heap_size, u64 mapped_code_address) {
|
||||||
R_TRY(svcUnmapProcessMemory(reinterpret_cast<void *>(const_cast<NrrHeader *>(header)), process_handle, mapped_code_address, nrr_heap_size));
|
R_TRY(svcUnmapProcessMemory(reinterpret_cast<void *>(const_cast<NrrHeader *>(header)), process_handle, mapped_code_address, nrr_heap_size));
|
||||||
R_TRY(svcUnmapProcessCodeMemory(process_handle, mapped_code_address, nrr_heap_address, nrr_heap_size));
|
R_TRY(svcUnmapProcessCodeMemory(process_handle, mapped_code_address, nrr_heap_address, nrr_heap_size));
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
namespace ams::ro::impl {
|
namespace ams::ro::impl {
|
||||||
|
|
||||||
/* Utilities for working with NRRs. */
|
/* Utilities for working with NRRs. */
|
||||||
Result MapAndValidateNrr(NrrHeader **out_header, u64 *out_mapped_code_address, void *out_hash, size_t out_hash_size, Handle process_handle, ncm::ProgramId program_id, u64 nrr_heap_address, u64 nrr_heap_size, NrrKind nrr_kind, bool enforce_nrr_kind);
|
Result MapAndValidateNrr(NrrHeader **out_header, u64 *out_mapped_code_address, void *out_hash, size_t out_hash_size, os::NativeHandle process_handle, ncm::ProgramId program_id, u64 nrr_heap_address, u64 nrr_heap_size, NrrKind nrr_kind, bool enforce_nrr_kind);
|
||||||
Result UnmapNrr(Handle process_handle, const NrrHeader *header, u64 nrr_heap_address, u64 nrr_heap_size, u64 mapped_code_address);
|
Result UnmapNrr(os::NativeHandle process_handle, const NrrHeader *header, u64 nrr_heap_address, u64 nrr_heap_size, u64 mapped_code_address);
|
||||||
|
|
||||||
bool ValidateNrrHashTableEntry(const void *signed_area, size_t signed_area_size, size_t hashes_offset, size_t num_hashes, const void *nrr_hash, const u8 *hash_table, const void *desired_hash);
|
bool ValidateNrrHashTableEntry(const void *signed_area, size_t signed_area_size, size_t hashes_offset, size_t num_hashes, const void *nrr_hash, const u8 *hash_table, const void *desired_hash);
|
||||||
|
|
||||||
|
|
|
@ -77,20 +77,17 @@ namespace ams::ro::impl {
|
||||||
bool nrr_in_use[MaxNrrInfos];
|
bool nrr_in_use[MaxNrrInfos];
|
||||||
NroInfo nro_infos[MaxNroInfos];
|
NroInfo nro_infos[MaxNroInfos];
|
||||||
NrrInfo nrr_infos[MaxNrrInfos];
|
NrrInfo nrr_infos[MaxNrrInfos];
|
||||||
Handle process_handle;
|
os::NativeHandle process_handle;
|
||||||
os::ProcessId process_id;
|
os::ProcessId process_id;
|
||||||
bool in_use;
|
bool in_use;
|
||||||
|
|
||||||
ncm::ProgramId GetProgramId(Handle other_process_h) const {
|
ncm::ProgramId GetProgramId(os::NativeHandle other_process_h) const {
|
||||||
/* Automatically select a handle, allowing for override. */
|
/* Automatically select a handle, allowing for override. */
|
||||||
Handle process_h = this->process_handle;
|
if (other_process_h != os::InvalidNativeHandle) {
|
||||||
if (other_process_h != svc::InvalidHandle) {
|
return os::GetProgramId(other_process_h);
|
||||||
process_h = other_process_h;
|
} else {
|
||||||
|
return os::GetProgramId(this->process_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
ncm::ProgramId program_id = ncm::InvalidProgramId;
|
|
||||||
R_ABORT_UNLESS(svc::GetInfo(std::addressof(program_id.value), svc::InfoType_ProgramId, process_h, 0));
|
|
||||||
return program_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetNrrInfoByAddress(NrrInfo **out, u64 nrr_heap_address) {
|
Result GetNrrInfoByAddress(NrrInfo **out, u64 nrr_heap_address) {
|
||||||
|
@ -296,7 +293,7 @@ namespace ams::ro::impl {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AllocateContext(Handle process_handle, os::ProcessId process_id) {
|
size_t AllocateContext(os::NativeHandle process_handle, os::ProcessId process_id) {
|
||||||
/* Find a free process context. */
|
/* Find a free process context. */
|
||||||
for (size_t i = 0; i < MaxSessions; i++) {
|
for (size_t i = 0; i < MaxSessions; i++) {
|
||||||
ProcessContext *context = &g_process_contexts[i];
|
ProcessContext *context = &g_process_contexts[i];
|
||||||
|
@ -316,7 +313,7 @@ namespace ams::ro::impl {
|
||||||
void FreeContext(size_t context_id) {
|
void FreeContext(size_t context_id) {
|
||||||
ProcessContext *context = GetContextById(context_id);
|
ProcessContext *context = GetContextById(context_id);
|
||||||
if (context != nullptr) {
|
if (context != nullptr) {
|
||||||
if (context->process_handle != INVALID_HANDLE) {
|
if (context->process_handle != os::InvalidNativeHandle) {
|
||||||
for (size_t i = 0; i < MaxNrrInfos; i++) {
|
for (size_t i = 0; i < MaxNrrInfos; i++) {
|
||||||
if (context->nrr_in_use[i]) {
|
if (context->nrr_in_use[i]) {
|
||||||
UnmapNrr(context->process_handle, context->nrr_infos[i].mapped_header, context->nrr_infos[i].nrr_heap_address, context->nrr_infos[i].nrr_heap_size, context->nrr_infos[i].mapped_code_address);
|
UnmapNrr(context->process_handle, context->nrr_infos[i].mapped_header, context->nrr_infos[i].nrr_heap_address, context->nrr_infos[i].nrr_heap_size, context->nrr_infos[i].mapped_code_address);
|
||||||
|
@ -376,13 +373,16 @@ namespace ams::ro::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Context utilities. */
|
/* Context utilities. */
|
||||||
Result RegisterProcess(size_t *out_context_id, os::ManagedHandle process_handle, os::ProcessId process_id) {
|
Result RegisterProcess(size_t *out_context_id, os::NativeHandle process_handle, os::ProcessId process_id) {
|
||||||
|
/* Ensure we manage process handle correctly. */
|
||||||
|
auto handle_guard = SCOPE_GUARD { os::CloseNativeHandle(process_handle); };
|
||||||
|
|
||||||
/* Validate process handle. */
|
/* Validate process handle. */
|
||||||
{
|
{
|
||||||
os::ProcessId handle_pid = os::InvalidProcessId;
|
os::ProcessId handle_pid = os::InvalidProcessId;
|
||||||
|
|
||||||
/* Validate handle is a valid process handle. */
|
/* Validate handle is a valid process handle. */
|
||||||
R_UNLESS(R_SUCCEEDED(os::TryGetProcessId(&handle_pid, process_handle.Get())), ResultInvalidProcess());
|
R_UNLESS(R_SUCCEEDED(os::GetProcessId(&handle_pid, process_handle)), ResultInvalidProcess());
|
||||||
|
|
||||||
/* Validate process id. */
|
/* Validate process id. */
|
||||||
R_UNLESS(handle_pid == process_id, ResultInvalidProcess());
|
R_UNLESS(handle_pid == process_id, ResultInvalidProcess());
|
||||||
|
@ -391,7 +391,10 @@ namespace ams::ro::impl {
|
||||||
/* Check if a process context already exists. */
|
/* Check if a process context already exists. */
|
||||||
R_UNLESS(GetContextByProcessId(process_id) == nullptr, ResultInvalidSession());
|
R_UNLESS(GetContextByProcessId(process_id) == nullptr, ResultInvalidSession());
|
||||||
|
|
||||||
*out_context_id = AllocateContext(process_handle.Move(), process_id);
|
/* Allocate a context to manage the process handle. */
|
||||||
|
handle_guard.Cancel();
|
||||||
|
*out_context_id = AllocateContext(process_handle, process_id);
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,13 +410,16 @@ namespace ams::ro::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Service implementations. */
|
/* Service implementations. */
|
||||||
Result RegisterModuleInfo(size_t context_id, os::ManagedHandle process_handle, u64 nrr_address, u64 nrr_size, NrrKind nrr_kind, bool enforce_nrr_kind) {
|
Result RegisterModuleInfo(size_t context_id, os::NativeHandle process_handle, u64 nrr_address, u64 nrr_size, NrrKind nrr_kind, bool enforce_nrr_kind) {
|
||||||
|
/* Ensure we close the process handle when we're done with it. */
|
||||||
|
ON_SCOPE_EXIT { os::CloseNativeHandle(process_handle); };
|
||||||
|
|
||||||
/* Get context. */
|
/* Get context. */
|
||||||
ProcessContext *context = GetContextById(context_id);
|
ProcessContext *context = GetContextById(context_id);
|
||||||
AMS_ABORT_UNLESS(context != nullptr);
|
AMS_ABORT_UNLESS(context != nullptr);
|
||||||
|
|
||||||
/* Get program id. */
|
/* Get program id. */
|
||||||
const ncm::ProgramId program_id = context->GetProgramId(process_handle.Get());
|
const ncm::ProgramId program_id = context->GetProgramId(process_handle);
|
||||||
|
|
||||||
/* Validate address/size. */
|
/* Validate address/size. */
|
||||||
R_TRY(ValidateAddressAndNonZeroSize(nrr_address, nrr_size));
|
R_TRY(ValidateAddressAndNonZeroSize(nrr_address, nrr_size));
|
||||||
|
|
|
@ -30,12 +30,12 @@ namespace ams::ro::impl {
|
||||||
bool ShouldEaseNroRestriction();
|
bool ShouldEaseNroRestriction();
|
||||||
|
|
||||||
/* Context utilities. */
|
/* Context utilities. */
|
||||||
Result RegisterProcess(size_t *out_context_id, os::ManagedHandle process_handle, os::ProcessId process_id);
|
Result RegisterProcess(size_t *out_context_id, os::NativeHandle process_handle, os::ProcessId process_id);
|
||||||
Result ValidateProcess(size_t context_id, os::ProcessId process_id);
|
Result ValidateProcess(size_t context_id, os::ProcessId process_id);
|
||||||
void UnregisterProcess(size_t context_id);
|
void UnregisterProcess(size_t context_id);
|
||||||
|
|
||||||
/* Service implementations. */
|
/* Service implementations. */
|
||||||
Result RegisterModuleInfo(size_t context_id, os::ManagedHandle process_h, u64 nrr_address, u64 nrr_size, NrrKind nrr_kind, bool enforce_nrr_kind);
|
Result RegisterModuleInfo(size_t context_id, os::NativeHandle process_h, u64 nrr_address, u64 nrr_size, NrrKind nrr_kind, bool enforce_nrr_kind);
|
||||||
Result UnregisterModuleInfo(size_t context_id, u64 nrr_address);
|
Result UnregisterModuleInfo(size_t context_id, u64 nrr_address);
|
||||||
Result MapManualLoadModuleMemory(u64 *out_address, size_t context_id, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size);
|
Result MapManualLoadModuleMemory(u64 *out_address, size_t context_id, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size);
|
||||||
Result UnmapManualLoadModuleMemory(size_t context_id, u64 nro_address);
|
Result UnmapManualLoadModuleMemory(size_t context_id, u64 nro_address);
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace ams::ro {
|
||||||
|
|
||||||
Result RoService::RegisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size) {
|
Result RoService::RegisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size) {
|
||||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||||
return impl::RegisterModuleInfo(this->context_id, svc::InvalidHandle, nrr_address, nrr_size, NrrKind_User, true);
|
return impl::RegisterModuleInfo(this->context_id, os::InvalidNativeHandle, nrr_address, nrr_size, NrrKind_User, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RoService::UnregisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address) {
|
Result RoService::UnregisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address) {
|
||||||
|
@ -56,20 +56,20 @@ namespace ams::ro {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RoService::RegisterProcessHandle(const sf::ClientProcessId &client_pid, sf::CopyHandle process_h) {
|
Result RoService::RegisterProcessHandle(const sf::ClientProcessId &client_pid, sf::CopyHandle process_h) {
|
||||||
/* Ensure we manage references to the process handle correctly. */
|
|
||||||
os::ManagedHandle process_handle(process_h.GetValue());
|
|
||||||
|
|
||||||
/* Register the process. */
|
/* Register the process. */
|
||||||
return impl::RegisterProcess(std::addressof(this->context_id), std::move(process_handle), client_pid.GetValue());
|
return impl::RegisterProcess(std::addressof(this->context_id), process_h.GetValue(), client_pid.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RoService::RegisterProcessModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle process_h) {
|
Result RoService::RegisterProcessModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle process_h) {
|
||||||
/* Ensure we manage references to the process handle correctly. */
|
/* Validate the process, ensuring we manage the process handle correctly. */
|
||||||
os::ManagedHandle process_handle(process_h.GetValue());
|
{
|
||||||
|
auto handle_guard = SCOPE_GUARD { os::CloseNativeHandle(process_h.GetValue()); };
|
||||||
|
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||||
|
handle_guard.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
/* Register the module. */
|
/* Register the module. */
|
||||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
return impl::RegisterModuleInfo(this->context_id, process_h.GetValue(), nrr_address, nrr_size, this->nrr_kind, this->nrr_kind == NrrKind_JitPlugin);
|
||||||
return impl::RegisterModuleInfo(this->context_id, std::move(process_handle), nrr_address, nrr_size, this->nrr_kind, this->nrr_kind == NrrKind_JitPlugin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue