diff options
28 files changed, 299 insertions, 63 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 6cf1886cf..1cac1d0c9 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -23,6 +23,11 @@ void SessionRequestHandler::ClientDisconnected(SharedPtr<ServerSession> server_s | |||
| 23 | boost::range::remove_erase(connected_sessions, server_session); | 23 | boost::range::remove_erase(connected_sessions, server_session); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | HLERequestContext::HLERequestContext(SharedPtr<ServerSession> session) | ||
| 27 | : session(std::move(session)) { | ||
| 28 | cmd_buf[0] = 0; | ||
| 29 | } | ||
| 30 | |||
| 26 | HLERequestContext::~HLERequestContext() = default; | 31 | HLERequestContext::~HLERequestContext() = default; |
| 27 | 32 | ||
| 28 | SharedPtr<Object> HLERequestContext::GetIncomingHandle(u32 id_from_cmdbuf) const { | 33 | SharedPtr<Object> HLERequestContext::GetIncomingHandle(u32 id_from_cmdbuf) const { |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index cbb109d8f..35795fc1d 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -84,6 +84,7 @@ protected: | |||
| 84 | */ | 84 | */ |
| 85 | class HLERequestContext { | 85 | class HLERequestContext { |
| 86 | public: | 86 | public: |
| 87 | HLERequestContext(SharedPtr<ServerSession> session); | ||
| 87 | ~HLERequestContext(); | 88 | ~HLERequestContext(); |
| 88 | 89 | ||
| 89 | /// Returns a pointer to the IPC command buffer for this request. | 90 | /// Returns a pointer to the IPC command buffer for this request. |
| @@ -118,14 +119,14 @@ public: | |||
| 118 | */ | 119 | */ |
| 119 | void ClearIncomingObjects(); | 120 | void ClearIncomingObjects(); |
| 120 | 121 | ||
| 121 | private: | 122 | /// Populates this context with data from the requesting process/thread. |
| 122 | friend class Service::ServiceFrameworkBase; | ||
| 123 | |||
| 124 | ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process, | 123 | ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process, |
| 125 | HandleTable& src_table); | 124 | HandleTable& src_table); |
| 125 | /// Writes data from this context back to the requesting process/thread. | ||
| 126 | ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process, | 126 | ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process, |
| 127 | HandleTable& dst_table) const; | 127 | HandleTable& dst_table) const; |
| 128 | 128 | ||
| 129 | private: | ||
| 129 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | 130 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |
| 130 | SharedPtr<ServerSession> session; | 131 | SharedPtr<ServerSession> session; |
| 131 | // TODO(yuriks): Check common usage of this and optimize size accordingly | 132 | // TODO(yuriks): Check common usage of this and optimize size accordingly |
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp index 804f23b1c..496d07cb5 100644 --- a/src/core/hle/kernel/memory.cpp +++ b/src/core/hle/kernel/memory.cpp | |||
| @@ -166,7 +166,7 @@ void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mappin | |||
| 166 | auto vma = address_space | 166 | auto vma = address_space |
| 167 | .MapBackingMemory(mapping.address, target_pointer + offset_into_region, | 167 | .MapBackingMemory(mapping.address, target_pointer + offset_into_region, |
| 168 | mapping.size, memory_state) | 168 | mapping.size, memory_state) |
| 169 | .MoveFrom(); | 169 | .Unwrap(); |
| 170 | address_space.Reprotect(vma, | 170 | address_space.Reprotect(vma, |
| 171 | mapping.read_only ? VMAPermission::Read : VMAPermission::ReadWrite); | 171 | mapping.read_only ? VMAPermission::Read : VMAPermission::ReadWrite); |
| 172 | } | 172 | } |
| @@ -176,14 +176,14 @@ void MapSharedPages(VMManager& address_space) { | |||
| 176 | .MapBackingMemory(Memory::CONFIG_MEMORY_VADDR, | 176 | .MapBackingMemory(Memory::CONFIG_MEMORY_VADDR, |
| 177 | reinterpret_cast<u8*>(&ConfigMem::config_mem), | 177 | reinterpret_cast<u8*>(&ConfigMem::config_mem), |
| 178 | Memory::CONFIG_MEMORY_SIZE, MemoryState::Shared) | 178 | Memory::CONFIG_MEMORY_SIZE, MemoryState::Shared) |
| 179 | .MoveFrom(); | 179 | .Unwrap(); |
| 180 | address_space.Reprotect(cfg_mem_vma, VMAPermission::Read); | 180 | address_space.Reprotect(cfg_mem_vma, VMAPermission::Read); |
| 181 | 181 | ||
| 182 | auto shared_page_vma = address_space | 182 | auto shared_page_vma = address_space |
| 183 | .MapBackingMemory(Memory::SHARED_PAGE_VADDR, | 183 | .MapBackingMemory(Memory::SHARED_PAGE_VADDR, |
| 184 | reinterpret_cast<u8*>(&SharedPage::shared_page), | 184 | reinterpret_cast<u8*>(&SharedPage::shared_page), |
| 185 | Memory::SHARED_PAGE_SIZE, MemoryState::Shared) | 185 | Memory::SHARED_PAGE_SIZE, MemoryState::Shared) |
| 186 | .MoveFrom(); | 186 | .Unwrap(); |
| 187 | address_space.Reprotect(shared_page_vma, VMAPermission::Read); | 187 | address_space.Reprotect(shared_page_vma, VMAPermission::Read); |
| 188 | } | 188 | } |
| 189 | 189 | ||
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 2dc709bc9..d197137c3 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -71,7 +71,7 @@ ResultCode ServerSession::HandleSyncRequest() { | |||
| 71 | 71 | ||
| 72 | ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, | 72 | ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, |
| 73 | SharedPtr<ClientPort> port) { | 73 | SharedPtr<ClientPort> port) { |
| 74 | auto server_session = ServerSession::Create(name + "_Server").MoveFrom(); | 74 | auto server_session = ServerSession::Create(name + "_Server").Unwrap(); |
| 75 | SharedPtr<ClientSession> client_session(new ClientSession); | 75 | SharedPtr<ClientSession> client_session(new ClientSession); |
| 76 | client_session->name = name + "_Client"; | 76 | client_session->name = name + "_Client"; |
| 77 | 77 | ||
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 75ce626f8..f5f2eb2f7 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -389,7 +389,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 389 | thread->wait_objects.clear(); | 389 | thread->wait_objects.clear(); |
| 390 | thread->wait_address = 0; | 390 | thread->wait_address = 0; |
| 391 | thread->name = std::move(name); | 391 | thread->name = std::move(name); |
| 392 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom(); | 392 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); |
| 393 | thread->owner_process = g_current_process; | 393 | thread->owner_process = g_current_process; |
| 394 | 394 | ||
| 395 | // Find the next available TLS index, and mark it as used | 395 | // Find the next available TLS index, and mark it as used |
| @@ -484,7 +484,7 @@ SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) { | |||
| 484 | auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0, | 484 | auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0, |
| 485 | Memory::HEAP_VADDR_END); | 485 | Memory::HEAP_VADDR_END); |
| 486 | 486 | ||
| 487 | SharedPtr<Thread> thread = thread_res.MoveFrom(); | 487 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); |
| 488 | 488 | ||
| 489 | thread->context.fpscr = | 489 | thread->context.fpscr = |
| 490 | FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC; // 0x03C00010 | 490 | FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC; // 0x03C00010 |
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 6f2cf3b02..d7ec93672 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp | |||
| @@ -30,7 +30,7 @@ SharedPtr<Timer> Timer::Create(ResetType reset_type, std::string name) { | |||
| 30 | timer->name = std::move(name); | 30 | timer->name = std::move(name); |
| 31 | timer->initial_delay = 0; | 31 | timer->initial_delay = 0; |
| 32 | timer->interval_delay = 0; | 32 | timer->interval_delay = 0; |
| 33 | timer->callback_handle = timer_callback_handle_table.Create(timer).MoveFrom(); | 33 | timer->callback_handle = timer_callback_handle_table.Create(timer).Unwrap(); |
| 34 | 34 | ||
| 35 | return timer; | 35 | return timer; |
| 36 | } | 36 | } |
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 5f2cdbb96..47b6e2b23 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h | |||
| @@ -388,13 +388,14 @@ public: | |||
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | /// Asserts that the result succeeded and returns a reference to it. | 390 | /// Asserts that the result succeeded and returns a reference to it. |
| 391 | T& Unwrap() { | 391 | T& Unwrap() & { |
| 392 | ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal"); | 392 | ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal"); |
| 393 | return **this; | 393 | return **this; |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | T&& MoveFrom() { | 396 | T&& Unwrap() && { |
| 397 | return std::move(Unwrap()); | 397 | ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal"); |
| 398 | return std::move(**this); | ||
| 398 | } | 399 | } |
| 399 | 400 | ||
| 400 | private: | 401 | private: |
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 4c587e3c8..25e7b777d 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp | |||
| @@ -55,8 +55,8 @@ void Initialize(Service::Interface* self) { | |||
| 55 | u32 flags = rp.Pop<u32>(); | 55 | u32 flags = rp.Pop<u32>(); |
| 56 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); | 56 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); |
| 57 | rb.Push(RESULT_SUCCESS); | 57 | rb.Push(RESULT_SUCCESS); |
| 58 | rb.PushCopyHandles(Kernel::g_handle_table.Create(notification_event).MoveFrom(), | 58 | rb.PushCopyHandles(Kernel::g_handle_table.Create(notification_event).Unwrap(), |
| 59 | Kernel::g_handle_table.Create(parameter_event).MoveFrom()); | 59 | Kernel::g_handle_table.Create(parameter_event).Unwrap()); |
| 60 | 60 | ||
| 61 | // TODO(bunnei): Check if these events are cleared every time Initialize is called. | 61 | // TODO(bunnei): Check if these events are cleared every time Initialize is called. |
| 62 | notification_event->Clear(); | 62 | notification_event->Clear(); |
| @@ -93,7 +93,7 @@ void GetSharedFont(Service::Interface* self) { | |||
| 93 | // allocated, the real APT service calculates this address by scanning the entire address space | 93 | // allocated, the real APT service calculates this address by scanning the entire address space |
| 94 | // (using svcQueryMemory) and searches for an allocation of the same size as the Shared Font. | 94 | // (using svcQueryMemory) and searches for an allocation of the same size as the Shared Font. |
| 95 | rb.Push(target_address); | 95 | rb.Push(target_address); |
| 96 | rb.PushCopyHandles(Kernel::g_handle_table.Create(shared_font_mem).MoveFrom()); | 96 | rb.PushCopyHandles(Kernel::g_handle_table.Create(shared_font_mem).Unwrap()); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | void NotifyToWait(Service::Interface* self) { | 99 | void NotifyToWait(Service::Interface* self) { |
| @@ -115,7 +115,7 @@ void GetLockHandle(Service::Interface* self) { | |||
| 115 | rb.Push(RESULT_SUCCESS); // No error | 115 | rb.Push(RESULT_SUCCESS); // No error |
| 116 | rb.Push(applet_attributes); // Applet Attributes, this value is passed to Enable. | 116 | rb.Push(applet_attributes); // Applet Attributes, this value is passed to Enable. |
| 117 | rb.Push<u32>(0); // Least significant bit = power button state | 117 | rb.Push<u32>(0); // Least significant bit = power button state |
| 118 | Kernel::Handle handle_copy = Kernel::g_handle_table.Create(lock).MoveFrom(); | 118 | Kernel::Handle handle_copy = Kernel::g_handle_table.Create(lock).Unwrap(); |
| 119 | rb.PushCopyHandles(handle_copy); | 119 | rb.PushCopyHandles(handle_copy); |
| 120 | 120 | ||
| 121 | LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", handle_copy, | 121 | LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", handle_copy, |
| @@ -231,7 +231,7 @@ void ReceiveParameter(Service::Interface* self) { | |||
| 231 | rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size | 231 | rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size |
| 232 | 232 | ||
| 233 | rb.PushMoveHandles((next_parameter.object != nullptr) | 233 | rb.PushMoveHandles((next_parameter.object != nullptr) |
| 234 | ? Kernel::g_handle_table.Create(next_parameter.object).MoveFrom() | 234 | ? Kernel::g_handle_table.Create(next_parameter.object).Unwrap() |
| 235 | : 0); | 235 | : 0); |
| 236 | rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0); | 236 | rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0); |
| 237 | 237 | ||
| @@ -261,7 +261,7 @@ void GlanceParameter(Service::Interface* self) { | |||
| 261 | rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size | 261 | rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size |
| 262 | 262 | ||
| 263 | rb.PushCopyHandles((next_parameter.object != nullptr) | 263 | rb.PushCopyHandles((next_parameter.object != nullptr) |
| 264 | ? Kernel::g_handle_table.Create(next_parameter.object).MoveFrom() | 264 | ? Kernel::g_handle_table.Create(next_parameter.object).Unwrap() |
| 265 | : 0); | 265 | : 0); |
| 266 | rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0); | 266 | rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0); |
| 267 | 267 | ||
diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index 7394c844f..c9f9e9d95 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp | |||
| @@ -347,7 +347,7 @@ void GetVsyncInterruptEvent(Service::Interface* self) { | |||
| 347 | int port = *port_select.begin(); | 347 | int port = *port_select.begin(); |
| 348 | rb.Push(RESULT_SUCCESS); | 348 | rb.Push(RESULT_SUCCESS); |
| 349 | rb.PushCopyHandles( | 349 | rb.PushCopyHandles( |
| 350 | Kernel::g_handle_table.Create(ports[port].vsync_interrupt_event).MoveFrom()); | 350 | Kernel::g_handle_table.Create(ports[port].vsync_interrupt_event).Unwrap()); |
| 351 | } else { | 351 | } else { |
| 352 | LOG_ERROR(Service_CAM, "invalid port_select=%u", port_select.m_val); | 352 | LOG_ERROR(Service_CAM, "invalid port_select=%u", port_select.m_val); |
| 353 | rb.Push(ERROR_INVALID_ENUM_VALUE); | 353 | rb.Push(ERROR_INVALID_ENUM_VALUE); |
| @@ -366,7 +366,7 @@ void GetBufferErrorInterruptEvent(Service::Interface* self) { | |||
| 366 | int port = *port_select.begin(); | 366 | int port = *port_select.begin(); |
| 367 | rb.Push(RESULT_SUCCESS); | 367 | rb.Push(RESULT_SUCCESS); |
| 368 | rb.PushCopyHandles( | 368 | rb.PushCopyHandles( |
| 369 | Kernel::g_handle_table.Create(ports[port].buffer_error_interrupt_event).MoveFrom()); | 369 | Kernel::g_handle_table.Create(ports[port].buffer_error_interrupt_event).Unwrap()); |
| 370 | } else { | 370 | } else { |
| 371 | LOG_ERROR(Service_CAM, "invalid port_select=%u", port_select.m_val); | 371 | LOG_ERROR(Service_CAM, "invalid port_select=%u", port_select.m_val); |
| 372 | rb.Push(ERROR_INVALID_ENUM_VALUE); | 372 | rb.Push(ERROR_INVALID_ENUM_VALUE); |
| @@ -400,7 +400,7 @@ void SetReceiving(Service::Interface* self) { | |||
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | rb.Push(RESULT_SUCCESS); | 402 | rb.Push(RESULT_SUCCESS); |
| 403 | rb.PushCopyHandles(Kernel::g_handle_table.Create(port.completion_event).MoveFrom()); | 403 | rb.PushCopyHandles(Kernel::g_handle_table.Create(port.completion_event).Unwrap()); |
| 404 | } else { | 404 | } else { |
| 405 | LOG_ERROR(Service_CAM, "invalid port_select=%u", port_select.m_val); | 405 | LOG_ERROR(Service_CAM, "invalid port_select=%u", port_select.m_val); |
| 406 | rb.Push(ERROR_INVALID_ENUM_VALUE); | 406 | rb.Push(ERROR_INVALID_ENUM_VALUE); |
diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index bd9814244..421006a9e 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp | |||
| @@ -31,8 +31,8 @@ void GetCecStateAbbreviated(Service::Interface* self) { | |||
| 31 | void GetCecInfoEventHandle(Service::Interface* self) { | 31 | void GetCecInfoEventHandle(Service::Interface* self) { |
| 32 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 32 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 33 | 33 | ||
| 34 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 34 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 35 | cmd_buff[3] = Kernel::g_handle_table.Create(cecinfo_event).MoveFrom(); // Event handle | 35 | cmd_buff[3] = Kernel::g_handle_table.Create(cecinfo_event).Unwrap(); // Event handle |
| 36 | 36 | ||
| 37 | LOG_WARNING(Service_CECD, "(STUBBED) called"); | 37 | LOG_WARNING(Service_CECD, "(STUBBED) called"); |
| 38 | } | 38 | } |
| @@ -40,8 +40,8 @@ void GetCecInfoEventHandle(Service::Interface* self) { | |||
| 40 | void GetChangeStateEventHandle(Service::Interface* self) { | 40 | void GetChangeStateEventHandle(Service::Interface* self) { |
| 41 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 41 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 42 | 42 | ||
| 43 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 43 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 44 | cmd_buff[3] = Kernel::g_handle_table.Create(change_state_event).MoveFrom(); // Event handle | 44 | cmd_buff[3] = Kernel::g_handle_table.Create(change_state_event).Unwrap(); // Event handle |
| 45 | 45 | ||
| 46 | LOG_WARNING(Service_CECD, "(STUBBED) called"); | 46 | LOG_WARNING(Service_CECD, "(STUBBED) called"); |
| 47 | } | 47 | } |
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 5a7878b31..6624f1711 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp | |||
| @@ -406,7 +406,7 @@ ResultCode UpdateConfigNANDSavegame() { | |||
| 406 | auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode); | 406 | auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode); |
| 407 | ASSERT_MSG(config_result.Succeeded(), "could not open file"); | 407 | ASSERT_MSG(config_result.Succeeded(), "could not open file"); |
| 408 | 408 | ||
| 409 | auto config = config_result.MoveFrom(); | 409 | auto config = std::move(config_result).Unwrap(); |
| 410 | config->backend->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data()); | 410 | config->backend->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data()); |
| 411 | 411 | ||
| 412 | return RESULT_SUCCESS; | 412 | return RESULT_SUCCESS; |
| @@ -560,7 +560,7 @@ ResultCode LoadConfigNANDSaveFile() { | |||
| 560 | 560 | ||
| 561 | // Read the file if it already exists | 561 | // Read the file if it already exists |
| 562 | if (config_result.Succeeded()) { | 562 | if (config_result.Succeeded()) { |
| 563 | auto config = config_result.MoveFrom(); | 563 | auto config = std::move(config_result).Unwrap(); |
| 564 | config->backend->Read(0, CONFIG_SAVEFILE_SIZE, cfg_config_file_buffer.data()); | 564 | config->backend->Read(0, CONFIG_SAVEFILE_SIZE, cfg_config_file_buffer.data()); |
| 565 | return RESULT_SUCCESS; | 565 | return RESULT_SUCCESS; |
| 566 | } | 566 | } |
diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp index 1455f20ca..9471ec1ef 100644 --- a/src/core/hle/service/csnd_snd.cpp +++ b/src/core/hle/service/csnd_snd.cpp | |||
| @@ -51,8 +51,8 @@ static void Initialize(Interface* self) { | |||
| 51 | 51 | ||
| 52 | cmd_buff[1] = RESULT_SUCCESS.raw; | 52 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 53 | cmd_buff[2] = IPC::CopyHandleDesc(2); | 53 | cmd_buff[2] = IPC::CopyHandleDesc(2); |
| 54 | cmd_buff[3] = Kernel::g_handle_table.Create(mutex).MoveFrom(); | 54 | cmd_buff[3] = Kernel::g_handle_table.Create(mutex).Unwrap(); |
| 55 | cmd_buff[4] = Kernel::g_handle_table.Create(shared_memory).MoveFrom(); | 55 | cmd_buff[4] = Kernel::g_handle_table.Create(shared_memory).Unwrap(); |
| 56 | 56 | ||
| 57 | LOG_WARNING(Service_CSND, "(STUBBED) called"); | 57 | LOG_WARNING(Service_CSND, "(STUBBED) called"); |
| 58 | } | 58 | } |
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index 363066d14..7d746054f 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp | |||
| @@ -168,7 +168,7 @@ static void GetSemaphoreEventHandle(Service::Interface* self) { | |||
| 168 | cmd_buff[0] = IPC::MakeHeader(0x16, 1, 2); | 168 | cmd_buff[0] = IPC::MakeHeader(0x16, 1, 2); |
| 169 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 169 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 170 | // cmd_buff[2] not set | 170 | // cmd_buff[2] not set |
| 171 | cmd_buff[3] = Kernel::g_handle_table.Create(semaphore_event).MoveFrom(); // Event handle | 171 | cmd_buff[3] = Kernel::g_handle_table.Create(semaphore_event).Unwrap(); // Event handle |
| 172 | 172 | ||
| 173 | LOG_WARNING(Service_DSP, "(STUBBED) called"); | 173 | LOG_WARNING(Service_DSP, "(STUBBED) called"); |
| 174 | } | 174 | } |
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 3605ef175..033fbc9aa 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp | |||
| @@ -311,7 +311,7 @@ ResultVal<std::shared_ptr<File>> OpenFileFromArchive(ArchiveHandle archive_handl | |||
| 311 | if (backend.Failed()) | 311 | if (backend.Failed()) |
| 312 | return backend.Code(); | 312 | return backend.Code(); |
| 313 | 313 | ||
| 314 | auto file = std::shared_ptr<File>(new File(backend.MoveFrom(), path)); | 314 | auto file = std::shared_ptr<File>(new File(std::move(backend).Unwrap(), path)); |
| 315 | return MakeResult<std::shared_ptr<File>>(std::move(file)); | 315 | return MakeResult<std::shared_ptr<File>>(std::move(file)); |
| 316 | } | 316 | } |
| 317 | 317 | ||
| @@ -401,7 +401,7 @@ ResultVal<std::shared_ptr<Directory>> OpenDirectoryFromArchive(ArchiveHandle arc | |||
| 401 | if (backend.Failed()) | 401 | if (backend.Failed()) |
| 402 | return backend.Code(); | 402 | return backend.Code(); |
| 403 | 403 | ||
| 404 | auto directory = std::shared_ptr<Directory>(new Directory(backend.MoveFrom(), path)); | 404 | auto directory = std::shared_ptr<Directory>(new Directory(std::move(backend).Unwrap(), path)); |
| 405 | return MakeResult<std::shared_ptr<Directory>>(std::move(directory)); | 405 | return MakeResult<std::shared_ptr<Directory>>(std::move(directory)); |
| 406 | } | 406 | } |
| 407 | 407 | ||
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 34e1783ec..b9eab7838 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp | |||
| @@ -87,7 +87,7 @@ static void OpenFile(Service::Interface* self) { | |||
| 87 | file->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); | 87 | file->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); |
| 88 | 88 | ||
| 89 | rb.PushMoveHandles( | 89 | rb.PushMoveHandles( |
| 90 | Kernel::g_handle_table.Create(std::get<SharedPtr<ClientSession>>(sessions)).MoveFrom()); | 90 | Kernel::g_handle_table.Create(std::get<SharedPtr<ClientSession>>(sessions)).Unwrap()); |
| 91 | } else { | 91 | } else { |
| 92 | rb.PushMoveHandles(0); | 92 | rb.PushMoveHandles(0); |
| 93 | LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); | 93 | LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); |
| @@ -153,7 +153,7 @@ static void OpenFileDirectly(Service::Interface* self) { | |||
| 153 | file->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); | 153 | file->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); |
| 154 | 154 | ||
| 155 | cmd_buff[3] = | 155 | cmd_buff[3] = |
| 156 | Kernel::g_handle_table.Create(std::get<SharedPtr<ClientSession>>(sessions)).MoveFrom(); | 156 | Kernel::g_handle_table.Create(std::get<SharedPtr<ClientSession>>(sessions)).Unwrap(); |
| 157 | } else { | 157 | } else { |
| 158 | cmd_buff[3] = 0; | 158 | cmd_buff[3] = 0; |
| 159 | LOG_ERROR(Service_FS, "failed to get a handle for file %s mode=%u attributes=%u", | 159 | LOG_ERROR(Service_FS, "failed to get a handle for file %s mode=%u attributes=%u", |
| @@ -420,7 +420,7 @@ static void OpenDirectory(Service::Interface* self) { | |||
| 420 | directory->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); | 420 | directory->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); |
| 421 | 421 | ||
| 422 | cmd_buff[3] = | 422 | cmd_buff[3] = |
| 423 | Kernel::g_handle_table.Create(std::get<SharedPtr<ClientSession>>(sessions)).MoveFrom(); | 423 | Kernel::g_handle_table.Create(std::get<SharedPtr<ClientSession>>(sessions)).Unwrap(); |
| 424 | } else { | 424 | } else { |
| 425 | LOG_ERROR(Service_FS, "failed to get a handle for directory type=%d size=%d data=%s", | 425 | LOG_ERROR(Service_FS, "failed to get a handle for directory type=%d size=%d data=%s", |
| 426 | dirname_type, dirname_size, dir_path.DebugStr().c_str()); | 426 | dirname_type, dirname_size, dir_path.DebugStr().c_str()); |
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 6ff0f4812..bc964ec60 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp | |||
| @@ -389,8 +389,8 @@ static void RegisterInterruptRelayQueue(Interface* self) { | |||
| 389 | } else { | 389 | } else { |
| 390 | cmd_buff[1] = RESULT_SUCCESS.raw; | 390 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 391 | } | 391 | } |
| 392 | cmd_buff[2] = g_thread_id++; // Thread ID | 392 | cmd_buff[2] = g_thread_id++; // Thread ID |
| 393 | cmd_buff[4] = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); // GSP shared memory | 393 | cmd_buff[4] = Kernel::g_handle_table.Create(g_shared_memory).Unwrap(); // GSP shared memory |
| 394 | 394 | ||
| 395 | g_interrupt_event->Signal(); // TODO(bunnei): Is this correct? | 395 | g_interrupt_event->Signal(); // TODO(bunnei): Is this correct? |
| 396 | 396 | ||
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 5255f6dc8..2014b8461 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -253,12 +253,12 @@ void GetIPCHandles(Service::Interface* self) { | |||
| 253 | cmd_buff[1] = 0; // No error | 253 | cmd_buff[1] = 0; // No error |
| 254 | cmd_buff[2] = 0x14000000; // IPC Command Structure translate-header | 254 | cmd_buff[2] = 0x14000000; // IPC Command Structure translate-header |
| 255 | // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling) | 255 | // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling) |
| 256 | cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).MoveFrom(); | 256 | cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).Unwrap(); |
| 257 | cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_1).MoveFrom(); | 257 | cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_1).Unwrap(); |
| 258 | cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_2).MoveFrom(); | 258 | cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_2).Unwrap(); |
| 259 | cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::event_accelerometer).MoveFrom(); | 259 | cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::event_accelerometer).Unwrap(); |
| 260 | cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::event_gyroscope).MoveFrom(); | 260 | cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::event_gyroscope).Unwrap(); |
| 261 | cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::event_debug_pad).MoveFrom(); | 261 | cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::event_debug_pad).Unwrap(); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | void EnableAccelerometer(Service::Interface* self) { | 264 | void EnableAccelerometer(Service::Interface* self) { |
diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 0de698003..837413f93 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp | |||
| @@ -145,8 +145,8 @@ static void GetHandles(Interface* self) { | |||
| 145 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x01, 0, 0); | 145 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x01, 0, 0); |
| 146 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); | 146 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); |
| 147 | rb.Push(RESULT_SUCCESS); | 147 | rb.Push(RESULT_SUCCESS); |
| 148 | rb.PushMoveHandles(Kernel::g_handle_table.Create(Service::IR::shared_memory).MoveFrom(), | 148 | rb.PushMoveHandles(Kernel::g_handle_table.Create(Service::IR::shared_memory).Unwrap(), |
| 149 | Kernel::g_handle_table.Create(Service::IR::update_event).MoveFrom()); | 149 | Kernel::g_handle_table.Create(Service::IR::update_event).Unwrap()); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | /** | 152 | /** |
diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index fdecdce64..fbdf7a465 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp | |||
| @@ -337,7 +337,7 @@ void GetReceiveEvent(Interface* self) { | |||
| 337 | IPC::RequestBuilder rb(Kernel::GetCommandBuffer(), 0x0A, 1, 2); | 337 | IPC::RequestBuilder rb(Kernel::GetCommandBuffer(), 0x0A, 1, 2); |
| 338 | 338 | ||
| 339 | rb.Push(RESULT_SUCCESS); | 339 | rb.Push(RESULT_SUCCESS); |
| 340 | rb.PushCopyHandles(Kernel::g_handle_table.Create(Service::IR::receive_event).MoveFrom()); | 340 | rb.PushCopyHandles(Kernel::g_handle_table.Create(Service::IR::receive_event).Unwrap()); |
| 341 | 341 | ||
| 342 | LOG_INFO(Service_IR, "called"); | 342 | LOG_INFO(Service_IR, "called"); |
| 343 | } | 343 | } |
| @@ -354,7 +354,7 @@ void GetSendEvent(Interface* self) { | |||
| 354 | IPC::RequestBuilder rb(Kernel::GetCommandBuffer(), 0x0B, 1, 2); | 354 | IPC::RequestBuilder rb(Kernel::GetCommandBuffer(), 0x0B, 1, 2); |
| 355 | 355 | ||
| 356 | rb.Push(RESULT_SUCCESS); | 356 | rb.Push(RESULT_SUCCESS); |
| 357 | rb.PushCopyHandles(Kernel::g_handle_table.Create(Service::IR::send_event).MoveFrom()); | 357 | rb.PushCopyHandles(Kernel::g_handle_table.Create(Service::IR::send_event).Unwrap()); |
| 358 | 358 | ||
| 359 | LOG_INFO(Service_IR, "called"); | 359 | LOG_INFO(Service_IR, "called"); |
| 360 | } | 360 | } |
| @@ -394,7 +394,7 @@ static void GetConnectionStatusEvent(Interface* self) { | |||
| 394 | IPC::RequestBuilder rb(Kernel::GetCommandBuffer(), 0x0C, 1, 2); | 394 | IPC::RequestBuilder rb(Kernel::GetCommandBuffer(), 0x0C, 1, 2); |
| 395 | 395 | ||
| 396 | rb.Push(RESULT_SUCCESS); | 396 | rb.Push(RESULT_SUCCESS); |
| 397 | rb.PushCopyHandles(Kernel::g_handle_table.Create(Service::IR::conn_status_event).MoveFrom()); | 397 | rb.PushCopyHandles(Kernel::g_handle_table.Create(Service::IR::conn_status_event).Unwrap()); |
| 398 | 398 | ||
| 399 | LOG_INFO(Service_IR, "called"); | 399 | LOG_INFO(Service_IR, "called"); |
| 400 | } | 400 | } |
diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 35212b59b..23e1ff094 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp | |||
| @@ -160,7 +160,7 @@ static void IsSampling(Interface* self) { | |||
| 160 | static void GetBufferFullEvent(Interface* self) { | 160 | static void GetBufferFullEvent(Interface* self) { |
| 161 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 161 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 162 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 162 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 163 | cmd_buff[3] = Kernel::g_handle_table.Create(buffer_full_event).MoveFrom(); | 163 | cmd_buff[3] = Kernel::g_handle_table.Create(buffer_full_event).Unwrap(); |
| 164 | LOG_WARNING(Service_MIC, "(STUBBED) called"); | 164 | LOG_WARNING(Service_MIC, "(STUBBED) called"); |
| 165 | } | 165 | } |
| 166 | 166 | ||
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index b44a9f668..cb09ed0b7 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp | |||
| @@ -95,7 +95,7 @@ void GetTagInRangeEvent(Interface* self) { | |||
| 95 | cmd_buff[0] = IPC::MakeHeader(0xB, 1, 2); | 95 | cmd_buff[0] = IPC::MakeHeader(0xB, 1, 2); |
| 96 | cmd_buff[1] = RESULT_SUCCESS.raw; | 96 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 97 | cmd_buff[2] = IPC::CopyHandleDesc(); | 97 | cmd_buff[2] = IPC::CopyHandleDesc(); |
| 98 | cmd_buff[3] = Kernel::g_handle_table.Create(tag_in_range_event).MoveFrom(); | 98 | cmd_buff[3] = Kernel::g_handle_table.Create(tag_in_range_event).Unwrap(); |
| 99 | LOG_WARNING(Service_NFC, "(STUBBED) called"); | 99 | LOG_WARNING(Service_NFC, "(STUBBED) called"); |
| 100 | } | 100 | } |
| 101 | 101 | ||
| @@ -105,7 +105,7 @@ void GetTagOutOfRangeEvent(Interface* self) { | |||
| 105 | cmd_buff[0] = IPC::MakeHeader(0xC, 1, 2); | 105 | cmd_buff[0] = IPC::MakeHeader(0xC, 1, 2); |
| 106 | cmd_buff[1] = RESULT_SUCCESS.raw; | 106 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 107 | cmd_buff[2] = IPC::CopyHandleDesc(); | 107 | cmd_buff[2] = IPC::CopyHandleDesc(); |
| 108 | cmd_buff[3] = Kernel::g_handle_table.Create(tag_out_of_range_event).MoveFrom(); | 108 | cmd_buff[3] = Kernel::g_handle_table.Create(tag_out_of_range_event).Unwrap(); |
| 109 | LOG_WARNING(Service_NFC, "(STUBBED) called"); | 109 | LOG_WARNING(Service_NFC, "(STUBBED) called"); |
| 110 | } | 110 | } |
| 111 | 111 | ||
diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index e92900d48..a7149c9e8 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp | |||
| @@ -190,7 +190,7 @@ static void InitializeWithVersion(Interface* self) { | |||
| 190 | 190 | ||
| 191 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | 191 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |
| 192 | rb.Push(RESULT_SUCCESS); | 192 | rb.Push(RESULT_SUCCESS); |
| 193 | rb.PushCopyHandles(Kernel::g_handle_table.Create(connection_status_event).MoveFrom()); | 193 | rb.PushCopyHandles(Kernel::g_handle_table.Create(connection_status_event).Unwrap()); |
| 194 | 194 | ||
| 195 | LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X, sharedmem_handle=0x%08X", | 195 | LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X, sharedmem_handle=0x%08X", |
| 196 | sharedmem_size, version, sharedmem_handle); | 196 | sharedmem_size, version, sharedmem_handle); |
| @@ -265,7 +265,7 @@ static void Bind(Interface* self) { | |||
| 265 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | 265 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |
| 266 | 266 | ||
| 267 | rb.Push(RESULT_SUCCESS); | 267 | rb.Push(RESULT_SUCCESS); |
| 268 | rb.PushCopyHandles(Kernel::g_handle_table.Create(event).MoveFrom()); | 268 | rb.PushCopyHandles(Kernel::g_handle_table.Create(event).Unwrap()); |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | /** | 271 | /** |
| @@ -543,6 +543,42 @@ static void BeaconBroadcastCallback(u64 userdata, int cycles_late) { | |||
| 543 | beacon_broadcast_event, 0); | 543 | beacon_broadcast_event, 0); |
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | /* | ||
| 547 | * Returns an available index in the nodes array for the | ||
| 548 | * currently-hosted UDS network. | ||
| 549 | */ | ||
| 550 | static u32 GetNextAvailableNodeId() { | ||
| 551 | ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost), | ||
| 552 | "Can not accept clients if we're not hosting a network"); | ||
| 553 | |||
| 554 | for (unsigned index = 0; index < connection_status.max_nodes; ++index) { | ||
| 555 | if ((connection_status.node_bitmask & (1 << index)) == 0) | ||
| 556 | return index; | ||
| 557 | } | ||
| 558 | |||
| 559 | // Any connection attempts to an already full network should have been refused. | ||
| 560 | ASSERT_MSG(false, "No available connection slots in the network"); | ||
| 561 | } | ||
| 562 | |||
| 563 | /* | ||
| 564 | * Called when a client connects to an UDS network we're hosting, | ||
| 565 | * updates the connection status and signals the update event. | ||
| 566 | * @param network_node_id Network Node Id of the connecting client. | ||
| 567 | */ | ||
| 568 | void OnClientConnected(u16 network_node_id) { | ||
| 569 | ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost), | ||
| 570 | "Can not accept clients if we're not hosting a network"); | ||
| 571 | ASSERT_MSG(connection_status.total_nodes < connection_status.max_nodes, | ||
| 572 | "Can not accept connections on a full network"); | ||
| 573 | |||
| 574 | u32 node_id = GetNextAvailableNodeId(); | ||
| 575 | connection_status.node_bitmask |= 1 << node_id; | ||
| 576 | connection_status.changed_nodes |= 1 << node_id; | ||
| 577 | connection_status.nodes[node_id] = network_node_id; | ||
| 578 | connection_status.total_nodes++; | ||
| 579 | connection_status_event->Signal(); | ||
| 580 | } | ||
| 581 | |||
| 546 | const Interface::FunctionInfo FunctionTable[] = { | 582 | const Interface::FunctionInfo FunctionTable[] = { |
| 547 | {0x00010442, nullptr, "Initialize (deprecated)"}, | 583 | {0x00010442, nullptr, "Initialize (deprecated)"}, |
| 548 | {0x00020000, nullptr, "Scrap"}, | 584 | {0x00020000, nullptr, "Scrap"}, |
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 39382ef09..a0b959797 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp | |||
| @@ -152,7 +152,7 @@ void Init() { | |||
| 152 | auto gamecoin_result = | 152 | auto gamecoin_result = |
| 153 | Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); | 153 | Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); |
| 154 | if (gamecoin_result.Succeeded()) { | 154 | if (gamecoin_result.Succeeded()) { |
| 155 | auto gamecoin = gamecoin_result.MoveFrom(); | 155 | auto gamecoin = std::move(gamecoin_result).Unwrap(); |
| 156 | gamecoin->backend->Write(0, sizeof(GameCoin), true, | 156 | gamecoin->backend->Write(0, sizeof(GameCoin), true, |
| 157 | reinterpret_cast<const u8*>(&default_game_coin)); | 157 | reinterpret_cast<const u8*>(&default_game_coin)); |
| 158 | gamecoin->backend->Close(); | 158 | gamecoin->backend->Close(); |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 791a65c19..aad950e50 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -173,8 +173,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_ses | |||
| 173 | 173 | ||
| 174 | // TODO(yuriks): The kernel should be the one handling this as part of translation after | 174 | // TODO(yuriks): The kernel should be the one handling this as part of translation after |
| 175 | // everything else is migrated | 175 | // everything else is migrated |
| 176 | Kernel::HLERequestContext context; | 176 | Kernel::HLERequestContext context(std::move(server_session)); |
| 177 | context.session = std::move(server_session); | ||
| 178 | context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process, | 177 | context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process, |
| 179 | Kernel::g_handle_table); | 178 | Kernel::g_handle_table); |
| 180 | 179 | ||
| @@ -207,7 +206,7 @@ void AddService(Interface* interface_) { | |||
| 207 | auto server_port = | 206 | auto server_port = |
| 208 | SM::g_service_manager | 207 | SM::g_service_manager |
| 209 | ->RegisterService(interface_->GetPortName(), interface_->GetMaxSessions()) | 208 | ->RegisterService(interface_->GetPortName(), interface_->GetMaxSessions()) |
| 210 | .MoveFrom(); | 209 | .Unwrap(); |
| 211 | server_port->SetHleHandler(std::shared_ptr<Interface>(interface_)); | 210 | server_port->SetHleHandler(std::shared_ptr<Interface>(interface_)); |
| 212 | } | 211 | } |
| 213 | 212 | ||
diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 74a1256e0..352941e69 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp | |||
| @@ -113,13 +113,13 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { | |||
| 113 | (*session)->GetObjectId()); | 113 | (*session)->GetObjectId()); |
| 114 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | 114 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |
| 115 | rb.Push(session.Code()); | 115 | rb.Push(session.Code()); |
| 116 | rb.PushObjects(session.MoveFrom()); | 116 | rb.PushObjects(std::move(session).Unwrap()); |
| 117 | } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED && return_port_on_failure) { | 117 | } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED && return_port_on_failure) { |
| 118 | LOG_WARNING(Service_SRV, "called service=%s -> ERR_MAX_CONNECTIONS_REACHED, *port*=%u", | 118 | LOG_WARNING(Service_SRV, "called service=%s -> ERR_MAX_CONNECTIONS_REACHED, *port*=%u", |
| 119 | name.c_str(), (*client_port)->GetObjectId()); | 119 | name.c_str(), (*client_port)->GetObjectId()); |
| 120 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | 120 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |
| 121 | rb.Push(ERR_MAX_CONNECTIONS_REACHED); | 121 | rb.Push(ERR_MAX_CONNECTIONS_REACHED); |
| 122 | rb.PushObjects(client_port.MoveFrom()); | 122 | rb.PushObjects(std::move(client_port).Unwrap()); |
| 123 | } else { | 123 | } else { |
| 124 | LOG_ERROR(Service_SRV, "called service=%s -> error 0x%08X", name.c_str(), session.Code()); | 124 | LOG_ERROR(Service_SRV, "called service=%s -> error 0x%08X", name.c_str(), session.Code()); |
| 125 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | 125 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index bb7bf2d67..e73971d5f 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp | |||
| @@ -275,7 +275,7 @@ static void GetTransferEndEvent(Interface* self) { | |||
| 275 | 275 | ||
| 276 | cmd_buff[0] = IPC::MakeHeader(0xF, 2, 0); | 276 | cmd_buff[0] = IPC::MakeHeader(0xF, 2, 0); |
| 277 | cmd_buff[1] = RESULT_SUCCESS.raw; | 277 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 278 | cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom(); | 278 | cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).Unwrap(); |
| 279 | 279 | ||
| 280 | LOG_DEBUG(Service_Y2R, "called"); | 280 | LOG_DEBUG(Service_Y2R, "called"); |
| 281 | } | 281 | } |
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 00d7c636a..a14df325a 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | set(SRCS | 1 | set(SRCS |
| 2 | glad.cpp | ||
| 3 | tests.cpp | ||
| 4 | common/param_package.cpp | 2 | common/param_package.cpp |
| 5 | core/file_sys/path_parser.cpp | 3 | core/file_sys/path_parser.cpp |
| 4 | core/hle/kernel/hle_ipc.cpp | ||
| 5 | glad.cpp | ||
| 6 | tests.cpp | ||
| 6 | ) | 7 | ) |
| 7 | 8 | ||
| 8 | set(HEADERS | 9 | set(HEADERS |
diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp new file mode 100644 index 000000000..e07a28c5b --- /dev/null +++ b/src/tests/core/hle/kernel/hle_ipc.cpp | |||
| @@ -0,0 +1,193 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <catch.hpp> | ||
| 6 | #include "core/hle/ipc.h" | ||
| 7 | #include "core/hle/kernel/client_port.h" | ||
| 8 | #include "core/hle/kernel/client_session.h" | ||
| 9 | #include "core/hle/kernel/event.h" | ||
| 10 | #include "core/hle/kernel/handle_table.h" | ||
| 11 | #include "core/hle/kernel/hle_ipc.h" | ||
| 12 | #include "core/hle/kernel/process.h" | ||
| 13 | #include "core/hle/kernel/server_session.h" | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | |||
| 17 | static SharedPtr<Object> MakeObject() { | ||
| 18 | return Event::Create(ResetType::OneShot); | ||
| 19 | } | ||
| 20 | |||
| 21 | TEST_CASE("HLERequestContext::PopoulateFromIncomingCommandBuffer", "[core][kernel]") { | ||
| 22 | auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair()); | ||
| 23 | HLERequestContext context(std::move(session)); | ||
| 24 | |||
| 25 | auto process = Process::Create(CodeSet::Create("", 0)); | ||
| 26 | HandleTable handle_table; | ||
| 27 | |||
| 28 | SECTION("works with empty cmdbuf") { | ||
| 29 | const u32_le input[]{ | ||
| 30 | IPC::MakeHeader(0x1234, 0, 0), | ||
| 31 | }; | ||
| 32 | |||
| 33 | context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||
| 34 | |||
| 35 | REQUIRE(context.CommandBuffer()[0] == 0x12340000); | ||
| 36 | } | ||
| 37 | |||
| 38 | SECTION("translates regular params") { | ||
| 39 | const u32_le input[]{ | ||
| 40 | IPC::MakeHeader(0, 3, 0), 0x12345678, 0x21122112, 0xAABBCCDD, | ||
| 41 | }; | ||
| 42 | |||
| 43 | context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||
| 44 | |||
| 45 | auto* output = context.CommandBuffer(); | ||
| 46 | REQUIRE(output[1] == 0x12345678); | ||
| 47 | REQUIRE(output[2] == 0x21122112); | ||
| 48 | REQUIRE(output[3] == 0xAABBCCDD); | ||
| 49 | } | ||
| 50 | |||
| 51 | SECTION("translates move handles") { | ||
| 52 | auto a = MakeObject(); | ||
| 53 | Handle a_handle = handle_table.Create(a).Unwrap(); | ||
| 54 | const u32_le input[]{ | ||
| 55 | IPC::MakeHeader(0, 0, 2), IPC::MoveHandleDesc(1), a_handle, | ||
| 56 | }; | ||
| 57 | |||
| 58 | context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||
| 59 | |||
| 60 | auto* output = context.CommandBuffer(); | ||
| 61 | REQUIRE(context.GetIncomingHandle(output[2]) == a); | ||
| 62 | REQUIRE(handle_table.GetGeneric(a_handle) == nullptr); | ||
| 63 | } | ||
| 64 | |||
| 65 | SECTION("translates copy handles") { | ||
| 66 | auto a = MakeObject(); | ||
| 67 | Handle a_handle = handle_table.Create(a).Unwrap(); | ||
| 68 | const u32_le input[]{ | ||
| 69 | IPC::MakeHeader(0, 0, 2), IPC::CopyHandleDesc(1), a_handle, | ||
| 70 | }; | ||
| 71 | |||
| 72 | context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||
| 73 | |||
| 74 | auto* output = context.CommandBuffer(); | ||
| 75 | REQUIRE(context.GetIncomingHandle(output[2]) == a); | ||
| 76 | REQUIRE(handle_table.GetGeneric(a_handle) == a); | ||
| 77 | } | ||
| 78 | |||
| 79 | SECTION("translates multi-handle descriptors") { | ||
| 80 | auto a = MakeObject(); | ||
| 81 | auto b = MakeObject(); | ||
| 82 | auto c = MakeObject(); | ||
| 83 | const u32_le input[]{ | ||
| 84 | IPC::MakeHeader(0, 0, 5), IPC::MoveHandleDesc(2), | ||
| 85 | handle_table.Create(a).Unwrap(), handle_table.Create(b).Unwrap(), | ||
| 86 | IPC::MoveHandleDesc(1), handle_table.Create(c).Unwrap(), | ||
| 87 | }; | ||
| 88 | |||
| 89 | context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||
| 90 | |||
| 91 | auto* output = context.CommandBuffer(); | ||
| 92 | REQUIRE(context.GetIncomingHandle(output[2]) == a); | ||
| 93 | REQUIRE(context.GetIncomingHandle(output[3]) == b); | ||
| 94 | REQUIRE(context.GetIncomingHandle(output[5]) == c); | ||
| 95 | } | ||
| 96 | |||
| 97 | SECTION("translates CallingPid descriptors") { | ||
| 98 | const u32_le input[]{ | ||
| 99 | IPC::MakeHeader(0, 0, 2), IPC::CallingPidDesc(), 0x98989898, | ||
| 100 | }; | ||
| 101 | |||
| 102 | context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||
| 103 | |||
| 104 | REQUIRE(context.CommandBuffer()[2] == process->process_id); | ||
| 105 | } | ||
| 106 | |||
| 107 | SECTION("translates mixed params") { | ||
| 108 | auto a = MakeObject(); | ||
| 109 | const u32_le input[]{ | ||
| 110 | IPC::MakeHeader(0, 2, 4), | ||
| 111 | 0x12345678, | ||
| 112 | 0xABCDEF00, | ||
| 113 | IPC::MoveHandleDesc(1), | ||
| 114 | handle_table.Create(a).Unwrap(), | ||
| 115 | IPC::CallingPidDesc(), | ||
| 116 | 0, | ||
| 117 | }; | ||
| 118 | |||
| 119 | context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); | ||
| 120 | |||
| 121 | auto* output = context.CommandBuffer(); | ||
| 122 | REQUIRE(output[1] == 0x12345678); | ||
| 123 | REQUIRE(output[2] == 0xABCDEF00); | ||
| 124 | REQUIRE(context.GetIncomingHandle(output[4]) == a); | ||
| 125 | REQUIRE(output[6] == process->process_id); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { | ||
| 130 | auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair()); | ||
| 131 | HLERequestContext context(std::move(session)); | ||
| 132 | |||
| 133 | auto process = Process::Create(CodeSet::Create("", 0)); | ||
| 134 | HandleTable handle_table; | ||
| 135 | auto* input = context.CommandBuffer(); | ||
| 136 | u32_le output[IPC::COMMAND_BUFFER_LENGTH]; | ||
| 137 | |||
| 138 | SECTION("works with empty cmdbuf") { | ||
| 139 | input[0] = IPC::MakeHeader(0x1234, 0, 0); | ||
| 140 | |||
| 141 | context.WriteToOutgoingCommandBuffer(output, *process, handle_table); | ||
| 142 | |||
| 143 | REQUIRE(output[0] == 0x12340000); | ||
| 144 | } | ||
| 145 | |||
| 146 | SECTION("translates regular params") { | ||
| 147 | input[0] = IPC::MakeHeader(0, 3, 0); | ||
| 148 | input[1] = 0x12345678; | ||
| 149 | input[2] = 0x21122112; | ||
| 150 | input[3] = 0xAABBCCDD; | ||
| 151 | |||
| 152 | context.WriteToOutgoingCommandBuffer(output, *process, handle_table); | ||
| 153 | |||
| 154 | REQUIRE(output[1] == 0x12345678); | ||
| 155 | REQUIRE(output[2] == 0x21122112); | ||
| 156 | REQUIRE(output[3] == 0xAABBCCDD); | ||
| 157 | } | ||
| 158 | |||
| 159 | SECTION("translates move/copy handles") { | ||
| 160 | auto a = MakeObject(); | ||
| 161 | auto b = MakeObject(); | ||
| 162 | input[0] = IPC::MakeHeader(0, 0, 4); | ||
| 163 | input[1] = IPC::MoveHandleDesc(1); | ||
| 164 | input[2] = context.AddOutgoingHandle(a); | ||
| 165 | input[3] = IPC::CopyHandleDesc(1); | ||
| 166 | input[4] = context.AddOutgoingHandle(b); | ||
| 167 | |||
| 168 | context.WriteToOutgoingCommandBuffer(output, *process, handle_table); | ||
| 169 | |||
| 170 | REQUIRE(handle_table.GetGeneric(output[2]) == a); | ||
| 171 | REQUIRE(handle_table.GetGeneric(output[4]) == b); | ||
| 172 | } | ||
| 173 | |||
| 174 | SECTION("translates multi-handle descriptors") { | ||
| 175 | auto a = MakeObject(); | ||
| 176 | auto b = MakeObject(); | ||
| 177 | auto c = MakeObject(); | ||
| 178 | input[0] = IPC::MakeHeader(0, 0, 5); | ||
| 179 | input[1] = IPC::MoveHandleDesc(2); | ||
| 180 | input[2] = context.AddOutgoingHandle(a); | ||
| 181 | input[3] = context.AddOutgoingHandle(b); | ||
| 182 | input[4] = IPC::CopyHandleDesc(1); | ||
| 183 | input[5] = context.AddOutgoingHandle(c); | ||
| 184 | |||
| 185 | context.WriteToOutgoingCommandBuffer(output, *process, handle_table); | ||
| 186 | |||
| 187 | REQUIRE(handle_table.GetGeneric(output[2]) == a); | ||
| 188 | REQUIRE(handle_table.GetGeneric(output[3]) == b); | ||
| 189 | REQUIRE(handle_table.GetGeneric(output[5]) == c); | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | } // namespace Kernel | ||