mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
new-ipc: implement deferral. sm now works.
This commit is contained in:
parent
f4dcd1db9b
commit
c8ed190e5c
13 changed files with 193 additions and 157 deletions
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue