pm: inform sm of title ids. remove inconsistent mitm association.

This commit is contained in:
Michael Scire 2019-07-03 22:57:49 -07:00 committed by SciresM
parent 4db212ea7b
commit 6777dd9b38
19 changed files with 150 additions and 97 deletions

View file

@ -27,7 +27,7 @@ class BpcMitmService : public IMitmServiceObject {
RebootSystem = 1,
};
public:
BpcMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
BpcMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
/* ... */
}

View file

@ -73,12 +73,6 @@ void FsMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx
case CommandId::SetCurrentProcess:
if (R_SUCCEEDED(ctx->rc)) {
this_ptr->has_initialized = true;
this_ptr->process_id = ctx->request.Pid;
this_ptr->title_id = sts::ncm::TitleId{this_ptr->process_id};
if (R_FAILED(MitmQueryUtils::GetAssociatedTidForPid(this_ptr->process_id, &this_ptr->title_id))) {
/* Log here, if desired. */
}
break;
}
break;
default:

View file

@ -44,7 +44,7 @@ class FsMitmService : public IMitmServiceObject {
bool has_initialized = false;
bool should_override_contents;
public:
FsMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
FsMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
if (Utils::HasSdDisableMitMFlag(static_cast<u64>(this->title_id))) {
this->should_override_contents = false;
} else {

View file

@ -28,7 +28,7 @@ class NsAmMitmService : public IMitmServiceObject {
GetRunningApplicationProgramId = 92,
};
public:
NsAmMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
NsAmMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
/* ... */
}

View file

@ -67,7 +67,7 @@ class NsWebMitmService : public IMitmServiceObject {
GetDocumentInterface = 7999,
};
public:
NsWebMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
NsWebMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
/* ... */
}

View file

@ -35,7 +35,7 @@ class SetMitmService : public IMitmServiceObject {
OverrideLocale locale;
bool got_locale;
public:
SetMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
SetMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
this->got_locale = false;
}

View file

@ -33,7 +33,7 @@ class SetSysMitmService : public IMitmServiceObject {
GetEdid = 41,
};
public:
SetSysMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
SetSysMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
/* ... */
}

@ -1 +1 @@
Subproject commit ccfadc501bb89c3b42b7b4ed473094fee8c1043f
Subproject commit b9e53052732699e1f7af8ad061181e3798c3f8fc

View file

@ -686,9 +686,6 @@ namespace sts::ldr {
}
}
/* Inform SM about the title for association purposes. */
R_ASSERT(sm::mitm::AssociateProcessIdAndTitleId(process_id, static_cast<u64>(loc.title_id)));
/* If we're overriding for HBL, perform HTML document redirection. */
if (mount.IsHblMounted()) {
/* Don't validate result, failure is okay. */

View file

@ -65,6 +65,8 @@
"svcReplyAndReceiveWithUserBuffer": "0x44",
"svcCreateEvent": "0x45",
"svcSetUnsafeLimit": "0x4a",
"svcDebugActiveProcess": "0x60",
"svcGetDebugEvent": "0x63",
"svcGetProcessList": "0x65",
"svcStartProcess": "0x7a",
"svcTerminateProcess": "0x7b",
@ -74,6 +76,13 @@
"svcGetSystemInfo": "0x6f",
"svcCallSecureMonitor": "0x7F"
}
},
{
"type": "debug_flags",
"value": {
"allow_debug": false,
"force_debug": true
}
}
]
}

View file

