From b969fe0a17f036c5400d220afc3c94b58581b4b9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 21 Nov 2019 04:03:19 -0800 Subject: [PATCH] mitm/cfg: pass around override status for decision-making --- include/stratosphere/cfg/cfg_api.hpp | 9 +- include/stratosphere/cfg/cfg_types.hpp | 62 ++++++++++++++ include/stratosphere/ldr/ldr_pm_api.hpp | 4 + include/stratosphere/pm/pm_dmnt_api.hpp | 2 +- include/stratosphere/pm/pm_info_api.hpp | 2 + .../sf/hipc/sf_hipc_server_manager.hpp | 13 ++- include/stratosphere/sf/sf_common.hpp | 3 +- include/stratosphere/sf/sf_service_object.hpp | 7 +- include/stratosphere/sm/sm_manager_api.hpp | 2 +- include/stratosphere/sm/sm_mitm_api.hpp | 3 +- include/stratosphere/sm/sm_types.hpp | 10 +++ source/cfg/cfg_override.cpp | 82 +++++-------------- source/ldr/ldr_ams.c | 15 ++++ source/ldr/ldr_ams.h | 8 ++ source/ldr/ldr_pm_api.cpp | 11 +++ source/pm/pm_ams.c | 28 ++++++- source/pm/pm_ams.h | 8 +- source/pm/pm_dmnt_api.cpp | 6 +- source/pm/pm_info_api.cpp | 9 ++ source/sf/hipc/sf_hipc_mitm_query_api.cpp | 4 +- source/sm/sm_ams.c | 19 ++--- source/sm/sm_ams.h | 2 +- source/sm/sm_manager_api.cpp | 5 +- source/sm/sm_mitm_api.cpp | 4 +- source/sm/smm_ams.c | 5 +- source/sm/smm_ams.h | 7 +- 26 files changed, 220 insertions(+), 110 deletions(-) create mode 100644 include/stratosphere/cfg/cfg_types.hpp diff --git a/include/stratosphere/cfg/cfg_api.hpp b/include/stratosphere/cfg/cfg_api.hpp index a33799d0..89181b82 100644 --- a/include/stratosphere/cfg/cfg_api.hpp +++ b/include/stratosphere/cfg/cfg_api.hpp @@ -13,10 +13,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once -#include "../os/os_common_types.hpp" -#include "../ncm/ncm_types.hpp" +#include "cfg_types.hpp" namespace ams::cfg { @@ -31,10 +29,7 @@ namespace ams::cfg { void WaitSdCardInitialized(); /* Override key utilities. */ - bool IsProgramOverrideKeyHeld(ncm::ProgramId program_id); - bool IsHblOverrideKeyHeld(ncm::ProgramId program_id); - void GetOverrideKeyHeldStatus(bool *out_hbl, bool *out_program, ncm::ProgramId program_id); - bool IsCheatEnableKeyHeld(ncm::ProgramId program_id); + OverrideStatus CaptureOverrideStatus(ncm::ProgramId program_id); /* Flag utilities. */ bool HasFlag(ncm::ProgramId program_id, const char *flag); diff --git a/include/stratosphere/cfg/cfg_types.hpp b/include/stratosphere/cfg/cfg_types.hpp new file mode 100644 index 00000000..530e4160 --- /dev/null +++ b/include/stratosphere/cfg/cfg_types.hpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include "../os/os_common_types.hpp" +#include "../ncm/ncm_types.hpp" + +namespace ams::cfg { + + namespace impl { + + enum OverrideStatusFlag : u64 { + OverrideStatusFlag_Hbl = BIT(0), + OverrideStatusFlag_ProgramSpecific = BIT(1), + OverrideStatusFlag_CheatEnabled = BIT(2), + }; + + } + + struct OverrideStatus { + u64 keys_held; + u64 flags; + + constexpr inline u64 GetKeysHeld() const { return this->keys_held; } + + #define DEFINE_FLAG_ACCESSORS(flag) \ + constexpr inline bool Is##flag() const { return this->flags & impl::OverrideStatusFlag_##flag; } \ + constexpr inline void Set##flag() { this->flags |= impl::OverrideStatusFlag_##flag; } \ + constexpr inline void Clear##flag() { this->flags &= ~u64(impl::OverrideStatusFlag_##flag); } + + DEFINE_FLAG_ACCESSORS(Hbl) + DEFINE_FLAG_ACCESSORS(ProgramSpecific) + DEFINE_FLAG_ACCESSORS(CheatEnabled) + + #undef DEFINE_FLAG_ACCESSORS + }; + + static_assert(sizeof(OverrideStatus) == 0x10, "sizeof(OverrideStatus)"); + static_assert(std::is_pod::value, "std::is_pod::value"); + + constexpr inline bool operator==(const OverrideStatus &lhs, const OverrideStatus &rhs) { + return lhs.keys_held == rhs.keys_held && lhs.flags == rhs.flags; + } + + constexpr inline bool operator!=(const OverrideStatus &lhs, const OverrideStatus &rhs) { + return !(lhs == rhs); + } + +} diff --git a/include/stratosphere/ldr/ldr_pm_api.hpp b/include/stratosphere/ldr/ldr_pm_api.hpp index 0945a32d..1eb6418d 100644 --- a/include/stratosphere/ldr/ldr_pm_api.hpp +++ b/include/stratosphere/ldr/ldr_pm_api.hpp @@ -26,4 +26,8 @@ namespace ams::ldr::pm { Result UnpinProgram(PinId pin_id); Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id); + /* Atmosphere extension API. */ + Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc); + Result AtmospherePinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); + } diff --git a/include/stratosphere/pm/pm_dmnt_api.hpp b/include/stratosphere/pm/pm_dmnt_api.hpp index 967dc28e..616e4d9c 100644 --- a/include/stratosphere/pm/pm_dmnt_api.hpp +++ b/include/stratosphere/pm/pm_dmnt_api.hpp @@ -26,7 +26,7 @@ namespace ams::pm::dmnt { Result GetProcessId(os::ProcessId *out_process_id, const ncm::ProgramId program_id); Result GetApplicationProcessId(os::ProcessId *out_process_id); Result HookToCreateApplicationProcess(Handle *out_handle); - Result AtmosphereGetProcessInfo(Handle *out_handle, ncm::ProgramLocation *out_loc, os::ProcessId process_id); + Result AtmosphereGetProcessInfo(Handle *out_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id); Result AtmosphereGetCurrentLimitInfo(u64 *out_current_value, u64 *out_limit_value, ResourceLimitGroup group, LimitableResource resource); } diff --git a/include/stratosphere/pm/pm_info_api.hpp b/include/stratosphere/pm/pm_info_api.hpp index cc803185..0b5e6dce 100644 --- a/include/stratosphere/pm/pm_info_api.hpp +++ b/include/stratosphere/pm/pm_info_api.hpp @@ -26,6 +26,8 @@ namespace ams::pm::info { Result GetProcessId(os::ProcessId *out_process_id, ncm::ProgramId program_id); Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id); + Result GetProcessInfo(ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id); + /* Information convenience API. */ bool HasLaunchedProgram(ncm::ProgramId program_id); diff --git a/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp b/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp index 6bdfd672..04cbd79c 100644 --- a/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp +++ b/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp @@ -36,7 +36,7 @@ namespace ams::sf::hipc { NON_COPYABLE(ServerManagerBase); NON_MOVEABLE(ServerManagerBase); public: - using MitmQueryFunction = bool (*)(os::ProcessId, ncm::ProgramId); + using MitmQueryFunction = bool (*)(const sm::MitmProcessInfo &); private: enum class UserDataTag : uintptr_t { Server = 1, @@ -106,11 +106,10 @@ namespace ams::sf::hipc { std::shared_ptr<::Service> forward_service = std::move(ServerSession::CreateForwardService()); /* Get mitm forward session. */ - os::ProcessId client_process_id; - ncm::ProgramId client_program_id; - R_ASSERT(sm::mitm::AcknowledgeSession(forward_service.get(), &client_process_id, &client_program_id, this->service_name)); + sm::MitmProcessInfo client_info; + R_ASSERT(sm::mitm::AcknowledgeSession(forward_service.get(), &client_info, this->service_name)); - *out_obj = std::move(cmif::ServiceObjectHolder(std::move(MakeShared(std::shared_ptr<::Service>(forward_service), client_process_id, client_program_id)))); + *out_obj = std::move(cmif::ServiceObjectHolder(std::move(MakeShared(std::shared_ptr<::Service>(forward_service), client_info)))); *out_fsrv = std::move(forward_service); } else { *out_obj = std::move(cmif::ServiceObjectHolder(std::move(MakeShared()))); @@ -166,8 +165,8 @@ namespace ams::sf::hipc { } template - static constexpr inline std::shared_ptr MakeSharedMitm(std::shared_ptr<::Service> &&s, os::ProcessId p, ncm::ProgramId r) { - return std::make_shared(std::forward>(s), p, r); + static constexpr inline std::shared_ptr MakeSharedMitm(std::shared_ptr<::Service> &&s, const sm::MitmProcessInfo &client_info) { + return std::make_shared(std::forward>(s), client_info); } Result InstallMitmServerImpl(Handle *out_port_handle, sm::ServiceName service_name, MitmQueryFunction query_func); diff --git a/include/stratosphere/sf/sf_common.hpp b/include/stratosphere/sf/sf_common.hpp index 71975321..39e0edcf 100644 --- a/include/stratosphere/sf/sf_common.hpp +++ b/include/stratosphere/sf/sf_common.hpp @@ -17,4 +17,5 @@ #pragma once #include #include "../ams.hpp" -#include "../os.hpp" \ No newline at end of file +#include "../os.hpp" +#include "../sm/sm_types.hpp" \ No newline at end of file diff --git a/include/stratosphere/sf/sf_service_object.hpp b/include/stratosphere/sf/sf_service_object.hpp index 8cf45caa..fd87ddb2 100644 --- a/include/stratosphere/sf/sf_service_object.hpp +++ b/include/stratosphere/sf/sf_service_object.hpp @@ -25,16 +25,15 @@ namespace ams::sf { class IMitmServiceObject : public IServiceObject { protected: std::shared_ptr<::Service> forward_service; - os::ProcessId process_id; - ncm::ProgramId program_id; + sm::MitmProcessInfo client_info; public: - IMitmServiceObject(std::shared_ptr<::Service> &&s, os::ProcessId p, ncm::ProgramId r) : forward_service(std::move(s)), process_id(p), program_id(r) { /* ... */ } + IMitmServiceObject(std::shared_ptr<::Service> &&s, const sm::MitmProcessInfo &c) : forward_service(std::move(s)), client_info(c) { /* ... */ } static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id); }; /* Utility. */ - #define SF_MITM_SERVICE_OBJECT_CTOR(cls) cls(std::shared_ptr<::Service> &&s, os::ProcessId p, ncm::ProgramId r) : ::ams::sf::IMitmServiceObject(std::forward>(s), p, r) + #define SF_MITM_SERVICE_OBJECT_CTOR(cls) cls(std::shared_ptr<::Service> &&s, const sm::MitmProcessInfo &c) : ::ams::sf::IMitmServiceObject(std::forward>(s), c) template struct ServiceObjectTraits { diff --git a/include/stratosphere/sm/sm_manager_api.hpp b/include/stratosphere/sm/sm_manager_api.hpp index a499da1d..d746c557 100644 --- a/include/stratosphere/sm/sm_manager_api.hpp +++ b/include/stratosphere/sm/sm_manager_api.hpp @@ -23,7 +23,7 @@ namespace ams::sm::manager { /* Manager API. */ - Result RegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, const void *acid, size_t acid_size, const void *aci, size_t aci_size); + Result RegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, cfg::OverrideStatus status, const void *acid, size_t acid_size, const void *aci, size_t aci_size); Result UnregisterProcess(os::ProcessId process_id); /* Atmosphere extensions. */ diff --git a/include/stratosphere/sm/sm_mitm_api.hpp b/include/stratosphere/sm/sm_mitm_api.hpp index 282f984c..1e230a2f 100644 --- a/include/stratosphere/sm/sm_mitm_api.hpp +++ b/include/stratosphere/sm/sm_mitm_api.hpp @@ -17,7 +17,6 @@ #pragma once #include "sm_types.hpp" -#include "../ncm/ncm_types.hpp" namespace ams::sm::mitm { @@ -25,7 +24,7 @@ namespace ams::sm::mitm { Result InstallMitm(Handle *out_port, Handle *out_query, ServiceName name); Result UninstallMitm(ServiceName name); Result DeclareFutureMitm(ServiceName name); - Result AcknowledgeSession(Service *out_service, os::ProcessId *out_process_id, ncm::ProgramId *out_program_id, ServiceName name); + Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name); Result HasMitm(bool *out, ServiceName name); Result WaitMitm(ServiceName name); diff --git a/include/stratosphere/sm/sm_types.hpp b/include/stratosphere/sm/sm_types.hpp index 7ee5fde1..c3a06929 100644 --- a/include/stratosphere/sm/sm_types.hpp +++ b/include/stratosphere/sm/sm_types.hpp @@ -16,6 +16,8 @@ #pragma once #include +#include "../ncm/ncm_types.hpp" +#include "../cfg/cfg_types.hpp" namespace ams::sm { @@ -65,4 +67,12 @@ namespace ams::sm { }; static_assert(sizeof(ServiceRecord) == 0x30, "ServiceRecord definition!"); + /* For Mitm extensions. */ + struct MitmProcessInfo { + os::ProcessId process_id; + ncm::ProgramId program_id; + cfg::OverrideStatus override_status; + }; + static_assert(std::is_trivial::value && sizeof(MitmProcessInfo) == 0x20, "MitmProcessInfo definition!"); + } diff --git a/source/cfg/cfg_override.cpp b/source/cfg/cfg_override.cpp index f407b8d5..5140ce81 100644 --- a/source/cfg/cfg_override.cpp +++ b/source/cfg/cfg_override.cpp @@ -164,10 +164,9 @@ namespace ams::cfg { return 1; } - bool IsOverrideKeyHeld(const OverrideKey *cfg) { - u64 kHeld = 0; - bool keys_triggered = (R_SUCCEEDED(hid::GetKeysHeld(&kHeld)) && ((kHeld & cfg->key_combination) != 0)); - return IsSdCardInitialized() && (cfg->override_by_default ^ keys_triggered); + constexpr inline bool IsOverrideMatch(const OverrideStatus &status, const OverrideKey &cfg) { + bool keys_triggered = ((status.keys_held & cfg.key_combination) != 0); + return (cfg.override_by_default ^ keys_triggered); } void ParseIniFile(util::ini::Handler handler, const char *path, void *user_ctx) { @@ -207,82 +206,45 @@ namespace ams::cfg { } - bool IsHblOverrideKeyHeld(ncm::ProgramId program_id) { + OverrideStatus CaptureOverrideStatus(ncm::ProgramId program_id) { + OverrideStatus status = {}; + /* If the SD card isn't initialized, we can't override. */ if (!IsSdCardInitialized()) { - return false; + return status; } /* For system modules and anything launched before the home menu, always override. */ if (program_id < ncm::ProgramId::AppletStart || !pm::info::HasLaunchedProgram(ncm::ProgramId::AppletQlaunch)) { - return true; + status.SetProgramSpecific(); + return status; } /* Unconditionally refresh loader.ini contents. */ RefreshLoaderConfiguration(); - /* Check HBL config. */ - return IsHblProgramId(program_id) && IsOverrideKeyHeld(&g_hbl_override_config.override_key); - } - - bool IsProgramOverrideKeyHeld(ncm::ProgramId program_id) { - /* If the SD card isn't initialized, we can't override. */ - if (!IsSdCardInitialized()) { - return false; + /* If we can't read the key state, don't override anything. */ + if (R_FAILED(hid::GetKeysHeld(&status.keys_held))) { + return status; } - /* For system modules and anything launched before the home menu, always override. */ - if (program_id < ncm::ProgramId::AppletStart || !pm::info::HasLaunchedProgram(ncm::ProgramId::AppletQlaunch)) { - return true; + /* Detect Hbl. */ + if (IsHblProgramId(program_id) && IsOverrideMatch(status, g_hbl_override_config.override_key)) { + status.SetHbl(); } - /* Unconditionally refresh loader.ini contents. */ - RefreshLoaderConfiguration(); - + /* Detect content specific keys. */ const auto content_cfg = GetContentOverrideConfig(program_id); - return IsOverrideKeyHeld(&content_cfg.override_key); - } - - void GetOverrideKeyHeldStatus(bool *out_hbl, bool *out_program, ncm::ProgramId program_id) { - - /* If the SD card isn't initialized, we can't override. */ - if (!IsSdCardInitialized()) { - *out_hbl = false; - *out_program = false; - return; + if (IsOverrideMatch(status, content_cfg.override_key)) { + status.SetProgramSpecific(); } - /* For system modules and anything launched before the home menu, always override. */ - if (program_id < ncm::ProgramId::AppletStart || !pm::info::HasLaunchedProgram(ncm::ProgramId::AppletQlaunch)) { - *out_hbl = false; - *out_program = true; - return; + /* Only allow cheat enable if not HBL. */ + if (!status.IsHbl() && IsOverrideMatch(status, content_cfg.cheat_enable_key)) { + status.SetCheatEnabled(); } - /* Unconditionally refresh loader.ini contents. */ - RefreshLoaderConfiguration(); - - /* Set HBL output. */ - *out_hbl = IsHblProgramId(program_id) && IsOverrideKeyHeld(&g_hbl_override_config.override_key); - - /* Set content specific output. */ - const auto content_cfg = GetContentOverrideConfig(program_id); - *out_program = IsOverrideKeyHeld(&content_cfg.override_key); - } - - bool IsCheatEnableKeyHeld(ncm::ProgramId program_id) { - /* If the SD card isn't initialized, don't apply cheats. */ - if (!IsSdCardInitialized()) { - return false; - } - - /* Don't apply cheats to HBL. */ - if (IsHblOverrideKeyHeld(program_id)) { - return false; - } - - const auto content_cfg = GetContentOverrideConfig(program_id); - return IsOverrideKeyHeld(&content_cfg.cheat_enable_key); + return status; } /* HBL Configuration utilities. */ diff --git a/source/ldr/ldr_ams.c b/source/ldr/ldr_ams.c index 9353d0a2..cc710f69 100644 --- a/source/ldr/ldr_ams.c +++ b/source/ldr/ldr_ams.c @@ -31,3 +31,18 @@ Result ldrDmntAtmosphereHasLaunchedProgram(bool *out, u64 program_id) { Result ldrPmAtmosphereHasLaunchedProgram(bool *out, u64 program_id) { return _ldrAtmosphereHasLaunchedProgram(ldrPmGetServiceSession(), out, program_id); } + +Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) { + return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, *loc, *out_status, + .buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize }, + .buffers = { { out_program_info, sizeof(*out_program_info) } }, + ); +} + +Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status) { + const struct { + NcmProgramLocation loc; + CfgOverrideStatus status; + } in = { *loc, *status }; + return serviceDispatchInOut(ldrPmGetServiceSession(), 65002, in, *out); +} diff --git a/source/ldr/ldr_ams.h b/source/ldr/ldr_ams.h index eacee318..feff70e4 100644 --- a/source/ldr/ldr_ams.h +++ b/source/ldr/ldr_ams.h @@ -11,9 +11,17 @@ extern "C" { #endif +typedef struct { + u64 keys_down; + u64 flags; +} CfgOverrideStatus; + Result ldrPmAtmosphereHasLaunchedProgram(bool *out, u64 program_id); Result ldrDmntAtmosphereHasLaunchedProgram(bool *out, u64 program_id); +Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc); +Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status); + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/source/ldr/ldr_pm_api.cpp b/source/ldr/ldr_pm_api.cpp index 6a81ad23..d9b95d06 100644 --- a/source/ldr/ldr_pm_api.cpp +++ b/source/ldr/ldr_pm_api.cpp @@ -40,4 +40,15 @@ namespace ams::ldr::pm { return ldrPmAtmosphereHasLaunchedProgram(out, static_cast(program_id)); } + Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { + static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!"); + return ldrPmAtmosphereGetProgramInfo(reinterpret_cast(out), reinterpret_cast(out_status), reinterpret_cast(&loc)); + } + + Result AtmospherePinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { + static_assert(sizeof(*out) == sizeof(u64), "PinId definition!"); + static_assert(sizeof(status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!"); + return ldrPmAtmospherePinProgram(reinterpret_cast(out), reinterpret_cast(&loc), reinterpret_cast(&status)); + } + } diff --git a/source/pm/pm_ams.c b/source/pm/pm_ams.c index 9beeef7e..858cae2a 100644 --- a/source/pm/pm_ams.c +++ b/source/pm/pm_ams.c @@ -28,10 +28,31 @@ Result pminfoAtmosphereHasLaunchedProgram(bool *out, u64 program_id) { return rc; } -Result pmdmntAtmosphereGetProcessInfo(Handle* handle_out, NcmProgramLocation *loc_out, u64 pid) { +Result pminfoAtmosphereGetProcessInfo(NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid) { + struct { + NcmProgramLocation loc; + CfgOverrideStatus status; + } out; + + Result rc = serviceDispatchInOut(pmdmntGetServiceSession(), 65002, pid, out); + + if (R_SUCCEEDED(rc)) { + if (loc_out) *loc_out = out.loc; + if (status_out) *status_out = out.status; + } + + return rc; +} + +Result pmdmntAtmosphereGetProcessInfo(Handle* handle_out, NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid) { Handle tmp_handle; - Result rc = serviceDispatchInOut(pmdmntGetServiceSession(), 65000, pid, *loc_out, + struct { + NcmProgramLocation loc; + CfgOverrideStatus status; + } out; + + Result rc = serviceDispatchInOut(pmdmntGetServiceSession(), 65000, pid, out, .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, .out_handles = &tmp_handle, ); @@ -42,6 +63,9 @@ Result pmdmntAtmosphereGetProcessInfo(Handle* handle_out, NcmProgramLocation *lo } else { svcCloseHandle(tmp_handle); } + + if (loc_out) *loc_out = out.loc; + if (status_out) *status_out = out.status; } return rc; diff --git a/source/pm/pm_ams.h b/source/pm/pm_ams.h index 5abcad08..74e2a015 100644 --- a/source/pm/pm_ams.h +++ b/source/pm/pm_ams.h @@ -11,10 +11,16 @@ extern "C" { #endif +typedef struct { + u64 keys_held; + u64 flags; +} CfgOverrideStatus; + Result pminfoAtmosphereGetProcessId(u64 *out_pid, u64 program_id); Result pminfoAtmosphereHasLaunchedProgram(bool *out, u64 program_id); +Result pminfoAtmosphereGetProcessInfo(NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid); -Result pmdmntAtmosphereGetProcessInfo(Handle *out, NcmProgramLocation *loc_out, u64 pid); +Result pmdmntAtmosphereGetProcessInfo(Handle *out, NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid); Result pmdmntAtmosphereGetCurrentLimitInfo(u64 *out_cur, u64 *out_lim, u32 group, u32 resource); #ifdef __cplusplus diff --git a/source/pm/pm_dmnt_api.cpp b/source/pm/pm_dmnt_api.cpp index 7087c83c..2fec2e0c 100644 --- a/source/pm/pm_dmnt_api.cpp +++ b/source/pm/pm_dmnt_api.cpp @@ -39,10 +39,12 @@ namespace ams::pm::dmnt { return ResultSuccess(); } - Result AtmosphereGetProcessInfo(Handle *out_handle, ncm::ProgramLocation *out_loc, os::ProcessId process_id) { + Result AtmosphereGetProcessInfo(Handle *out_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) { *out_handle = INVALID_HANDLE; *out_loc = {}; - return pmdmntAtmosphereGetProcessInfo(out_handle, reinterpret_cast(out_loc), static_cast(process_id)); + *out_status = {}; + static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus)); + return pmdmntAtmosphereGetProcessInfo(out_handle, reinterpret_cast(out_loc), reinterpret_cast(out_status), static_cast(process_id)); } Result AtmosphereGetCurrentLimitInfo(u64 *out_current_value, u64 *out_limit_value, ResourceLimitGroup group, LimitableResource resource) { diff --git a/source/pm/pm_info_api.cpp b/source/pm/pm_info_api.cpp index 969e9619..e07a1531 100644 --- a/source/pm/pm_info_api.cpp +++ b/source/pm/pm_info_api.cpp @@ -40,6 +40,15 @@ namespace ams::pm::info { return pminfoAtmosphereGetProcessId(reinterpret_cast(out_process_id), static_cast(program_id)); } + Result GetProcessInfo(ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) { + std::scoped_lock lk(g_info_lock); + + *out_loc = {}; + *out_status = {}; + static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus)); + return pminfoAtmosphereGetProcessInfo(reinterpret_cast(out_loc), reinterpret_cast(out_status), static_cast(process_id)); + } + Result WEAK HasLaunchedProgram(bool *out, ncm::ProgramId program_id) { std::scoped_lock lk(g_info_lock); diff --git a/source/sf/hipc/sf_hipc_mitm_query_api.cpp b/source/sf/hipc/sf_hipc_mitm_query_api.cpp index abf74717..12d881be 100644 --- a/source/sf/hipc/sf_hipc_mitm_query_api.cpp +++ b/source/sf/hipc/sf_hipc_mitm_query_api.cpp @@ -30,8 +30,8 @@ namespace ams::sf::hipc::impl { public: MitmQueryService(ServerManagerBase::MitmQueryFunction qf) : query_function(qf) { /* ... */ } - void ShouldMitm(sf::Out out, os::ProcessId process_id, ncm::ProgramId program_id) { - out.SetValue(this->query_function(process_id, program_id)); + void ShouldMitm(sf::Out out, const sm::MitmProcessInfo &client_info) { + out.SetValue(this->query_function(client_info)); } public: DEFINE_SERVICE_DISPATCH_TABLE { diff --git a/source/sm/sm_ams.c b/source/sm/sm_ams.c index 713fd393..ac606e67 100644 --- a/source/sm/sm_ams.c +++ b/source/sm/sm_ams.c @@ -107,21 +107,16 @@ Result smAtmosphereMitmDeclareFuture(SmServiceName name) { return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65006); } -Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, SmServiceName name) { +Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, void *_out, SmServiceName name) { struct { - u64 pid; - u64 tid; - } out; + u64 process_id; + u64 program_id; + u64 keys_held; + u64 flags; + } *out = _out; - Result rc = serviceDispatchInOut(&g_smAtmosphereMitmSrv, 65003, name, out, + return serviceDispatchInOut(&g_smAtmosphereMitmSrv, 65003, name, *out, .out_num_objects = 1, .out_objects = srv_out, ); - - if (R_SUCCEEDED(rc)) { - if (pid_out) *pid_out = out.pid; - if (tid_out) *tid_out = out.tid; - } - - return rc; } diff --git a/source/sm/sm_ams.h b/source/sm/sm_ams.h index 7358e3a7..3036cde9 100644 --- a/source/sm/sm_ams.h +++ b/source/sm/sm_ams.h @@ -28,7 +28,7 @@ void smAtmosphereCloseSession(Service *srv); Result smAtmosphereMitmInstall(Service *fwd_srv, Handle *handle_out, Handle *query_out, SmServiceName name); Result smAtmosphereMitmUninstall(SmServiceName name); Result smAtmosphereMitmDeclareFuture(SmServiceName name); -Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, SmServiceName name); +Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, void *info_out, SmServiceName name); #ifdef __cplusplus } diff --git a/source/sm/sm_manager_api.cpp b/source/sm/sm_manager_api.cpp index 41bb3e75..c7f85210 100644 --- a/source/sm/sm_manager_api.cpp +++ b/source/sm/sm_manager_api.cpp @@ -19,8 +19,9 @@ namespace ams::sm::manager { /* Manager API. */ - Result RegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, const void *acid, size_t acid_size, const void *aci, size_t aci_size) { - return smManagerAtmosphereRegisterProcess(static_cast(process_id), static_cast(program_id), acid, acid_size, aci, aci_size); + Result RegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, cfg::OverrideStatus status, const void *acid, size_t acid_size, const void *aci, size_t aci_size) { + static_assert(sizeof(status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition"); + return smManagerAtmosphereRegisterProcess(static_cast(process_id), static_cast(program_id), reinterpret_cast(&status), acid, acid_size, aci, aci_size); } Result UnregisterProcess(os::ProcessId process_id) { diff --git a/source/sm/sm_mitm_api.cpp b/source/sm/sm_mitm_api.cpp index 90503eb1..cc5807c7 100644 --- a/source/sm/sm_mitm_api.cpp +++ b/source/sm/sm_mitm_api.cpp @@ -36,9 +36,9 @@ namespace ams::sm::mitm { }); } - Result AcknowledgeSession(Service *out_service, os::ProcessId *out_process_id, ncm::ProgramId *out_program_id, ServiceName name) { + Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name) { return impl::DoWithMitmAcknowledgementSession([&]() { - return smAtmosphereMitmAcknowledgeSession(out_service, &out_process_id->value, &out_program_id->value, impl::ConvertName(name)); + return smAtmosphereMitmAcknowledgeSession(out_service, reinterpret_cast(out_info), impl::ConvertName(name)); }); } diff --git a/source/sm/smm_ams.c b/source/sm/smm_ams.c index ada3d7ed..b8871400 100644 --- a/source/sm/smm_ams.c +++ b/source/sm/smm_ams.c @@ -19,11 +19,12 @@ Result smManagerAtmosphereEndInitialDefers(void) { return serviceDispatch(smManagerGetServiceSession(), 65000); } -Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size) { +Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const CfgOverrideStatus *status, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size) { const struct { u64 pid; u64 tid; - } in = { pid, tid }; + CfgOverrideStatus status; + } in = { pid, tid, *status }; return serviceDispatchIn(smManagerGetServiceSession(), 65002, in, .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias, diff --git a/source/sm/smm_ams.h b/source/sm/smm_ams.h index 0af187f5..0f9c1d12 100644 --- a/source/sm/smm_ams.h +++ b/source/sm/smm_ams.h @@ -11,8 +11,13 @@ extern "C" { #endif +typedef struct { + u64 keys_held; + u64 flags; +} CfgOverrideStatus; + Result smManagerAtmosphereEndInitialDefers(void); -Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size); +Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const CfgOverrideStatus *status, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size); Result smManagerAtmosphereHasMitm(bool *out, SmServiceName name); #ifdef __cplusplus