diff --git a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp index e0e5956fe..f7024bdc2 100644 --- a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp +++ b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp @@ -24,15 +24,15 @@ namespace sts::dmnt::cheat { /* ==================================== Meta Commands ==================================== */ /* ========================================================================================= */ - void CheatService::HasCheatProcess(Out out) { + void CheatService::HasCheatProcess(sf::Out out) { out.SetValue(dmnt::cheat::impl::GetHasActiveCheatProcess()); } - void CheatService::GetCheatProcessEvent(Out out_event) { + void CheatService::GetCheatProcessEvent(sf::OutCopyHandle out_event) { out_event.SetValue(dmnt::cheat::impl::GetCheatProcessEventHandle()); } - Result CheatService::GetCheatProcessMetadata(Out out_metadata) { + Result CheatService::GetCheatProcessMetadata(sf::Out out_metadata) { return dmnt::cheat::impl::GetCheatProcessMetadata(out_metadata.GetPointer()); } @@ -48,35 +48,35 @@ namespace sts::dmnt::cheat { /* =================================== Memory Commands =================================== */ /* ========================================================================================= */ - Result CheatService::GetCheatProcessMappingCount(Out out_count) { + Result CheatService::GetCheatProcessMappingCount(sf::Out out_count) { return dmnt::cheat::impl::GetCheatProcessMappingCount(out_count.GetPointer()); } - Result CheatService::GetCheatProcessMappings(OutBuffer mappings, Out out_count, u64 offset) { - if (mappings.buffer == nullptr) { + Result CheatService::GetCheatProcessMappings(const sf::OutArray &mappings, sf::Out out_count, u64 offset) { + if (mappings.GetPointer() == nullptr) { return ResultDmntCheatNullBuffer; } - return dmnt::cheat::impl::GetCheatProcessMappings(mappings.buffer, mappings.num_elements, out_count.GetPointer(), offset); + return dmnt::cheat::impl::GetCheatProcessMappings(mappings.GetPointer(), mappings.GetSize(), out_count.GetPointer(), offset); } - Result CheatService::ReadCheatProcessMemory(OutBuffer buffer, u64 address, u64 out_size) { - if (buffer.buffer == nullptr) { + Result CheatService::ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size) { + if (buffer.GetPointer() == nullptr) { return ResultDmntCheatNullBuffer; } - return dmnt::cheat::impl::ReadCheatProcessMemory(address, buffer.buffer, std::min(out_size, buffer.num_elements)); + return dmnt::cheat::impl::ReadCheatProcessMemory(address, buffer.GetPointer(), std::min(out_size, buffer.GetSize())); } - Result CheatService::WriteCheatProcessMemory(InBuffer buffer, u64 address, u64 in_size) { - if (buffer.buffer == nullptr) { + Result CheatService::WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size) { + if (buffer.GetPointer() == nullptr) { return ResultDmntCheatNullBuffer; } - return dmnt::cheat::impl::WriteCheatProcessMemory(address, buffer.buffer, std::min(in_size, buffer.num_elements)); + return dmnt::cheat::impl::WriteCheatProcessMemory(address, buffer.GetPointer(), std::min(in_size, buffer.GetSize())); } - Result CheatService::QueryCheatProcessMemory(Out mapping, u64 address) { + Result CheatService::QueryCheatProcessMemory(sf::Out mapping, u64 address) { return dmnt::cheat::impl::QueryCheatProcessMemory(mapping.GetPointer(), address); } @@ -84,44 +84,28 @@ namespace sts::dmnt::cheat { /* =================================== Cheat Commands ==================================== */ /* ========================================================================================= */ - Result CheatService::GetCheatCount(Out out_count) { + Result CheatService::GetCheatCount(sf::Out out_count) { return dmnt::cheat::impl::GetCheatCount(out_count.GetPointer()); } - Result CheatService::GetCheats(OutBuffer cheats, Out out_count, u64 offset) { - if (cheats.buffer == nullptr) { + Result CheatService::GetCheats(const sf::OutArray &cheats, sf::Out out_count, u64 offset) { + if (cheats.GetPointer() == nullptr) { return ResultDmntCheatNullBuffer; } - return dmnt::cheat::impl::GetCheats(cheats.buffer, cheats.num_elements, out_count.GetPointer(), offset); + return dmnt::cheat::impl::GetCheats(cheats.GetPointer(), cheats.GetSize(), out_count.GetPointer(), offset); } - Result CheatService::GetCheatById(OutBuffer cheat, u32 cheat_id) { - if (cheat.buffer == nullptr) { - return ResultDmntCheatNullBuffer; - } - - if (cheat.num_elements < 1) { - return ResultDmntCheatInvalidBuffer; - } - - return dmnt::cheat::impl::GetCheatById(cheat.buffer, cheat_id); + Result CheatService::GetCheatById(sf::Out cheat, u32 cheat_id) { + return dmnt::cheat::impl::GetCheatById(cheat.GetPointer(), cheat_id); } Result CheatService::ToggleCheat(u32 cheat_id) { return dmnt::cheat::impl::ToggleCheat(cheat_id); } - Result CheatService::AddCheat(InBuffer cheat, Out out_cheat_id, bool enabled) { - if (cheat.buffer == nullptr) { - return ResultDmntCheatNullBuffer; - } - - if (cheat.num_elements < 1) { - return ResultDmntCheatInvalidBuffer; - } - - return dmnt::cheat::impl::AddCheat(out_cheat_id.GetPointer(), cheat.buffer, enabled); + Result CheatService::AddCheat(const CheatDefinition &cheat, sf::Out out_cheat_id, bool enabled) { + return dmnt::cheat::impl::AddCheat(out_cheat_id.GetPointer(), cheat, enabled); } Result CheatService::RemoveCheat(u32 cheat_id) { @@ -132,23 +116,23 @@ namespace sts::dmnt::cheat { /* =================================== Address Commands ================================== */ /* ========================================================================================= */ - Result CheatService::GetFrozenAddressCount(Out out_count) { + Result CheatService::GetFrozenAddressCount(sf::Out out_count) { return dmnt::cheat::impl::GetFrozenAddressCount(out_count.GetPointer()); } - Result CheatService::GetFrozenAddresses(OutBuffer frz_addrs, Out out_count, u64 offset) { - if (frz_addrs.buffer == nullptr) { + Result CheatService::GetFrozenAddresses(const sf::OutArray &addresses, sf::Out out_count, u64 offset) { + if (addresses.GetPointer() == nullptr) { return ResultDmntCheatNullBuffer; } - return dmnt::cheat::impl::GetFrozenAddresses(frz_addrs.buffer, frz_addrs.num_elements, out_count.GetPointer(), offset); + return dmnt::cheat::impl::GetFrozenAddresses(addresses.GetPointer(), addresses.GetSize(), out_count.GetPointer(), offset); } - Result CheatService::GetFrozenAddress(Out entry, u64 address) { + Result CheatService::GetFrozenAddress(sf::Out entry, u64 address) { return dmnt::cheat::impl::GetFrozenAddress(entry.GetPointer(), address); } - Result CheatService::EnableFrozenAddress(Out out_value, u64 address, u64 width) { + Result CheatService::EnableFrozenAddress(sf::Out out_value, u64 address, u64 width) { switch (width) { case 1: case 2: diff --git a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.hpp b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.hpp index 2cb29cc6b..6bd4cf79e 100644 --- a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.hpp +++ b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.hpp @@ -21,7 +21,7 @@ namespace sts::dmnt::cheat { - class CheatService final : public IServiceObject { + class CheatService final : public sf::IServiceObject { private: enum class CommandId { /* Meta */ @@ -53,55 +53,55 @@ namespace sts::dmnt::cheat { DisableFrozenAddress = 65304, }; private: - void HasCheatProcess(Out out); - void GetCheatProcessEvent(Out out_event); - Result GetCheatProcessMetadata(Out out_metadata); + void HasCheatProcess(sf::Out out); + void GetCheatProcessEvent(sf::OutCopyHandle out_event); + Result GetCheatProcessMetadata(sf::Out out_metadata); Result ForceOpenCheatProcess(); - Result GetCheatProcessMappingCount(Out out_count); - Result GetCheatProcessMappings(OutBuffer mappings, Out out_count, u64 offset); - Result ReadCheatProcessMemory(OutBuffer buffer, u64 address, u64 out_size); - Result WriteCheatProcessMemory(InBuffer buffer, u64 address, u64 in_size); - Result QueryCheatProcessMemory(Out mapping, u64 address); + Result GetCheatProcessMappingCount(sf::Out out_count); + Result GetCheatProcessMappings(const sf::OutArray &mappings, sf::Out out_count, u64 offset); + Result ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size); + Result WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size); + Result QueryCheatProcessMemory(sf::Out mapping, u64 address); - Result GetCheatCount(Out out_count); - Result GetCheats(OutBuffer cheats, Out out_count, u64 offset); - Result GetCheatById(OutBuffer cheat, u32 cheat_id); + Result GetCheatCount(sf::Out out_count); + Result GetCheats(const sf::OutArray &cheats, sf::Out out_count, u64 offset); + Result GetCheatById(sf::Out cheat, u32 cheat_id); Result ToggleCheat(u32 cheat_id); - Result AddCheat(InBuffer cheat, Out out_cheat_id, bool enabled); + Result AddCheat(const CheatDefinition &cheat, sf::Out out_cheat_id, bool enabled); Result RemoveCheat(u32 cheat_id); - Result GetFrozenAddressCount(Out out_count); - Result GetFrozenAddresses(OutBuffer addresses, Out out_count, u64 offset); - Result GetFrozenAddress(Out entry, u64 address); - Result EnableFrozenAddress(Out out_value, u64 address, u64 width); + Result GetFrozenAddressCount(sf::Out out_count); + Result GetFrozenAddresses(const sf::OutArray &addresses, sf::Out out_count, u64 offset); + Result GetFrozenAddress(sf::Out entry, u64 address); + Result EnableFrozenAddress(sf::Out out_value, u64 address, u64 width); Result DisableFrozenAddress(u64 address); public: DEFINE_SERVICE_DISPATCH_TABLE { - MAKE_SERVICE_COMMAND_META(CheatService, HasCheatProcess), - MAKE_SERVICE_COMMAND_META(CheatService, GetCheatProcessEvent), - MAKE_SERVICE_COMMAND_META(CheatService, GetCheatProcessMetadata), - MAKE_SERVICE_COMMAND_META(CheatService, ForceOpenCheatProcess), + MAKE_SERVICE_COMMAND_META(HasCheatProcess), + MAKE_SERVICE_COMMAND_META(GetCheatProcessEvent), + MAKE_SERVICE_COMMAND_META(GetCheatProcessMetadata), + MAKE_SERVICE_COMMAND_META(ForceOpenCheatProcess), - MAKE_SERVICE_COMMAND_META(CheatService, GetCheatProcessMappingCount), - MAKE_SERVICE_COMMAND_META(CheatService, GetCheatProcessMappings), - MAKE_SERVICE_COMMAND_META(CheatService, ReadCheatProcessMemory), - MAKE_SERVICE_COMMAND_META(CheatService, WriteCheatProcessMemory), - MAKE_SERVICE_COMMAND_META(CheatService, QueryCheatProcessMemory), + MAKE_SERVICE_COMMAND_META(GetCheatProcessMappingCount), + MAKE_SERVICE_COMMAND_META(GetCheatProcessMappings), + MAKE_SERVICE_COMMAND_META(ReadCheatProcessMemory), + MAKE_SERVICE_COMMAND_META(WriteCheatProcessMemory), + MAKE_SERVICE_COMMAND_META(QueryCheatProcessMemory), - MAKE_SERVICE_COMMAND_META(CheatService, GetCheatCount), - MAKE_SERVICE_COMMAND_META(CheatService, GetCheats), - MAKE_SERVICE_COMMAND_META(CheatService, GetCheatById), - MAKE_SERVICE_COMMAND_META(CheatService, ToggleCheat), - MAKE_SERVICE_COMMAND_META(CheatService, AddCheat), - MAKE_SERVICE_COMMAND_META(CheatService, RemoveCheat), + MAKE_SERVICE_COMMAND_META(GetCheatCount), + MAKE_SERVICE_COMMAND_META(GetCheats), + MAKE_SERVICE_COMMAND_META(GetCheatById), + MAKE_SERVICE_COMMAND_META(ToggleCheat), + MAKE_SERVICE_COMMAND_META(AddCheat), + MAKE_SERVICE_COMMAND_META(RemoveCheat), - MAKE_SERVICE_COMMAND_META(CheatService, GetFrozenAddressCount), - MAKE_SERVICE_COMMAND_META(CheatService, GetFrozenAddresses), - MAKE_SERVICE_COMMAND_META(CheatService, GetFrozenAddress), - MAKE_SERVICE_COMMAND_META(CheatService, EnableFrozenAddress), - MAKE_SERVICE_COMMAND_META(CheatService, DisableFrozenAddress), + MAKE_SERVICE_COMMAND_META(GetFrozenAddressCount), + MAKE_SERVICE_COMMAND_META(GetFrozenAddresses), + MAKE_SERVICE_COMMAND_META(GetFrozenAddress), + MAKE_SERVICE_COMMAND_META(EnableFrozenAddress), + MAKE_SERVICE_COMMAND_META(DisableFrozenAddress), }; }; diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp index 0468c3f43..f6f0cbe26 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp @@ -45,7 +45,7 @@ namespace sts::dmnt::cheat::impl { bool enable_cheats_by_default = true; bool always_save_cheat_toggles = false; bool should_save_cheat_toggles = false; - CheatEntry cheat_entries[MaxCheatCount]; + CheatEntry cheat_entries[MaxCheatCount] = {}; std::map frozen_addresses_map; private: static void DetectLaunchThread(void *_this); @@ -146,11 +146,11 @@ namespace sts::dmnt::cheat::impl { bool HasActiveCheatProcess() { /* Note: This function *MUST* be called only with the cheat lock held. */ - u64 tmp; + os::ProcessId pid; bool has_cheat_process = this->cheat_process_debug_handle != INVALID_HANDLE; - has_cheat_process &= R_SUCCEEDED(svcGetProcessId(&tmp, this->cheat_process_debug_handle)); - has_cheat_process &= R_SUCCEEDED(pm::dmnt::GetApplicationProcessId(&tmp)); - has_cheat_process &= (tmp == this->cheat_process_metadata.process_id); + 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 &= (pid == this->cheat_process_metadata.process_id); if (!has_cheat_process) { this->CloseActiveCheatProcess(); @@ -176,7 +176,7 @@ namespace sts::dmnt::cheat::impl { return h; } - void StartProcess(u64 process_id) const { + void StartProcess(os::ProcessId process_id) const { R_ASSERT(pm::dmnt::StartProcess(process_id)); } @@ -404,12 +404,12 @@ namespace sts::dmnt::cheat::impl { return ResultSuccess; } - Result AddCheat(u32 *out_id, const CheatDefinition *def, bool enabled) { + Result AddCheat(u32 *out_id, const CheatDefinition &def, bool enabled) { std::scoped_lock lk(this->cheat_lock); R_TRY(this->EnsureCheatProcess()); - if (def->num_opcodes == 0 || def->num_opcodes > util::size(def->opcodes)) { + if (def.num_opcodes == 0 || def.num_opcodes > util::size(def.opcodes)) { return ResultDmntCheatInvalidCheat; } @@ -419,7 +419,7 @@ namespace sts::dmnt::cheat::impl { } new_entry->enabled = enabled; - new_entry->definition = *def; + new_entry->definition = def; /* Trigger a VM reload. */ this->SetNeedsReloadVm(true); @@ -630,7 +630,7 @@ namespace sts::dmnt::cheat::impl { if (on_process_launch) { this->StartProcess(this->cheat_process_metadata.process_id); } - this->cheat_process_metadata.process_id = 0; + this->cheat_process_metadata.process_id = os::ProcessId{}; }; /* Get process handle, use it to learn memory extents. */ @@ -667,7 +667,7 @@ namespace sts::dmnt::cheat::impl { u32 num_modules; /* TODO: ldr::dmnt:: */ - R_ASSERT_IF_NEW_PROCESS(ldrDmntGetModuleInfos(this->cheat_process_metadata.process_id, proc_modules, util::size(proc_modules), &num_modules)); + R_ASSERT_IF_NEW_PROCESS(ldrDmntGetModuleInfos(static_cast(this->cheat_process_metadata.process_id), proc_modules, util::size(proc_modules), &num_modules)); /* All applications must have two modules. */ /* Only accept one (which means we're attaching to HBL) */ @@ -696,7 +696,7 @@ namespace sts::dmnt::cheat::impl { } /* Open a debug handle. */ - R_ASSERT_IF_NEW_PROCESS(svcDebugActiveProcess(&this->cheat_process_debug_handle, this->cheat_process_metadata.process_id)); + R_ASSERT_IF_NEW_PROCESS(svcDebugActiveProcess(&this->cheat_process_debug_handle, static_cast(this->cheat_process_metadata.process_id))); /* Cancel process guard. */ proc_guard.Cancel(); @@ -1064,7 +1064,7 @@ namespace sts::dmnt::cheat::impl { return g_cheat_process_manager.ToggleCheat(cheat_id); } - Result AddCheat(u32 *out_id, const CheatDefinition *def, bool enabled) { + Result AddCheat(u32 *out_id, const CheatDefinition &def, bool enabled) { return g_cheat_process_manager.AddCheat(out_id, def, enabled); } diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.hpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.hpp index 19d037c84..ed901034a 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.hpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.hpp @@ -38,7 +38,7 @@ namespace sts::dmnt::cheat::impl { Result GetCheats(CheatEntry *cheats, size_t max_count, u64 *out_count, u64 offset); Result GetCheatById(CheatEntry *out_cheat, u32 cheat_id); Result ToggleCheat(u32 cheat_id); - Result AddCheat(u32 *out_id, const CheatDefinition *def, bool enabled); + Result AddCheat(u32 *out_id, const CheatDefinition &def, bool enabled); Result RemoveCheat(u32 cheat_id); Result GetFrozenAddressCount(u64 *out_count); diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_debug_events_manager.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_debug_events_manager.cpp index 277edf2d9..4230e862d 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_debug_events_manager.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_debug_events_manager.cpp @@ -72,7 +72,7 @@ namespace sts::dmnt::cheat::impl { } Result ContinueDebugEvent(Handle debug_handle) { - if (GetRuntimeFirmwareVersion() >= FirmwareVersion_300) { + if (hos::GetVersion() >= hos::Version_300) { return svcContinueDebugEvent(debug_handle, 5, nullptr, 0); } else { return svcLegacyContinueDebugEvent(debug_handle, 5, 0); diff --git a/stratosphere/dmnt/source/dmnt_main.cpp b/stratosphere/dmnt/source/dmnt_main.cpp index 8b39a1789..98dfa6f3c 100644 --- a/stratosphere/dmnt/source/dmnt_main.cpp +++ b/stratosphere/dmnt/source/dmnt_main.cpp @@ -30,7 +30,9 @@ extern "C" { extern u32 __start__; u32 __nx_applet_type = AppletType_None; + u32 __nx_fs_num_sessions = 1; + /* TODO: Evaluate how much this can be reduced by. */ #define INNER_HEAP_SIZE 0xC0000 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; @@ -55,15 +57,17 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } +using namespace sts; + void __appInit(void) { - SetFirmwareVersionForLibnx(); + hos::SetVersionForLibnx(); DoWithSmSession([&]() { R_ASSERT(pmdmntInitialize()); R_ASSERT(pminfoInitialize()); R_ASSERT(ldrDmntInitialize()); /* TODO: We provide this on every sysver via ro. Do we need a shim? */ - if (GetRuntimeFirmwareVersion() >= FirmwareVersion_300) { + if (hos::GetVersion() >= hos::Version_300) { R_ASSERT(roDmntInitialize()); } R_ASSERT(nsdevInitialize()); @@ -94,19 +98,70 @@ void __appExit(void) { pmdmntExit(); } +namespace { + + using ServerOptions = sf::hipc::DefaultServerManagerOptions; + + constexpr sm::ServiceName DebugMonitorServiceName = sm::ServiceName::Encode("dmnt:-"); + constexpr size_t DebugMonitorMaxSessions = 4; + + constexpr sm::ServiceName CheatServiceName = sm::ServiceName::Encode("dmnt:cht"); + constexpr size_t CheatMaxSessions = 2; + + /* dmnt:-, dmnt:cht. */ + constexpr size_t NumServers = 2; + constexpr size_t NumSessions = DebugMonitorMaxSessions + CheatMaxSessions; + + sf::hipc::ServerManager g_server_manager; + + void LoopServerThread(void *arg) { + g_server_manager.LoopProcess(); + } + +} + int main(int argc, char **argv) { - /* Nintendo uses four threads. Add a fifth for our cheat service. */ - static auto s_server_manager = WaitableManager(5); - /* Create services. */ - /* TODO: Implement rest of dmnt:- in ams.tma development branch. */ - /* server_manager->AddWaitable(new ServiceServer("dmnt:-", 4)); */ - s_server_manager.AddWaitable(new ServiceServer("dmnt:cht", 1)); + /* R_ASSERT((g_server_manager.RegisterServer(DebugMonitorServiceName, DebugMonitorMaxSessions))); */ + R_ASSERT((g_server_manager.RegisterServer(CheatServiceName, CheatMaxSessions))); /* Loop forever, servicing our services. */ - s_server_manager.Process(); + /* Nintendo loops four threads processing on the manager -- we'll loop an extra fifth for our cheat service. */ + { + constexpr size_t TotalThreads = DebugMonitorMaxSessions + 1; + constexpr size_t NumExtraThreads = TotalThreads - 1; + static_assert(TotalThreads >= 1, "TotalThreads"); + + os::Thread extra_threads[NumExtraThreads]; + + /* Initialize threads. */ + if constexpr (NumExtraThreads > 0) { + constexpr size_t ThreadStackSize = 0x4000; + const u32 priority = os::GetCurrentThreadPriority(); + for (size_t i = 0; i < NumExtraThreads; i++) { + R_ASSERT(extra_threads[i].Initialize(LoopServerThread, nullptr, ThreadStackSize, priority)); + } + } + + /* Start extra threads. */ + if constexpr (NumExtraThreads > 0) { + for (size_t i = 0; i < NumExtraThreads; i++) { + R_ASSERT(extra_threads[i].Start()); + } + } + + /* Loop this thread. */ + LoopServerThread(nullptr); + + /* Wait for extra threads to finish. */ + if constexpr (NumExtraThreads > 0) { + for (size_t i = 0; i < NumExtraThreads; i++) { + R_ASSERT(extra_threads[i].Join()); + } + } + } return 0; } diff --git a/stratosphere/dmnt/source/dmnt_service.hpp b/stratosphere/dmnt/source/dmnt_service.hpp index eff755ec2..dec1771bf 100644 --- a/stratosphere/dmnt/source/dmnt_service.hpp +++ b/stratosphere/dmnt/source/dmnt_service.hpp @@ -20,7 +20,46 @@ namespace sts::dmnt { - class DebugMonitorService final : public IServiceObject { + /* TODO: Move into libstratosphere, eventually. */ + struct TargetIOFileHandle : sf::LargeData, sf::PrefersMapAliasTransferMode { + u64 value; + + constexpr u64 GetValue() const { + return this->value; + } + + constexpr explicit operator u64() const { + return this->value; + } + + inline constexpr bool operator==(const TargetIOFileHandle &rhs) const { + return this->value == rhs.value; + } + + inline constexpr bool operator!=(const TargetIOFileHandle &rhs) const { + return this->value != rhs.value; + } + + inline constexpr bool operator<(const TargetIOFileHandle &rhs) const { + return this->value < rhs.value; + } + + inline constexpr bool operator<=(const TargetIOFileHandle &rhs) const { + return this->value <= rhs.value; + } + + inline constexpr bool operator>(const TargetIOFileHandle &rhs) const { + return this->value > rhs.value; + } + + inline constexpr bool operator>=(const TargetIOFileHandle &rhs) const { + return this->value >= rhs.value; + } + }; + + static_assert(std::is_pod::value && sizeof(TargetIOFileHandle) == sizeof(u64), "TargetIOFileHandle"); + + class DebugMonitorService final : public sf::IServiceObject { private: enum class CommandId { BreakDebugProcess = 0, @@ -80,74 +119,74 @@ namespace sts::dmnt { Result BreakDebugProcess(Handle debug_hnd); Result TerminateDebugProcess(Handle debug_hnd); Result CloseHandle(Handle debug_hnd); - Result GetProcessId(Out out_pid, Handle hnd); - Result GetProcessHandle(Out out_hnd, u64 pid); + Result GetProcessId(sf::Out out_pid, Handle hnd); + Result GetProcessHandle(sf::Out out_hnd, os::ProcessId pid); Result WaitSynchronization(Handle hnd, u64 ns); - Result TargetIO_FileOpen(OutBuffer out_hnd, InBuffer path, int open_mode, u32 create_mode); - Result TargetIO_FileClose(InBuffer hnd); - Result TargetIO_FileRead(InBuffer hnd, OutBuffer out_data, Out out_read, u64 offset); - Result TargetIO_FileWrite(InBuffer hnd, InBuffer data, Out out_written, u64 offset); - Result TargetIO_FileSetAttributes(InBuffer path, InBuffer attributes); - Result TargetIO_FileGetInformation(InBuffer path, OutBuffer out_info, Out is_directory); - Result TargetIO_FileSetTime(InBuffer path, u64 create, u64 access, u64 modify); - Result TargetIO_FileSetSize(InBuffer path, u64 size); - Result TargetIO_FileDelete(InBuffer path); - Result TargetIO_FileMove(InBuffer path0, InBuffer path1); + Result TargetIO_FileOpen(sf::Out out_hnd, const sf::InBuffer &path, int open_mode, u32 create_mode); + Result TargetIO_FileClose(TargetIOFileHandle hnd); + Result TargetIO_FileRead(TargetIOFileHandle hnd, const sf::OutNonSecureBuffer &out_data, sf::Out out_read, u64 offset); + Result TargetIO_FileWrite(TargetIOFileHandle hnd, const sf::InNonSecureBuffer &data, sf::Out out_written, u64 offset); + Result TargetIO_FileSetAttributes(const sf::InBuffer &path, const sf::InBuffer &attributes); + Result TargetIO_FileGetInformation(const sf::InBuffer &path, const sf::OutArray &out_info, sf::Out is_directory); + Result TargetIO_FileSetTime(const sf::InBuffer &path, u64 create, u64 access, u64 modify); + Result TargetIO_FileSetSize(const sf::InBuffer &input, u64 size); + Result TargetIO_FileDelete(const sf::InBuffer &path); + Result TargetIO_FileMove(const sf::InBuffer &src_path, const sf::InBuffer &dst_path); public: DEFINE_SERVICE_DISPATCH_TABLE { - MAKE_SERVICE_COMMAND_META(DebugMonitorService, BreakDebugProcess), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TerminateDebugProcess), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, CloseHandle), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, LoadImage), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetProcessId), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetProcessHandle), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, WaitSynchronization), - //MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetDebugEvent), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetProcessModuleInfo), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetProcessList), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetThreadList), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetDebugThreadContext), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, ContinueDebugEvent), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, ReadDebugProcessMemory), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, WriteDebugProcessMemory), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, SetDebugThreadContext), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetDebugThreadParam), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, InitializeThreadInfo), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, SetHardwareBreakPoint), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, QueryDebugProcessMemory), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetProcessMemoryDetails), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, AttachByProgramId), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, AttachOnLaunch), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetDebugMonitorProcessId), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetJitDebugProcessList), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, CreateCoreDump), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, GetAllDebugThreadInfo), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileOpen), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileClose), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileRead), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileWrite), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileSetAttributes), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileGetInformation), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileSetTime), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileSetSize), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileDelete), - MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_FileMove), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_DirectoryCreate), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_DirectoryDelete), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_DirectoryRename), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_DirectoryGetCount), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_DirectoryOpen), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_DirectoryGetNext), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_DirectoryClose), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_GetFreeSpace), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, TargetIO_GetVolumeInformation), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, InitiateCoreDump), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, ContinueCoreDump), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, AddTTYToCoreDump), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, AddImageToCoreDump), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, CloseCoreDump), - // MAKE_SERVICE_COMMAND_META(DebugMonitorService, CancelAttach), + MAKE_SERVICE_COMMAND_META(BreakDebugProcess), + MAKE_SERVICE_COMMAND_META(TerminateDebugProcess), + MAKE_SERVICE_COMMAND_META(CloseHandle), + // MAKE_SERVICE_COMMAND_META(LoadImage), + MAKE_SERVICE_COMMAND_META(GetProcessId), + MAKE_SERVICE_COMMAND_META(GetProcessHandle), + MAKE_SERVICE_COMMAND_META(WaitSynchronization), + //MAKE_SERVICE_COMMAND_META(GetDebugEvent), + // MAKE_SERVICE_COMMAND_META(GetProcessModuleInfo), + // MAKE_SERVICE_COMMAND_META(GetProcessList), + // MAKE_SERVICE_COMMAND_META(GetThreadList), + // MAKE_SERVICE_COMMAND_META(GetDebugThreadContext), + // MAKE_SERVICE_COMMAND_META(ContinueDebugEvent), + // MAKE_SERVICE_COMMAND_META(ReadDebugProcessMemory), + // MAKE_SERVICE_COMMAND_META(WriteDebugProcessMemory), + // MAKE_SERVICE_COMMAND_META(SetDebugThreadContext), + // MAKE_SERVICE_COMMAND_META(GetDebugThreadParam), + // MAKE_SERVICE_COMMAND_META(InitializeThreadInfo), + // MAKE_SERVICE_COMMAND_META(SetHardwareBreakPoint), + // MAKE_SERVICE_COMMAND_META(QueryDebugProcessMemory), + // MAKE_SERVICE_COMMAND_META(GetProcessMemoryDetails), + // MAKE_SERVICE_COMMAND_META(AttachByProgramId), + // MAKE_SERVICE_COMMAND_META(AttachOnLaunch), + // MAKE_SERVICE_COMMAND_META(GetDebugMonitorProcessId), + // MAKE_SERVICE_COMMAND_META(GetJitDebugProcessList), + // MAKE_SERVICE_COMMAND_META(CreateCoreDump), + // MAKE_SERVICE_COMMAND_META(GetAllDebugThreadInfo), + MAKE_SERVICE_COMMAND_META(TargetIO_FileOpen), + MAKE_SERVICE_COMMAND_META(TargetIO_FileClose), + MAKE_SERVICE_COMMAND_META(TargetIO_FileRead), + MAKE_SERVICE_COMMAND_META(TargetIO_FileWrite), + MAKE_SERVICE_COMMAND_META(TargetIO_FileSetAttributes), + MAKE_SERVICE_COMMAND_META(TargetIO_FileGetInformation), + MAKE_SERVICE_COMMAND_META(TargetIO_FileSetTime), + MAKE_SERVICE_COMMAND_META(TargetIO_FileSetSize), + MAKE_SERVICE_COMMAND_META(TargetIO_FileDelete), + MAKE_SERVICE_COMMAND_META(TargetIO_FileMove), + // MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryCreate), + // MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryDelete), + // MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryRename), + // MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryGetCount), + // MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryOpen), + // MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryGetNext), + // MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryClose), + // MAKE_SERVICE_COMMAND_META(TargetIO_GetFreeSpace), + // MAKE_SERVICE_COMMAND_META(TargetIO_GetVolumeInformation), + // MAKE_SERVICE_COMMAND_META(InitiateCoreDump), + // MAKE_SERVICE_COMMAND_META(ContinueCoreDump), + // MAKE_SERVICE_COMMAND_META(AddTTYToCoreDump), + // MAKE_SERVICE_COMMAND_META(AddImageToCoreDump), + // MAKE_SERVICE_COMMAND_META(CloseCoreDump), + // MAKE_SERVICE_COMMAND_META(CancelAttach), }; }; diff --git a/stratosphere/dmnt/source/dmnt_service_debug.cpp b/stratosphere/dmnt/source/dmnt_service_debug.cpp index 72b6dbbbc..656a1e72f 100644 --- a/stratosphere/dmnt/source/dmnt_service_debug.cpp +++ b/stratosphere/dmnt/source/dmnt_service_debug.cpp @@ -34,13 +34,13 @@ namespace sts::dmnt { return svcCloseHandle(debug_hnd); } - Result DebugMonitorService::GetProcessId(Out out_pid, Handle hnd) { + Result DebugMonitorService::GetProcessId(sf::Out out_pid, Handle hnd) { /* Nintendo discards the output of this command, but we will return it. */ - return svcGetProcessId(out_pid.GetPointer(), hnd); + return svcGetProcessId(reinterpret_cast(out_pid.GetPointer()), hnd); } - Result DebugMonitorService::GetProcessHandle(Out out_hnd, u64 pid) { - R_TRY_CATCH(svcDebugActiveProcess(out_hnd.GetPointer(), pid)) { + Result DebugMonitorService::GetProcessHandle(sf::Out out_hnd, os::ProcessId pid) { + R_TRY_CATCH(svcDebugActiveProcess(out_hnd.GetPointer(), static_cast(pid))) { R_CATCH(ResultKernelAlreadyExists) { return ResultDebugAlreadyAttached; } diff --git a/stratosphere/dmnt/source/dmnt_service_target_io.cpp b/stratosphere/dmnt/source/dmnt_service_target_io.cpp index a22e63b44..76f5d4f70 100644 --- a/stratosphere/dmnt/source/dmnt_service_target_io.cpp +++ b/stratosphere/dmnt/source/dmnt_service_target_io.cpp @@ -17,6 +17,17 @@ #include #include "dmnt_service.hpp" +namespace std { + + template<> + struct hash { + u64 operator()(sts::dmnt::TargetIOFileHandle const &handle) const noexcept { + return handle.GetValue(); + } + }; + +} + namespace sts::dmnt { namespace { @@ -36,7 +47,7 @@ namespace sts::dmnt { os::Mutex g_file_handle_lock; u64 g_cur_fd; - std::unordered_map g_file_handles; + std::unordered_map g_file_handles; Result EnsureSdInitialized() { std::scoped_lock lk(g_sd_lock); @@ -49,15 +60,15 @@ namespace sts::dmnt { return ResultSuccess; } - u64 GetNewFileHandle(FsFile f) { + TargetIOFileHandle GetNewFileHandle(FsFile f) { std::scoped_lock lk(g_file_handle_lock); - u64 fd = g_cur_fd++; + TargetIOFileHandle fd = { .value = g_cur_fd++ }; g_file_handles[fd] = f; return fd; } - Result GetFileByHandle(FsFile *out, u64 handle) { + Result GetFileByHandle(FsFile *out, TargetIOFileHandle handle) { std::scoped_lock lk(g_file_handle_lock); if (g_file_handles.find(handle) != g_file_handles.end()) { @@ -68,7 +79,7 @@ namespace sts::dmnt { return ResultFsInvalidArgument; } - Result CloseFileByHandle(u64 handle) { + Result CloseFileByHandle(TargetIOFileHandle handle) { std::scoped_lock lk(g_file_handle_lock); if (g_file_handles.find(handle) != g_file_handles.end()) { @@ -80,18 +91,18 @@ namespace sts::dmnt { return ResultFsInvalidArgument; } - void FixPath(char *dst, size_t dst_size, InBuffer &path) { + void FixPath(char *dst, size_t dst_size, const sf::InBuffer &path) { dst[dst_size - 1] = 0; strncpy(dst, "/", dst_size - 1); - const char *src = path.buffer; + const char *src = reinterpret_cast(path.GetPointer()); size_t src_idx = 0; size_t dst_idx = 1; - while (src_idx < path.num_elements && (src[src_idx] == '/' || src[src_idx] == '\\')) { + while (src_idx < path.GetSize() && (src[src_idx] == '/' || src[src_idx] == '\\')) { src_idx++; } - while (src_idx < path.num_elements && dst_idx < dst_size - 1 && src[src_idx] != 0) { + while (src_idx < path.GetSize() && dst_idx < dst_size - 1 && src[src_idx] != 0) { if (src[src_idx] == '\\') { dst[dst_idx] = '/'; } else { @@ -109,12 +120,7 @@ namespace sts::dmnt { } - Result DebugMonitorService::TargetIO_FileOpen(OutBuffer out_hnd, InBuffer path, int open_mode, u32 create_mode) { - if (out_hnd.num_elements != 1) { - /* Serialization error. */ - return ResultKernelConnectionClosed; - } - + Result DebugMonitorService::TargetIO_FileOpen(sf::Out out_hnd, const sf::InBuffer &path, int open_mode, u32 create_mode) { R_TRY(EnsureSdInitialized()); char fs_path[FS_MAX_PATH]; @@ -144,84 +150,66 @@ namespace sts::dmnt { /* Cancel guard, output file handle. */ file_guard.Cancel(); - out_hnd[0] = GetNewFileHandle(f); + out_hnd.SetValue(GetNewFileHandle(f)); return ResultSuccess; } - Result DebugMonitorService::TargetIO_FileClose(InBuffer hnd) { - if (hnd.num_elements != 1) { - /* Serialization error. */ - return ResultKernelConnectionClosed; - } - - return CloseFileByHandle(hnd[0]); + Result DebugMonitorService::TargetIO_FileClose(TargetIOFileHandle hnd) { + return CloseFileByHandle(hnd); } - Result DebugMonitorService::TargetIO_FileRead(InBuffer hnd, OutBuffer out_data, Out out_read, u64 offset) { - if (hnd.num_elements != 1) { - /* Serialization error. */ - return ResultKernelConnectionClosed; - } - + Result DebugMonitorService::TargetIO_FileRead(TargetIOFileHandle hnd, const sf::OutNonSecureBuffer &out_data, sf::Out out_read, u64 offset) { FsFile f; size_t read = 0; - R_TRY(GetFileByHandle(&f, hnd[0])); - R_TRY(fsFileRead(&f, offset, out_data.buffer, out_data.num_elements, FS_READOPTION_NONE, &read)); + R_TRY(GetFileByHandle(&f, hnd)); + R_TRY(fsFileRead(&f, offset, out_data.GetPointer(), out_data.GetSize(), FsReadOption_None, &read)); out_read.SetValue(static_cast(read)); return ResultSuccess; } - Result DebugMonitorService::TargetIO_FileWrite(InBuffer hnd, InBuffer data, Out out_written, u64 offset) { - if (hnd.num_elements != 1) { - /* Serialization error. */ - return ResultKernelConnectionClosed; - } - + Result DebugMonitorService::TargetIO_FileWrite(TargetIOFileHandle hnd, const sf::InNonSecureBuffer &data, sf::Out out_written, u64 offset) { FsFile f; - R_TRY(GetFileByHandle(&f, hnd[0])); - R_TRY(fsFileWrite(&f, offset, data.buffer, data.num_elements, FS_WRITEOPTION_NONE)); + R_TRY(GetFileByHandle(&f, hnd)); + R_TRY(fsFileWrite(&f, offset, data.GetPointer(), data.GetSize(), FsWriteOption_None)); - out_written.SetValue(data.num_elements); + out_written.SetValue(data.GetSize()); return ResultSuccess; } - Result DebugMonitorService::TargetIO_FileSetAttributes(InBuffer path, InBuffer attributes) { + Result DebugMonitorService::TargetIO_FileSetAttributes(const sf::InBuffer &path, const sf::InBuffer &attributes) { /* I don't really know why this command exists, Horizon doesn't allow you to set any attributes. */ /* N just returns ResultSuccess unconditionally here. */ return ResultSuccess; } - Result DebugMonitorService::TargetIO_FileGetInformation(InBuffer path, OutBuffer out_info, Out is_directory) { - if (out_info.num_elements != 4) { - /* Serialization error. */ - return ResultKernelConnectionClosed; - } - + Result DebugMonitorService::TargetIO_FileGetInformation(const sf::InBuffer &path, const sf::OutArray &out_info, sf::Out is_directory) { R_TRY(EnsureSdInitialized()); char fs_path[FS_MAX_PATH]; FixPath(fs_path, sizeof(fs_path), path); - for (size_t i = 0; i < out_info.num_elements; i++) { + for (size_t i = 0; i < out_info.GetSize(); i++) { out_info[i] = 0; } is_directory.SetValue(0); FsFile f; - if (R_SUCCEEDED(fsFsOpenFile(&g_sd_fs, fs_path, FS_OPEN_READ, &f))) { + if (R_SUCCEEDED(fsFsOpenFile(&g_sd_fs, fs_path, FsOpenMode_Read, &f))) { ON_SCOPE_EXIT { fsFileClose(&f); }; /* N doesn't check this return code. */ - fsFileGetSize(&f, &out_info[0]); + if (out_info.GetSize() > 0) { + fsFileGetSize(&f, &out_info[0]); + } /* TODO: N does not call fsFsGetFileTimestampRaw here, but we possibly could. */ } else { FsDir dir; - R_TRY(fsFsOpenDirectory(&g_sd_fs, fs_path, FS_DIROPEN_FILE | FS_DIROPEN_DIRECTORY, &dir)); + R_TRY(fsFsOpenDirectory(&g_sd_fs, fs_path, FsDirOpenMode_ReadFiles | FsDirOpenMode_ReadDirs, &dir)); fsDirClose(&dir); is_directory.SetValue(1); } @@ -229,35 +217,33 @@ namespace sts::dmnt { return ResultSuccess; } - Result DebugMonitorService::TargetIO_FileSetTime(InBuffer path, u64 create, u64 access, u64 modify) { + Result DebugMonitorService::TargetIO_FileSetTime(const sf::InBuffer &path, u64 create, u64 access, u64 modify) { /* This is another function that doesn't really need to exist, because Horizon doesn't let you set anything. */ return ResultSuccess; } - Result DebugMonitorService::TargetIO_FileSetSize(InBuffer input, u64 size) { + Result DebugMonitorService::TargetIO_FileSetSize(const sf::InBuffer &input, u64 size) { /* Why does this function take in a path and not a file handle? */ + R_TRY(EnsureSdInitialized()); /* We will try to be better than N, here. N only treats input as a path. */ - if (input.num_elements == sizeof(u64)) { - FsFile f; - if (R_SUCCEEDED(GetFileByHandle(&f, reinterpret_cast(input.buffer)[0]))) { + FsFile f; + if (input.GetSize() == sizeof(TargetIOFileHandle)) { + if (R_SUCCEEDED(GetFileByHandle(&f, *reinterpret_cast(input.GetPointer())))) { return fsFileSetSize(&f, size); } } - R_TRY(EnsureSdInitialized()); - char fs_path[FS_MAX_PATH]; FixPath(fs_path, sizeof(fs_path), input); - FsFile f; - R_TRY(fsFsOpenFile(&g_sd_fs, fs_path, FS_OPEN_WRITE, &f)); + R_TRY(fsFsOpenFile(&g_sd_fs, fs_path, FsOpenMode_Write, &f)); ON_SCOPE_EXIT { fsFileClose(&f); }; return fsFileSetSize(&f, size); } - Result DebugMonitorService::TargetIO_FileDelete(InBuffer path) { + Result DebugMonitorService::TargetIO_FileDelete(const sf::InBuffer &path) { R_TRY(EnsureSdInitialized()); char fs_path[FS_MAX_PATH]; @@ -266,15 +252,15 @@ namespace sts::dmnt { return fsFsDeleteFile(&g_sd_fs, fs_path); } - Result DebugMonitorService::TargetIO_FileMove(InBuffer path0, InBuffer path1) { + Result DebugMonitorService::TargetIO_FileMove(const sf::InBuffer &src_path, const sf::InBuffer &dst_path) { R_TRY(EnsureSdInitialized()); - char fs_path0[FS_MAX_PATH]; - char fs_path1[FS_MAX_PATH]; - FixPath(fs_path0, sizeof(fs_path0), path0); - FixPath(fs_path1, sizeof(fs_path1), path1); + char fs_src_path[FS_MAX_PATH]; + char fs_dst_path[FS_MAX_PATH]; + FixPath(fs_src_path, sizeof(fs_src_path), src_path); + FixPath(fs_dst_path, sizeof(fs_dst_path), dst_path); - return fsFsRenameFile(&g_sd_fs, fs_path0, fs_path1); + return fsFsRenameFile(&g_sd_fs, fs_src_path, fs_dst_path); } } diff --git a/stratosphere/fatal/source/fatal_main.cpp b/stratosphere/fatal/source/fatal_main.cpp index 974a36b4f..b8ac7f0f7 100644 --- a/stratosphere/fatal/source/fatal_main.cpp +++ b/stratosphere/fatal/source/fatal_main.cpp @@ -132,7 +132,6 @@ namespace { constexpr size_t PrivateMaxSessions = 4; /* fatal:u, fatal:p. */ - /* TODO: Consider max sessions enforcement? */ constexpr size_t NumServers = 2; constexpr size_t NumSessions = UserMaxSessions + PrivateMaxSessions; diff --git a/stratosphere/libstratosphere/include/stratosphere/dmnt/dmnt_cheat_types.hpp b/stratosphere/libstratosphere/include/stratosphere/dmnt/dmnt_cheat_types.hpp index 1edb9192f..40413c307 100644 --- a/stratosphere/libstratosphere/include/stratosphere/dmnt/dmnt_cheat_types.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/dmnt/dmnt_cheat_types.hpp @@ -16,7 +16,9 @@ #pragma once +#include "../os/os_common_types.hpp" #include "../ncm/ncm_types.hpp" +#include "../sf/sf_buffer_tags.hpp" namespace sts::dmnt::cheat { @@ -26,7 +28,7 @@ namespace sts::dmnt::cheat { u64 size; }; - u64 process_id; + os::ProcessId process_id; ncm::TitleId title_id; MemoryRegionExtents main_nso_extents; MemoryRegionExtents heap_extents; @@ -37,18 +39,21 @@ namespace sts::dmnt::cheat { static_assert(std::is_pod::value && sizeof(CheatProcessMetadata) == 0x70, "CheatProcessMetadata definition!"); - struct CheatDefinition { + struct CheatDefinition : sf::LargeData, sf::PrefersMapAliasTransferMode { char readable_name[0x40]; uint32_t num_opcodes; uint32_t opcodes[0x100]; }; - struct CheatEntry { + struct CheatEntry : sf::LargeData, sf::PrefersMapAliasTransferMode { bool enabled; uint32_t cheat_id; CheatDefinition definition; }; + static_assert(std::is_pod::value, "CheatDefinition"); + static_assert(std::is_pod::value, "CheatEntry"); + struct FrozenAddressValue { u64 value; u8 width; diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_common_types.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_common_types.hpp index afdab148c..8740faed1 100644 --- a/stratosphere/libstratosphere/include/stratosphere/os/os_common_types.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_common_types.hpp @@ -46,10 +46,14 @@ namespace sts::os { inline constexpr const ProcessId InvalidProcessId = ProcessId::Invalid; + NX_INLINE Result GetProcessId(os::ProcessId *out, ::Handle process_handle) { + return svcGetProcessId(&out->value, process_handle); + } + NX_INLINE ProcessId GetCurrentProcessId() { - u64 current_process_id = 0; - R_ASSERT(svcGetProcessId(¤t_process_id, CUR_PROCESS_HANDLE)); - return os::ProcessId{current_process_id}; + os::ProcessId current_process_id; + R_ASSERT(GetProcessId(¤t_process_id, CUR_PROCESS_HANDLE)); + return current_process_id; } inline constexpr bool operator==(const ProcessId &lhs, const ProcessId &rhs) { diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp index b0ab77f4f..3d2b7f3ca 100644 --- a/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp @@ -52,4 +52,10 @@ namespace sts::os { } }; + NX_INLINE u32 GetCurrentThreadPriority() { + u32 prio; + R_ASSERT(svcGetThreadPriority(&prio, CUR_THREAD_HANDLE)); + return prio; + } + }