@ -245,12 +245,6 @@ namespace sts::boot2 {
cfg::WaitSdCardInitialized();
R_ASSERT(fsdevMountSdmc());
/* Find out whether we are maintenance mode. */
const bool maintenance = IsMaintenanceMode();
if (maintenance) {
pm::bm::SetMaintenanceBoot();
}
/* Wait for other atmosphere mitm modules to initialize. */
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("set:sys")));
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200) {
@ -259,16 +253,26 @@ namespace sts::boot2 {
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc:c")));
}
/* Find out whether we are maintenance mode. */
const bool maintenance = IsMaintenanceMode();
if (maintenance) {
pm::bm::SetMaintenanceBoot();
}
/* Launch Atmosphere dmnt, using FsStorageId_None to force SD card boot. */
LaunchTitle(nullptr, ncm::TitleLocation::Make(ncm::TitleId::Dmnt, ncm::StorageId::None), 0);
/* Launch additional programs. */
if (maintenance) {
LaunchList(AdditionalMaintenanceLaunchPrograms, NumAdditionalMaintenanceLaunchPrograms);
/* Starting in 7.0.0, npns is launched during maintenance boot. */
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_700) {
LaunchTitle(nullptr, ncm::TitleLocation::Make(ncm::TitleId::Npns, ncm::StorageId::NandSystem), 0);
}
} else {
LaunchList(AdditionalLaunchPrograms, NumAdditionalLaunchPrograms);
}
/* Launch user programs off of the SD. */
LaunchFlaggedProgramsFromSdCard();

View file

