new-ipc: implement deferral. sm now works.

This commit is contained in:
Michael Scire 2019-10-11 02:15:14 -07:00 committed by SciresM
parent f4dcd1db9b
commit c8ed190e5c
13 changed files with 193 additions and 157 deletions

View file

@ -127,6 +127,10 @@ namespace sts::sf::hipc {
os::Mutex waitlist_mutex;
os::WaitableManager waitlist;
os::Mutex deferred_session_mutex;
using DeferredSessionList = typename util::IntrusiveListMemberTraits<&ServerSession::deferred_list_node>::ListType;
DeferredSessionList deferred_session_list;
private:
virtual void RegisterSessionToWaitList(ServerSession *session) override final;
void RegisterToWaitList(os::WaitableHolder *holder);
@ -138,6 +142,8 @@ namespace sts::sf::hipc {
Result ProcessForMitmServer(os::WaitableHolder *holder);
Result ProcessForSession(os::WaitableHolder *holder);
void ProcessDeferredSessions();
template<typename ServiceImpl, auto MakeShared = std::make_shared<ServiceImpl>>
void RegisterServerImpl(Handle port_handle, sm::ServiceName service_name, bool managed, cmif::ServiceObjectHolder &&static_holder) {
/* Allocate server memory. */

View file

@ -32,6 +32,7 @@ namespace sts::sf::hipc {
NON_COPYABLE(ServerSession);
NON_MOVEABLE(ServerSession);
private:
util::IntrusiveListNode deferred_list_node;
cmif::ServiceObjectHolder srv_obj_holder;
cmif::PointerAndSize pointer_buffer;
cmif::PointerAndSize saved_message;

View file

@ -936,10 +936,15 @@ namespace sts::sf::impl {
if constexpr (Info.arg_type == ArgumentType::InData) {
/* New in rawdata. */
constexpr size_t Offset = CommandMeta::InDataOffsets[Info.in_raw_data_index];
return *reinterpret_cast<const T *>(in_raw_data.GetAddress() + Offset);
if constexpr (!std::is_same<T, bool>::value) {
return *reinterpret_cast<const T *>(in_raw_data.GetAddress() + Offset);
} else {
/* Special case bools. */
return *reinterpret_cast<const u8 *>(in_raw_data.GetAddress() + Offset) & 1;
}
} else if constexpr (Info.arg_type == ArgumentType::OutData) {
/* New out rawdata. */
constexpr size_t Offset = CommandMeta::InDataOffsets[Info.in_raw_data_index];
constexpr size_t Offset = CommandMeta::InDataOffsets[Info.out_raw_data_index];
return T(out_raw_holder.template GetAddress<Offset, T::TypeSize>());
} else if constexpr (Info.arg_type == ArgumentType::InHandle) {
/* New InHandle. */

View file

@ -127,6 +127,27 @@ namespace sts::sf::hipc {
return this->ProcessRequest(session, tls_message);
}
void ServerManagerBase::ProcessDeferredSessions() {
/* Iterate over the list of deferred sessions, and see if we can't do anything. */
std::scoped_lock lk(this->deferred_session_mutex);
auto it = this->deferred_session_list.begin();
while (it != this->deferred_session_list.end()) {
ServerSession *session = static_cast<ServerSession *>(&*it);
R_TRY_CATCH(this->ProcessForSession(session)) {
R_CATCH(ResultServiceFrameworkRequestDeferredByUser) {
/* Session is still deferred, so let's continue. */
it++;
continue;
}
/* TODO: N has a result that undefers without success. */
} R_END_TRY_CATCH_WITH_ASSERT;
/* We succeeded! Remove from deferred list. */
it = this->deferred_session_list.erase(it);
}
}
Result ServerManagerBase::Process(os::WaitableHolder *holder) {
switch (static_cast<UserDataTag>(holder->GetUserData())) {
case UserDataTag::Server:
@ -136,8 +157,19 @@ namespace sts::sf::hipc {
return this->ProcessForMitmServer(holder);
break;
case UserDataTag::Session:
/* TODO: Process deferred. */
return this->ProcessForSession(holder);
/* Try to process for session. */
R_TRY_CATCH(this->ProcessForSession(holder)) {
R_CATCH(ResultServiceFrameworkRequestDeferredByUser) {
/* The session was deferred, so push it onto the deferred session list. */
std::scoped_lock lk(this->deferred_session_mutex);
this->deferred_session_list.push_back(*static_cast<ServerSession *>(holder));
return ResultSuccess;
}
} R_END_TRY_CATCH;
/* We successfully invoked a command...so let's see if anything can be undeferred. */
this->ProcessDeferredSessions();
return ResultSuccess;
break;
STS_UNREACHABLE_DEFAULT_CASE();
}

View file

@ -34,7 +34,7 @@ namespace sts::sm::impl {
/* Types. */
struct ProcessInfo {
u64 pid;
os::ProcessId pid;
ncm::TitleId tid;
size_t access_control_size;
u8 access_control[AccessControlSizeMax];
@ -44,7 +44,7 @@ namespace sts::sm::impl {
}
void Free() {
this->pid = InvalidProcessId;
this->pid = os::InvalidProcessId;
this->tid = ncm::TitleId::Invalid;
this->access_control_size = 0;
std::memset(this->access_control, 0, sizeof(this->access_control));
@ -52,11 +52,11 @@ namespace sts::sm::impl {
};
/* Forward declaration, for use in ServiceInfo. */
ncm::TitleId GetTitleIdForMitm(u64 pid);
ncm::TitleId GetTitleIdForMitm(os::ProcessId pid);
struct ServiceInfo {
ServiceName name;
u64 owner_pid;
os::ProcessId owner_pid;
os::ManagedHandle port_h;
/* Debug. */
@ -64,13 +64,13 @@ namespace sts::sm::impl {
bool is_light;
/* Mitm Extension. */
u64 mitm_pid;
os::ProcessId mitm_pid;
os::ManagedHandle mitm_port_h;
os::ManagedHandle mitm_query_h;
/* Acknowledgement members. */
bool mitm_waiting_ack;
u64 mitm_waiting_ack_pid;
os::ProcessId mitm_waiting_ack_pid;
os::ManagedHandle mitm_fwd_sess_h;
ServiceInfo() {
@ -86,12 +86,12 @@ namespace sts::sm::impl {
/* Reset all other members. */
this->name = InvalidServiceName;
this->owner_pid = InvalidProcessId;
this->owner_pid = os::InvalidProcessId;
this->max_sessions = 0;
this->is_light = false;
this->mitm_pid = InvalidProcessId;
this->mitm_pid = os::InvalidProcessId;
this->mitm_waiting_ack = false;
this->mitm_waiting_ack_pid = InvalidProcessId;
this->mitm_waiting_ack_pid = os::InvalidProcessId;
}
void FreeMitm() {
@ -100,16 +100,16 @@ namespace sts::sm::impl {
this->mitm_query_h.Clear();
/* Reset mitm members. */
this->mitm_pid = InvalidProcessId;
this->mitm_pid = os::InvalidProcessId;
}
void AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd) {
void AcknowledgeMitmSession(os::ProcessId *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;
this->mitm_waiting_ack_pid = os::InvalidProcessId;
}
};
@ -159,8 +159,8 @@ namespace sts::sm::impl {
class InitialProcessIdLimits {
private:
u64 min;
u64 max;
os::ProcessId min;
os::ProcessId max;
public:
InitialProcessIdLimits() {
/* Retrieve process limits. */
@ -170,8 +170,8 @@ namespace sts::sm::impl {
STS_ASSERT(this->min <= this->max);
}
bool IsInitialProcess(u64 pid) const {
STS_ASSERT(pid != InvalidProcessId);
bool IsInitialProcess(os::ProcessId pid) const {
STS_ASSERT(pid != os::InvalidProcessId);
return this->min <= pid && pid <= this->max;
}
};
@ -184,7 +184,7 @@ namespace sts::sm::impl {
bool g_ended_initial_defers;
/* Helper functions for interacting with processes/services. */
ProcessInfo *GetProcessInfo(u64 pid) {
ProcessInfo *GetProcessInfo(os::ProcessId pid) {
for (size_t i = 0; i < ProcessCountMax; i++) {
if (g_process_list[i].pid == pid) {
return &g_process_list[i];
@ -194,19 +194,19 @@ namespace sts::sm::impl {
}
ProcessInfo *GetFreeProcessInfo() {
return GetProcessInfo(InvalidProcessId);
return GetProcessInfo(os::InvalidProcessId);
}
bool HasProcessInfo(u64 pid) {
bool HasProcessInfo(os::ProcessId pid) {
return GetProcessInfo(pid) != nullptr;
}
bool IsInitialProcess(u64 pid) {
bool IsInitialProcess(os::ProcessId pid) {
return g_initial_process_id_limits.IsInitialProcess(pid);
}
bool IsValidProcessId(u64 pid) {
return pid != InvalidProcessId;
constexpr inline bool IsValidProcessId(os::ProcessId pid) {
return pid != os::InvalidProcessId;
}
ServiceInfo *GetServiceInfo(ServiceName service_name) {
@ -231,7 +231,7 @@ namespace sts::sm::impl {
return service_info != nullptr && IsValidProcessId(service_info->mitm_pid);
}
ncm::TitleId GetTitleIdForMitm(u64 pid) {
ncm::TitleId GetTitleIdForMitm(os::ProcessId pid) {
/* Anything that can request a mitm session must have a process info. */
const auto process_info = GetProcessInfo(pid);
STS_ASSERT(process_info != nullptr);
@ -352,37 +352,16 @@ namespace sts::sm::impl {
return service == ServiceName::Encode("fsp-srv");
}
Result GetMitmServiceHandleImpl(Handle *out, ServiceInfo *service_info, u64 pid, ncm::TitleId title_id) {
Result GetMitmServiceHandleImpl(Handle *out, ServiceInfo *service_info, os::ProcessId process_id, ncm::TitleId title_id) {
/* Send command to query if we should mitm. */
{
IpcCommand c;
ipcInitialize(&c);
struct {
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 = title_id;
R_TRY(ipcDispatch(service_info->mitm_query_h.Get()));
}
/* Parse response to see if we should mitm. */
bool should_mitm;
{
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
bool should_mitm;
} *resp = ((decltype(resp))r.Raw);
R_TRY(resp->result);
should_mitm = resp->should_mitm;
Service srv { .session = service_info->mitm_query_h.Get() };
const struct {
os::ProcessId process_id;
ncm::TitleId title_id;
} in = { process_id, title_id };
R_TRY(serviceDispatchInOut(&srv, 65000, in, should_mitm));
}
/* If we shouldn't mitm, give normal session. */
@ -399,13 +378,13 @@ namespace sts::sm::impl {
*out = hnd.Move();
}
service_info->mitm_waiting_ack_pid = pid;
service_info->mitm_waiting_ack_pid = process_id;
service_info->mitm_waiting_ack = true;
return ResultSuccess;
}
Result GetServiceHandleImpl(Handle *out, ServiceInfo *service_info, u64 pid) {
Result GetServiceHandleImpl(Handle *out, ServiceInfo *service_info, os::ProcessId pid) {
/* Clear handle output. */
*out = INVALID_HANDLE;
@ -424,7 +403,7 @@ namespace sts::sm::impl {
return svcConnectToPort(out, service_info->port_h.Get());
}
Result RegisterServiceImpl(Handle *out, u64 pid, ServiceName service, size_t max_sessions, bool is_light) {
Result RegisterServiceImpl(Handle *out, os::ProcessId pid, ServiceName service, size_t max_sessions, bool is_light) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -461,7 +440,7 @@ namespace sts::sm::impl {
}
/* Process management. */
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 RegisterProcess(os::ProcessId 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 (aci_sac_size > AccessControlSizeMax) {
return ResultSmTooLargeAccessControl;
@ -487,7 +466,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result UnregisterProcess(u64 pid) {
Result UnregisterProcess(os::ProcessId pid) {
/* Find the process. */
ProcessInfo *proc = GetProcessInfo(pid);
if (proc == nullptr) {
@ -518,7 +497,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result GetServiceHandle(Handle *out, u64 pid, ServiceName service) {
Result GetServiceHandle(Handle *out, os::ProcessId pid, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -527,7 +506,7 @@ namespace sts::sm::impl {
/* This would return true, and homebrew would *wait forever* trying to get a handle to a service */
/* that will never register. Thus, in the interest of not breaking every single piece of homebrew */
/* we will provide a little first class help. */
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_800 && service == ServiceName::Encode("apm:p")) {
if (hos::GetVersion() >= hos::Version_800 && service == ServiceName::Encode("apm:p")) {
return ResultSmNotAllowed;
}
@ -558,7 +537,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result RegisterService(Handle *out, u64 pid, ServiceName service, size_t max_sessions, bool is_light) {
Result RegisterService(Handle *out, os::ProcessId pid, ServiceName service, size_t max_sessions, bool is_light) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -580,13 +559,10 @@ namespace sts::sm::impl {
}
Result RegisterServiceForSelf(Handle *out, ServiceName service, size_t max_sessions) {
u64 self_pid;
R_TRY(svcGetProcessId(&self_pid, CUR_PROCESS_HANDLE));
return RegisterServiceImpl(out, self_pid, service, max_sessions, false);
return RegisterServiceImpl(out, os::GetCurrentProcessId(), service, max_sessions, false);
}
Result UnregisterService(u64 pid, ServiceName service) {
Result UnregisterService(os::ProcessId pid, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -634,7 +610,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service) {
Result InstallMitm(Handle *out, Handle *out_query, os::ProcessId pid, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -685,7 +661,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result UninstallMitm(u64 pid, ServiceName service) {
Result UninstallMitm(os::ProcessId pid, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -713,7 +689,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result DeclareFutureMitm(u64 pid, ServiceName service) {
Result DeclareFutureMitm(os::ProcessId pid, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -737,7 +713,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, u64 pid, ServiceName service) {
Result AcknowledgeMitmSession(os::ProcessId *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, os::ProcessId pid, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));

View file

@ -22,24 +22,24 @@
namespace sts::sm::impl {
/* Process management. */
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);
Result RegisterProcess(os::ProcessId pid, ncm::TitleId tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size);
Result UnregisterProcess(os::ProcessId pid);
/* Service management. */
Result HasService(bool *out, ServiceName service);
Result WaitService(ServiceName service);
Result GetServiceHandle(Handle *out, u64 pid, ServiceName service);
Result RegisterService(Handle *out, u64 pid, ServiceName service, size_t max_sessions, bool is_light);
Result GetServiceHandle(Handle *out, os::ProcessId pid, ServiceName service);
Result RegisterService(Handle *out, os::ProcessId pid, ServiceName service, size_t max_sessions, bool is_light);
Result RegisterServiceForSelf(Handle *out, ServiceName service, size_t max_sessions);
Result UnregisterService(u64 pid, ServiceName service);
Result UnregisterService(os::ProcessId pid, ServiceName service);
/* Mitm extensions. */
Result HasMitm(bool *out, ServiceName service);
Result WaitMitm(ServiceName service);
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service);
Result UninstallMitm(u64 pid, ServiceName service);
Result DeclareFutureMitm(u64 pid, ServiceName service);
Result AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, u64 pid, ServiceName service);
Result InstallMitm(Handle *out, Handle *out_query, os::ProcessId pid, ServiceName service);
Result UninstallMitm(os::ProcessId pid, ServiceName service);
Result DeclareFutureMitm(os::ProcessId pid, ServiceName service);
Result AcknowledgeMitmSession(os::ProcessId *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, os::ProcessId pid, ServiceName service);
/* Dmnt record extensions. */
Result GetServiceRecord(ServiceRecord *out, ServiceName service);

View file

@ -22,15 +22,15 @@
namespace sts::sm {
Result DmntService::AtmosphereGetRecord(Out<ServiceRecord> record, ServiceName service) {
Result DmntService::AtmosphereGetRecord(sf::Out<ServiceRecord> record, ServiceName service) {
return impl::GetServiceRecord(record.GetPointer(), service);
}
void DmntService::AtmosphereListRecords(OutBuffer<ServiceRecord> records, Out<u64> out_count, u64 offset) {
R_ASSERT(impl::ListServiceRecords(records.buffer, out_count.GetPointer(), offset, records.num_elements));
void DmntService::AtmosphereListRecords(const sf::OutArray<ServiceRecord> &records, sf::Out<u64> out_count, u64 offset) {
R_ASSERT(impl::ListServiceRecords(records.GetPointer(), out_count.GetPointer(), offset, records.GetSize()));
}
void DmntService::AtmosphereGetRecordSize(Out<u64> record_size) {
void DmntService::AtmosphereGetRecordSize(sf::Out<u64> record_size) {
record_size.SetValue(sizeof(ServiceRecord));
}

View file

@ -22,7 +22,7 @@
namespace sts::sm {
/* Service definition. */
class DmntService final : public IServiceObject {
class DmntService final : public sf::IServiceObject {
protected:
/* Command IDs. */
enum class CommandId {
@ -32,14 +32,14 @@ namespace sts::sm {
};
private:
/* Actual commands. */
virtual Result AtmosphereGetRecord(Out<ServiceRecord> record, ServiceName service);
virtual void AtmosphereListRecords(OutBuffer<ServiceRecord> records, Out<u64> out_count, u64 offset);
virtual void AtmosphereGetRecordSize(Out<u64> record_size);
virtual Result AtmosphereGetRecord(sf::Out<ServiceRecord> record, ServiceName service);
virtual void AtmosphereListRecords(const sf::OutArray<ServiceRecord> &records, sf::Out<u64> out_count, u64 offset);
virtual void AtmosphereGetRecordSize(sf::Out<u64> record_size);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(DmntService, AtmosphereGetRecord),
MAKE_SERVICE_COMMAND_META(DmntService, AtmosphereListRecords),
MAKE_SERVICE_COMMAND_META(DmntService, AtmosphereGetRecordSize),
MAKE_SERVICE_COMMAND_META(AtmosphereGetRecord),
MAKE_SERVICE_COMMAND_META(AtmosphereListRecords),
MAKE_SERVICE_COMMAND_META(AtmosphereGetRecordSize),
};
};

View file

@ -33,7 +33,7 @@ extern "C" {
u32 __nx_applet_type = AppletType_None;
#define INNER_HEAP_SIZE 0x20000
#define INNER_HEAP_SIZE 0x4000
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
@ -68,7 +68,7 @@ void __libnx_initheap(void) {
}
void __appInit(void) {
SetFirmwareVersionForLibnx();
sts::hos::SetVersionForLibnx();
/* We must do no service setup here, because we are sm. */
}
@ -79,29 +79,45 @@ void __appExit(void) {
using namespace sts;
namespace {
/* sm:m, sm:, sm:dmnt. */
constexpr size_t NumServers = 3;
sf::hipc::ServerManager<NumServers> g_server_manager;
}
int main(int argc, char **argv)
{
/* Create service waitable manager. */
static auto s_server_manager = WaitableManager(1);
/* NOTE: These handles are manually managed, but we don't save references to them to close on exit. */
/* This is fine, because if SM crashes we have much bigger issues. */
/* Create sm:, (and thus allow things to register to it). */
s_server_manager.AddWaitable(new ManagedPortServer<sm::UserService>("sm:", 0x40));
{
Handle sm_h;
R_ASSERT(svcManageNamedPort(&sm_h, "sm:", 0x40));
g_server_manager.RegisterServer<sm::UserService>(sm_h);
}
/* Create sm:m manually. */
Handle smm_h;
R_ASSERT(sm::impl::RegisterServiceForSelf(&smm_h, sm::ServiceName::Encode("sm:m"), 1));
s_server_manager.AddWaitable(new ExistingPortServer<sm::ManagerService>(smm_h, 1));
{
Handle smm_h;
R_ASSERT(sm::impl::RegisterServiceForSelf(&smm_h, sm::ServiceName::Encode("sm:m"), 1));
g_server_manager.RegisterServer<sm::ManagerService>(smm_h);
}
/*===== ATMOSPHERE EXTENSION =====*/
/* Create sm:dmnt manually. */
Handle smdmnt_h;
R_ASSERT(sm::impl::RegisterServiceForSelf(&smdmnt_h, sm::ServiceName::Encode("sm:dmnt"), 1));
s_server_manager.AddWaitable(new ExistingPortServer<sm::DmntService>(smm_h, 1));;
{
Handle smdmnt_h;
R_ASSERT(sm::impl::RegisterServiceForSelf(&smdmnt_h, sm::ServiceName::Encode("sm:dmnt"), 1));
g_server_manager.RegisterServer<sm::DmntService>(smdmnt_h);
}
/*================================*/
/* Loop forever, servicing our services. */
s_server_manager.Process();
g_server_manager.LoopProcess();
/* Cleanup. */
return 0;

View file

@ -22,25 +22,25 @@
namespace sts::sm {
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::RegisterProcess(os::ProcessId process_id, const sf::InBuffer &acid_sac, const sf::InBuffer &aci_sac) {
return impl::RegisterProcess(process_id, ncm::TitleId::Invalid, acid_sac.GetPointer(), acid_sac.GetSize(), aci_sac.GetPointer(), aci_sac.GetSize());
}
Result ManagerService::UnregisterProcess(u64 pid) {
return impl::UnregisterProcess(pid);
Result ManagerService::UnregisterProcess(os::ProcessId process_id) {
return impl::UnregisterProcess(process_id);
}
void ManagerService::AtmosphereEndInitDefers() {
R_ASSERT(impl::EndInitialDefers());
}
void ManagerService::AtmosphereHasMitm(Out<bool> out, ServiceName service) {
void ManagerService::AtmosphereHasMitm(sf::Out<bool> out, ServiceName service) {
R_ASSERT(impl::HasMitm(out.GetPointer(), service));
}
Result ManagerService::AtmosphereRegisterProcess(u64 pid, ncm::TitleId tid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac) {
Result ManagerService::AtmosphereRegisterProcess(os::ProcessId process_id, ncm::TitleId title_id, const sf::InBuffer &acid_sac, const sf::InBuffer &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);
return impl::RegisterProcess(process_id, title_id, acid_sac.GetPointer(), acid_sac.GetSize(), aci_sac.GetPointer(), aci_sac.GetSize());
}
}

View file

@ -23,7 +23,7 @@
namespace sts::sm {
/* Service definition. */
class ManagerService final : public IServiceObject {
class ManagerService final : public sf::IServiceObject {
protected:
/* Command IDs. */
enum class CommandId {
@ -36,19 +36,19 @@ namespace sts::sm {
};
private:
/* Actual commands. */
virtual Result RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac);
virtual Result UnregisterProcess(u64 pid);
virtual Result RegisterProcess(os::ProcessId process_id, const sf::InBuffer &acid_sac, const sf::InBuffer &aci_sac);
virtual Result UnregisterProcess(os::ProcessId process_id);
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);
virtual void AtmosphereHasMitm(sf::Out<bool> out, ServiceName service);
virtual Result AtmosphereRegisterProcess(os::ProcessId process_id, ncm::TitleId title_id, const sf::InBuffer &acid_sac, const sf::InBuffer &aci_sac);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(ManagerService, RegisterProcess),
MAKE_SERVICE_COMMAND_META(ManagerService, UnregisterProcess),
MAKE_SERVICE_COMMAND_META(RegisterProcess),
MAKE_SERVICE_COMMAND_META(UnregisterProcess),
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereEndInitDefers),
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereHasMitm),
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereRegisterProcess),
MAKE_SERVICE_COMMAND_META(AtmosphereEndInitDefers),
MAKE_SERVICE_COMMAND_META(AtmosphereHasMitm),
MAKE_SERVICE_COMMAND_META(AtmosphereRegisterProcess),
};
};

View file

@ -22,8 +22,8 @@
namespace sts::sm {
Result UserService::Initialize(PidDescriptor pid) {
this->pid = pid.pid;
Result UserService::Initialize(const sf::ClientProcessId &client_process_id) {
this->process_id = client_process_id.GetValue();
this->has_initialized = true;
return ResultSuccess;
}
@ -35,37 +35,37 @@ namespace sts::sm {
return ResultSuccess;
}
Result UserService::GetService(Out<MovedHandle> out_h, ServiceName service) {
Result UserService::GetService(sf::OutMoveHandle out_h, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::GetServiceHandle(out_h.GetHandlePointer(), this->pid, service);
return impl::GetServiceHandle(out_h.GetHandlePointer(), this->process_id, service);
}
Result UserService::RegisterService(Out<MovedHandle> out_h, ServiceName service, u32 max_sessions, bool is_light) {
Result UserService::RegisterService(sf::OutMoveHandle out_h, ServiceName service, u32 max_sessions, bool is_light) {
R_TRY(this->EnsureInitialized());
return impl::RegisterService(out_h.GetHandlePointer(), this->pid, service, max_sessions, is_light);
return impl::RegisterService(out_h.GetHandlePointer(), this->process_id, service, max_sessions, is_light);
}
Result UserService::UnregisterService(ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::UnregisterService(this->pid, service);
return impl::UnregisterService(this->process_id, service);
}
Result UserService::AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, ServiceName service) {
Result UserService::AtmosphereInstallMitm(sf::OutMoveHandle srv_h, sf::OutMoveHandle qry_h, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::InstallMitm(srv_h.GetHandlePointer(), qry_h.GetHandlePointer(), this->pid, service);
return impl::InstallMitm(srv_h.GetHandlePointer(), qry_h.GetHandlePointer(), this->process_id, service);
}
Result UserService::AtmosphereUninstallMitm(ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::UninstallMitm(this->pid, service);
return impl::UninstallMitm(this->process_id, service);
}
Result UserService::AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<ncm::TitleId> client_tid, Out<MovedHandle> fwd_h, ServiceName service) {
Result UserService::AtmosphereAcknowledgeMitmSession(sf::Out<os::ProcessId> client_pid, sf::Out<ncm::TitleId> client_tid, sf::OutMoveHandle fwd_h, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), client_tid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), client_tid.GetPointer(), fwd_h.GetHandlePointer(), this->process_id, service);
}
Result UserService::AtmosphereHasMitm(Out<bool> out, ServiceName service) {
Result UserService::AtmosphereHasMitm(sf::Out<bool> out, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::HasMitm(out.GetPointer(), service);
}
@ -77,11 +77,11 @@ namespace sts::sm {
Result UserService::AtmosphereDeclareFutureMitm(ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::DeclareFutureMitm(this->pid, service);
return impl::DeclareFutureMitm(this->process_id, service);
}
Result UserService::AtmosphereHasService(Out<bool> out, ServiceName service) {
Result UserService::AtmosphereHasService(sf::Out<bool> out, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::HasService(out.GetPointer(), service);
}

View file

@ -23,7 +23,7 @@
namespace sts::sm {
/* Service definition. */
class UserService final : public IServiceObject {
class UserService final : public sf::IServiceObject {
protected:
/* Command IDs. */
enum class CommandId {
@ -44,43 +44,43 @@ namespace sts::sm {
AtmosphereWaitService = 65101,
};
private:
u64 pid = InvalidProcessId;
os::ProcessId process_id = os::InvalidProcessId;
bool has_initialized = false;
private:
Result EnsureInitialized();
public:
/* Official commands. */
virtual Result Initialize(PidDescriptor pid);
virtual Result GetService(Out<MovedHandle> out_h, ServiceName service);
virtual Result RegisterService(Out<MovedHandle> out_h, ServiceName service, u32 max_sessions, bool is_light);
virtual Result Initialize(const sf::ClientProcessId &client_process_id);
virtual Result GetService(sf::OutMoveHandle out_h, ServiceName service);
virtual Result RegisterService(sf::OutMoveHandle out_h, ServiceName service, u32 max_sessions, bool is_light);
virtual Result UnregisterService(ServiceName service);
/* Atmosphere commands. */
virtual Result AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, ServiceName service);
virtual Result AtmosphereInstallMitm(sf::OutMoveHandle srv_h, sf::OutMoveHandle qry_h, ServiceName service);
virtual Result AtmosphereUninstallMitm(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 AtmosphereAcknowledgeMitmSession(sf::Out<os::ProcessId> client_pid, sf::Out<ncm::TitleId> client_tid, sf::OutMoveHandle fwd_h, ServiceName service);
virtual Result AtmosphereHasMitm(sf::Out<bool> out, ServiceName service);
virtual Result AtmosphereWaitMitm(ServiceName service);
virtual Result AtmosphereDeclareFutureMitm(ServiceName service);
virtual Result AtmosphereHasService(Out<bool> out, ServiceName service);
virtual Result AtmosphereHasService(sf::Out<bool> out, ServiceName service);
virtual Result AtmosphereWaitService(ServiceName service);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(UserService, Initialize),
MAKE_SERVICE_COMMAND_META(UserService, GetService),
MAKE_SERVICE_COMMAND_META(UserService, RegisterService),
MAKE_SERVICE_COMMAND_META(UserService, UnregisterService),
MAKE_SERVICE_COMMAND_META(Initialize),
MAKE_SERVICE_COMMAND_META(GetService),
MAKE_SERVICE_COMMAND_META(RegisterService),
MAKE_SERVICE_COMMAND_META(UnregisterService),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereInstallMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereUninstallMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAcknowledgeMitmSession),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereWaitMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereDeclareFutureMitm),
MAKE_SERVICE_COMMAND_META(AtmosphereInstallMitm),
MAKE_SERVICE_COMMAND_META(AtmosphereUninstallMitm),
MAKE_SERVICE_COMMAND_META(AtmosphereAcknowledgeMitmSession),
MAKE_SERVICE_COMMAND_META(AtmosphereHasMitm),
MAKE_SERVICE_COMMAND_META(AtmosphereWaitMitm),
MAKE_SERVICE_COMMAND_META(AtmosphereDeclareFutureMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasService),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereWaitService),
MAKE_SERVICE_COMMAND_META(AtmosphereHasService),
MAKE_SERVICE_COMMAND_META(AtmosphereWaitService),
};
};