mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-08-07 07:59:27 +02:00
libstrat/sm: add ScopedServiceHolder, Wait(Mitm/Service)
This commit is contained in:
parent
d7d7cba3d3
commit
45700a12e8
@ -48,4 +48,5 @@
|
||||
#include "stratosphere/ncm.hpp"
|
||||
#include "stratosphere/pm.hpp"
|
||||
#include "stratosphere/rnd.hpp"
|
||||
#include "stratosphere/sm.hpp"
|
||||
#include "stratosphere/util.hpp"
|
@ -27,5 +27,6 @@ namespace sts::sm {
|
||||
|
||||
/* Atmosphere extensions. */
|
||||
Result HasService(bool *out, ServiceName name);
|
||||
Result WaitService(ServiceName name);
|
||||
|
||||
}
|
||||
|
@ -26,5 +26,6 @@ namespace sts::sm::mitm {
|
||||
Result AssociateProcessIdAndTitleId(u64 process_id, u64 title_id);
|
||||
Result AcknowledgeSession(Service *out_service, u64 *out_pid, ServiceName name);
|
||||
Result HasMitm(bool *out, ServiceName name);
|
||||
Result WaitMitm(ServiceName name);
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
#pragma once
|
||||
#include <cstring>
|
||||
#include <switch.h>
|
||||
#include "../defines.hpp"
|
||||
#include "../results.hpp"
|
||||
|
||||
namespace sts::sm {
|
||||
|
||||
@ -69,4 +71,71 @@ namespace sts::sm {
|
||||
/* For process validation. */
|
||||
static constexpr u64 InvalidProcessId = static_cast<u64>(-1ull);
|
||||
|
||||
/* Utility, for scoped access to libnx services. */
|
||||
template<Result Initializer(), void Finalizer()>
|
||||
class ScopedServiceHolder {
|
||||
NON_COPYABLE(ScopedServiceHolder);
|
||||
private:
|
||||
Result result;
|
||||
bool has_initialized;
|
||||
public:
|
||||
ScopedServiceHolder(bool initialize = true) : result(ResultSuccess), has_initialized(false) {
|
||||
if (initialize) {
|
||||
this->Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
~ScopedServiceHolder() {
|
||||
if (this->has_initialized) {
|
||||
this->Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
ScopedServiceHolder(ScopedServiceHolder&& rhs) {
|
||||
this->result = rhs.result;
|
||||
this->has_initialized = rhs.has_initialized;
|
||||
rhs.result = ResultSuccess;
|
||||
rhs.has_initialized = false;
|
||||
}
|
||||
|
||||
ScopedServiceHolder& operator=(ScopedServiceHolder&& rhs) {
|
||||
rhs.Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Swap(ScopedServiceHolder& rhs) {
|
||||
std::swap(this->result, rhs.result);
|
||||
std::swap(this->has_initialized, rhs.has_initialized);
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return this->has_initialized;
|
||||
}
|
||||
|
||||
Result Initialize() {
|
||||
if (this->has_initialized) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
DoWithSmSession([&]() {
|
||||
this->result = Initializer();
|
||||
});
|
||||
|
||||
this->has_initialized = R_SUCCEEDED(this->result);
|
||||
return this->result;
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
if (!this->has_initialized) {
|
||||
std::abort();
|
||||
}
|
||||
Finalizer();
|
||||
this->has_initialized = false;
|
||||
}
|
||||
|
||||
Result GetResult() const {
|
||||
return this->result;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -60,6 +60,40 @@ Result smAtmosphereHasService(bool *out, const char *name) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smAtmosphereWaitService(const char *name) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
Service *srv = smGetServiceSession();
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 service_name;
|
||||
} *raw;
|
||||
|
||||
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 65101;
|
||||
raw->service_name = smEncodeName(name);
|
||||
|
||||
Result rc = serviceIpcDispatch(srv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smAtmosphereHasMitm(bool *out, const char *name) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
@ -99,6 +133,40 @@ Result smAtmosphereHasMitm(bool *out, const char *name) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smAtmosphereWaitMitm(const char *name) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
Service *srv = smGetServiceSession();
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 service_name;
|
||||
} *raw;
|
||||
|
||||
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 65005;
|
||||
raw->service_name = smEncodeName(name);
|
||||
|
||||
Result rc = serviceIpcDispatch(srv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smAtmosphereMitmInitialize(void) {
|
||||
atomicIncrement64(&g_mitmRefCnt);
|
||||
|
||||
|
@ -12,7 +12,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
Result smAtmosphereHasService(bool *out, const char *name);
|
||||
Result smAtmosphereWaitService(const char *name);
|
||||
Result smAtmosphereHasMitm(bool *out, const char *name);
|
||||
Result smAtmosphereWaitMitm(const char *name);
|
||||
|
||||
Result smAtmosphereMitmInitialize(void);
|
||||
void smAtmosphereMitmExit(void);
|
||||
|
@ -49,4 +49,10 @@ namespace sts::sm {
|
||||
});
|
||||
}
|
||||
|
||||
Result WaitService(ServiceName name) {
|
||||
return impl::DoWithUserSession([&]() {
|
||||
return smAtmosphereWaitService(name.name);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,4 +54,10 @@ namespace sts::sm::mitm {
|
||||
});
|
||||
}
|
||||
|
||||
Result WaitMitm(ServiceName name) {
|
||||
return impl::DoWithUserSession([&]() {
|
||||
return smAtmosphereWaitMitm(name.name);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user