@ -245,7 +245,7 @@ namespace sts::pm::impl {
/* Register with FS and SM. */
R_TRY(fsprRegisterProgram(process_id, static_cast<u64>(location.title_id), static_cast<FsStorageId>(location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size));
R_TRY(sm::manager::RegisterProcess(process_id, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size));
R_TRY(sm::manager::RegisterProcess(process_id, location.title_id, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size));
/* Set flags. */
if (is_application) {

View file

@ -74,16 +74,78 @@ namespace {
constexpr u32 PrivilegedFileAccessHeader[0x1C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000};
constexpr u32 PrivilegedFileAccessControl[0x2C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
constexpr u8 PrivilegedServiceAccessControl[] = {0x80, '*', 0x00, '*'};
constexpr size_t ProcessCountMax = 0x40;
/* TODO: Libstratosphere this stuff during fatal/creport rewrite. */
enum class DebugEventType : u32 {
AttachProcess = 0,
AttachThread = 1,
ExitProcess = 2,
ExitThread = 3,
Exception = 4
};
struct AttachProcessInfo {
sts::ncm::TitleId title_id;
u64 process_id;
char name[0xC];
u32 flags;
u64 user_exception_context_address; /* 5.0.0+ */
};
union DebugInfo {
AttachProcessInfo attach_process;
};
struct DebugEventInfo {
DebugEventType type;
u32 flags;
u64 thread_id;
union {
DebugInfo info;
u64 _[0x40/sizeof(u64)];
};
};
/* This uses debugging SVCs to retrieve a process's title id. */
sts::ncm::TitleId GetProcessTitleId(u64 process_id) {
/* Get a debug handle, or return our title id. */
AutoHandle debug_handle;
if (R_FAILED(svcDebugActiveProcess(debug_handle.GetPointer(), process_id))) {
u64 current_process_id = 0;
R_ASSERT(svcGetProcessId(&current_process_id, CUR_PROCESS_HANDLE));
if (current_process_id == process_id) {
return __stratosphere_title_id;
} else {
/* If we fail to debug a process other than our own, abort. */
std::abort();
}
}
/* Loop until we get the event that tells us about the process. */
DebugEventInfo d;
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()))) {
if (d.type == DebugEventType::AttachProcess) {
return d.info.attach_process.title_id;
}
}
/* If we somehow didn't get the event, abort. */
std::abort();
}
/* This works around a bug fixed by FS in 4.0.0. */
/* Not doing so will cause KIPs with higher process IDs than 7 to be unable to use filesystem services. */
void RegisterPrivilegedProcessWithFs(u64 process_id) {
/* It also registers privileged processes with SM, so that their title IDs can be known. */
void RegisterPrivilegedProcess(u64 process_id) {
fsprUnregisterProgram(process_id);
fsprRegisterProgram(process_id, process_id, FsStorageId_NandSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl));
sts::sm::manager::UnregisterProcess(process_id);
sts::sm::manager::RegisterProcess(process_id, GetProcessTitleId(process_id), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl));
}
void RegisterPrivilegedProcessesWithFs() {
void RegisterPrivilegedProcesses() {
/* Get privileged process range. */
u64 min_priv_process_id = 0, max_priv_process_id = 0;
sts::cfg::GetInitialProcessRange(&min_priv_process_id, &max_priv_process_id);
@ -94,7 +156,7 @@ namespace {
R_ASSERT(svcGetProcessList(&num_pids, pids, ProcessCountMax));
for (size_t i = 0; i < num_pids; i++) {
if (min_priv_process_id <= pids[i] && pids[i] <= max_priv_process_id) {
RegisterPrivilegedProcessWithFs(pids[i]);
RegisterPrivilegedProcess(pids[i]);
}
}
}
@ -106,12 +168,13 @@ void __appInit(void) {
DoWithSmSession([&]() {
R_ASSERT(fsprInitialize());
R_ASSERT(smManagerInitialize());
/* This works around a bug with process permissions on < 4.0.0. */
RegisterPrivilegedProcessesWithFs();
/* It also informs SM of privileged process information. */
RegisterPrivilegedProcesses();
/* Use AMS manager extension to tell SM that FS has been worked around. */
R_ASSERT(smManagerInitialize());
R_ASSERT(sts::sm::manager::EndInitialDefers());
R_ASSERT(lrInitialize());

View file

@ -16,6 +16,8 @@
#include <switch.h>
#include <stratosphere.hpp>
#include <stratosphere/cfg.hpp>
#include <stratosphere/ncm.hpp>
#include <stratosphere/sm.hpp>
#include "sm_service_manager.hpp"
@ -32,6 +34,7 @@ namespace sts::sm::impl {
/* Types. */
struct ProcessInfo {
u64 pid;
ncm::TitleId tid;
size_t access_control_size;
u8 access_control[AccessControlSizeMax];
@ -41,11 +44,15 @@ namespace sts::sm::impl {
void Free() {
this->pid = InvalidProcessId;
this->tid = ncm::TitleId::Invalid;
this->access_control_size = 0;
std::memset(this->access_control, 0, sizeof(this->access_control));
}
};
/* Forward declaration, for use in ServiceInfo. */
ncm::TitleId GetTitleIdForMitm(u64 pid);
struct ServiceInfo {
ServiceName name;
u64 owner_pid;
@ -95,9 +102,10 @@ namespace sts::sm::impl {
this->mitm_pid = InvalidProcessId;
}
void AcknowledgeMitmSession(u64 *out_pid, Handle *out_hnd) {
void AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd) {
/* Copy to output. */
*out_pid = this->mitm_waiting_ack_pid;
*out_tid = GetTitleIdForMitm(this->mitm_waiting_ack_pid);
*out_hnd = this->mitm_fwd_sess_h.Move();
this->mitm_waiting_ack = false;
this->mitm_waiting_ack_pid = InvalidProcessId;
@ -149,27 +157,13 @@ namespace sts::sm::impl {
};
class InitialProcessIdLimits {
public:
static constexpr u64 InitialProcessIdMin = 0x00;
static constexpr u64 InitialProcessIdMax = 0x50;
private:
u64 min;
u64 max;
public:
InitialProcessIdLimits() {
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_500) {
/* On 5.0.0+, we can get precise limits from svcGetSystemInfo. */
R_ASSERT(svcGetSystemInfo(&this->min, SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum));
R_ASSERT(svcGetSystemInfo(&this->max, SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum));
} else if (GetRuntimeFirmwareVersion() >= FirmwareVersion_400) {
/* On 4.0.0-4.1.0, we can get the precise limits from normal svcGetInfo. */
R_ASSERT(svcGetInfo(&this->min, InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum));
R_ASSERT(svcGetInfo(&this->max, InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum));
} else {
/* On < 4.0.0, we just use hardcoded extents. */
this->min = InitialProcessIdMin;
this->max = InitialProcessIdMax;
}
/* Retrieve process limits. */
cfg::GetInitialProcessRange(&this->min, &this->max);
/* Ensure range is sane. */
if (this->min > this->max) {
@ -301,6 +295,15 @@ namespace sts::sm::impl {
return pid != InvalidProcessId;
}
ncm::TitleId GetTitleIdForMitm(u64 pid) {
/* Anything that can request a mitm session must have a process info. */
const auto process_info = GetProcessInfo(pid);
if (process_info == nullptr) {
std::abort();
}
return process_info->tid;
}
bool ShouldDeferForInit(ServiceName service) {
/* Once end has been called, we're done. */
if (g_ended_initial_defers) {
@ -321,10 +324,12 @@ namespace sts::sm::impl {
u64 magic;
u64 cmd_id;
u64 pid;
ncm::TitleId tid;
} *info = ((decltype(info))ipcPrepareHeader(&c, sizeof(*info)));
info->magic = SFCI_MAGIC;
info->cmd_id = 65000;
info->pid = pid;
info->tid = GetTitleIdForMitm(pid);
R_TRY(ipcDispatch(service_info->mitm_query_h.Get()));
}
@ -414,9 +419,9 @@ namespace sts::sm::impl {
}
/* Process management. */
Result RegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size) {
Result RegisterProcess(u64 pid, ncm::TitleId tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size) {
/* Check that access control will fit in the ServiceInfo. */
if (aci0_sac_size > AccessControlSizeMax) {
if (aci_sac_size > AccessControlSizeMax) {
return ResultSmTooLargeAccessControl;
}
@ -427,15 +432,16 @@ namespace sts::sm::impl {
}
/* Validate restrictions. */
if (!aci0_sac_size) {
if (!aci_sac_size) {
return ResultSmNotAllowed;
}
R_TRY(ValidateAccessControl(AccessControlEntry(acid_sac, acid_sac_size), AccessControlEntry(aci0_sac, aci0_sac_size)));
R_TRY(ValidateAccessControl(AccessControlEntry(acid_sac, acid_sac_size), AccessControlEntry(aci_sac, aci_sac_size)));
/* Save info. */
proc->pid = pid;
proc->access_control_size = aci0_sac_size;
std::memcpy(proc->access_control, aci0_sac, proc->access_control_size);
proc->tid = tid;
proc->access_control_size = aci_sac_size;
std::memcpy(proc->access_control, aci_sac, proc->access_control_size);
return ResultSuccess;
}
@ -662,7 +668,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result AcknowledgeMitmSession(u64 *out_pid, Handle *out_hnd, u64 pid, ServiceName service) {
Result AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, u64 pid, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -686,30 +692,7 @@ namespace sts::sm::impl {
}
/* Acknowledge. */
service_info->AcknowledgeMitmSession(out_pid, out_hnd);
return ResultSuccess;
}
Result AssociatePidTidForMitm(u64 pid, u64 tid) {
for (size_t i = 0; i < ServiceCountMax; i++) {
const ServiceInfo *service_info = &g_service_list[i];
if (IsValidProcessId(service_info->mitm_pid)) {
/* Send association command to all mitm processes. */
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u64 pid;
u64 tid;
} *info = ((decltype(info))ipcPrepareHeader(&c, sizeof(*info)));
info->magic = SFCI_MAGIC;
info->cmd_id = 65001;
info->pid = pid;
info->tid = tid;
ipcDispatch(service_info->mitm_query_h.Get());
}
}
service_info->AcknowledgeMitmSession(out_pid, out_tid, out_hnd);
return ResultSuccess;
}

View file

@ -17,11 +17,12 @@
#pragma once
#include <switch.h>
#include <stratosphere/sm.hpp>
#include <stratosphere/ncm.hpp>
namespace sts::sm::impl {
/* Process management. */
Result RegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size);
Result RegisterProcess(u64 pid, ncm::TitleId tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size);
Result UnregisterProcess(u64 pid);
/* Service management. */
@ -37,8 +38,7 @@ namespace sts::sm::impl {
Result WaitMitm(ServiceName service);
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service);
Result UninstallMitm(u64 pid, ServiceName service);
Result AcknowledgeMitmSession(u64 *out_pid, Handle *out_hnd, u64 pid, ServiceName service);
Result AssociatePidTidForMitm(u64 pid, u64 tid);
Result AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, u64 pid, ServiceName service);
/* Dmnt record extensions. */
Result GetServiceRecord(ServiceRecord *out, ServiceName service);

View file

@ -22,8 +22,8 @@
namespace sts::sm {
Result ManagerService::RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac) {
return impl::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements);
Result ManagerService::RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac) {
return impl::RegisterProcess(pid, ncm::TitleId::Invalid, acid_sac.buffer, acid_sac.num_elements, aci_sac.buffer, aci_sac.num_elements);
}
Result ManagerService::UnregisterProcess(u64 pid) {
@ -38,4 +38,9 @@ namespace sts::sm {
R_ASSERT(impl::HasMitm(out.GetPointer(), service));
}
Result ManagerService::AtmosphereRegisterProcess(u64 pid, ncm::TitleId tid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac) {
/* This takes in a title id, unlike RegisterProcess. */
return impl::RegisterProcess(pid, tid, acid_sac.buffer, acid_sac.num_elements, aci_sac.buffer, aci_sac.num_elements);
}
}

View file

@ -18,6 +18,7 @@
#include <switch.h>
#include <stratosphere.hpp>
#include <stratosphere/sm.hpp>
#include <stratosphere/ncm.hpp>
namespace sts::sm {
@ -31,13 +32,15 @@ namespace sts::sm {
AtmosphereEndInitDefers = 65000,
AtmosphereHasMitm = 65001,
AtmosphereRegisterProcess = 65002,
};
private:
/* Actual commands. */
virtual Result RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac);
virtual Result RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac);
virtual Result UnregisterProcess(u64 pid);
virtual void AtmosphereEndInitDefers();
virtual void AtmosphereHasMitm(Out<bool> out, ServiceName service);
virtual Result AtmosphereRegisterProcess(u64 pid, ncm::TitleId tid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(ManagerService, RegisterProcess),
@ -45,6 +48,7 @@ namespace sts::sm {
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereEndInitDefers),
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereHasMitm),
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereRegisterProcess),
};
};

View file

@ -60,14 +60,9 @@ namespace sts::sm {
return impl::UninstallMitm(this->pid, service);
}
Result UserService::AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service) {
Result UserService::AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<ncm::TitleId> client_tid, Out<MovedHandle> fwd_h, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
}
Result UserService::AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid) {
R_TRY(this->EnsureInitialized());
return impl::AssociatePidTidForMitm(pid, tid);
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), client_tid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
}
Result UserService::AtmosphereHasMitm(Out<bool> out, ServiceName service) {

View file

@ -18,6 +18,7 @@
#include <switch.h>
#include <stratosphere.hpp>
#include <stratosphere/sm.hpp>
#include <stratosphere/ncm.hpp>
namespace sts::sm {
@ -33,7 +34,7 @@ namespace sts::sm {
AtmosphereInstallMitm = 65000,
AtmosphereUninstallMitm = 65001,
AtmosphereAssociatePidTidForMitm = 65002,
/* Deprecated: AtmosphereAssociatePidTidForMitm = 65002 */
AtmosphereAcknowledgeMitmSession = 65003,
AtmosphereHasMitm = 65004,
AtmosphereWaitMitm = 65005,
@ -56,8 +57,7 @@ namespace sts::sm {
/* Atmosphere commands. */
virtual Result AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, ServiceName service);
virtual Result AtmosphereUninstallMitm(ServiceName service);
virtual Result AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid);
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service);
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<ncm::TitleId> client_tid, Out<MovedHandle> fwd_h, ServiceName service);
virtual Result AtmosphereHasMitm(Out<bool> out, ServiceName service);
virtual Result AtmosphereWaitMitm(ServiceName service);
@ -72,7 +72,6 @@ namespace sts::sm {
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereInstallMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereUninstallMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAssociatePidTidForMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAcknowledgeMitmSession),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereWaitMitm),