mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-08-07 16:09:28 +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/ncm.hpp"
|
||||||
#include "stratosphere/pm.hpp"
|
#include "stratosphere/pm.hpp"
|
||||||
#include "stratosphere/rnd.hpp"
|
#include "stratosphere/rnd.hpp"
|
||||||
|
#include "stratosphere/sm.hpp"
|
||||||
#include "stratosphere/util.hpp"
|
#include "stratosphere/util.hpp"
|
@ -27,5 +27,6 @@ namespace sts::sm {
|
|||||||
|
|
||||||
/* Atmosphere extensions. */
|
/* Atmosphere extensions. */
|
||||||
Result HasService(bool *out, ServiceName name);
|
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 AssociateProcessIdAndTitleId(u64 process_id, u64 title_id);
|
||||||
Result AcknowledgeSession(Service *out_service, u64 *out_pid, ServiceName name);
|
Result AcknowledgeSession(Service *out_service, u64 *out_pid, ServiceName name);
|
||||||
Result HasMitm(bool *out, ServiceName name);
|
Result HasMitm(bool *out, ServiceName name);
|
||||||
|
Result WaitMitm(ServiceName name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include "../defines.hpp"
|
||||||
|
#include "../results.hpp"
|
||||||
|
|
||||||
namespace sts::sm {
|
namespace sts::sm {
|
||||||
|
|
||||||
@ -69,4 +71,71 @@ namespace sts::sm {
|
|||||||
/* For process validation. */
|
/* For process validation. */
|
||||||
static constexpr u64 InvalidProcessId = static_cast<u64>(-1ull);
|
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;
|
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) {
|
Result smAtmosphereHasMitm(bool *out, const char *name) {
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
@ -99,6 +133,40 @@ Result smAtmosphereHasMitm(bool *out, const char *name) {
|
|||||||
return rc;
|
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) {
|
Result smAtmosphereMitmInitialize(void) {
|
||||||
atomicIncrement64(&g_mitmRefCnt);
|
atomicIncrement64(&g_mitmRefCnt);
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Result smAtmosphereHasService(bool *out, const char *name);
|
Result smAtmosphereHasService(bool *out, const char *name);
|
||||||
|
Result smAtmosphereWaitService(const char *name);
|
||||||
Result smAtmosphereHasMitm(bool *out, const char *name);
|
Result smAtmosphereHasMitm(bool *out, const char *name);
|
||||||
|
Result smAtmosphereWaitMitm(const char *name);
|
||||||
|
|
||||||
Result smAtmosphereMitmInitialize(void);
|
Result smAtmosphereMitmInitialize(void);
|
||||||
void smAtmosphereMitmExit(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