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