mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-06-21 19:12:42 +02:00
libstrat: integrate sm API, add HasService/HasMitm.
This commit is contained in:
parent
bbb689cecf
commit
cf5c6cdad9
2
Makefile
2
Makefile
@ -16,7 +16,7 @@ include $(DEVKITPRO)/libnx/switch_rules
|
|||||||
# INCLUDES is a list of directories containing header files
|
# INCLUDES is a list of directories containing header files
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := $(notdir $(CURDIR))
|
TARGET := $(notdir $(CURDIR))
|
||||||
SOURCES := source source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util
|
SOURCES := source source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include
|
INCLUDES := include
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mitm/sm_mitm.h"
|
#include "sm.hpp"
|
||||||
|
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
#include "mitm_query_service.hpp"
|
#include "mitm_query_service.hpp"
|
||||||
#include "sm_mitm.h"
|
|
||||||
#include "mitm_session.hpp"
|
#include "mitm_session.hpp"
|
||||||
#include "../utilities.hpp"
|
#include "../utilities.hpp"
|
||||||
|
|
||||||
@ -30,29 +29,19 @@ class MitmServer : public IWaitable {
|
|||||||
private:
|
private:
|
||||||
Handle port_handle;
|
Handle port_handle;
|
||||||
unsigned int max_sessions;
|
unsigned int max_sessions;
|
||||||
char mitm_name[9];
|
sts::sm::ServiceName mitm_name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MitmServer(const char *service_name, unsigned int max_s) : port_handle(0), max_sessions(max_s) {
|
MitmServer(const char *service_name, unsigned int max_s) : port_handle(0), max_sessions(max_s), mitm_name(sts::sm::ServiceName::Encode(service_name)) {
|
||||||
Handle query_h = 0;
|
Handle query_h = INVALID_HANDLE;
|
||||||
|
R_ASSERT(sts::sm::mitm::InstallMitm(&this->port_handle, &query_h, this->mitm_name));
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
|
||||||
DoWithSmMitmSession([&]() {
|
|
||||||
strncpy(mitm_name, service_name, 8);
|
|
||||||
mitm_name[8] = '\x00';
|
|
||||||
R_ASSERT(smMitMInstall(&this->port_handle, &query_h, mitm_name));
|
|
||||||
});
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
RegisterMitmServerQueryHandle(query_h, std::move(ServiceObjectHolder(std::move(std::make_shared<MitmQueryService<T>>()))));
|
RegisterMitmServerQueryHandle(query_h, std::move(ServiceObjectHolder(std::move(std::make_shared<MitmQueryService<T>>()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~MitmServer() override {
|
virtual ~MitmServer() override {
|
||||||
if (this->port_handle) {
|
if (this->port_handle) {
|
||||||
DoWithSmMitmSession([&]() {
|
R_ASSERT(sts::sm::mitm::UninstallMitm(this->mitm_name));
|
||||||
R_ASSERT(smMitMUninstall(this->mitm_name));
|
|
||||||
});
|
|
||||||
svcCloseHandle(port_handle);
|
svcCloseHandle(port_handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,10 +68,7 @@ class MitmServer : public IWaitable {
|
|||||||
});
|
});
|
||||||
|
|
||||||
u64 client_pid;
|
u64 client_pid;
|
||||||
|
R_ASSERT(sts::sm::mitm::AcknowledgeSession(forward_service.get(), &client_pid, this->mitm_name));
|
||||||
DoWithSmMitmSession([&]() {
|
|
||||||
R_ASSERT(smMitMAcknowledgeSession(forward_service.get(), &client_pid, mitm_name));
|
|
||||||
});
|
|
||||||
|
|
||||||
this->GetSessionManager()->AddWaitable(new MitmSession(session_h, client_pid, forward_service, MakeShared(forward_service, client_pid)));
|
this->GetSessionManager()->AddWaitable(new MitmSession(session_h, client_pid, forward_service, MakeShared(forward_service, client_pid)));
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file sm_mitm.h
|
|
||||||
* @brief Service manager (sm) IPC wrapper for Atmosphere extensions.
|
|
||||||
* @author SciresM
|
|
||||||
* @copyright libnx Authors
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <switch.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Result smMitMInitialize(void);
|
|
||||||
void smMitMExit(void);
|
|
||||||
Result smMitMGetService(Service* service_out, const char *name);
|
|
||||||
Result smMitMInstall(Handle *handle_out, Handle *query_out, const char *name);
|
|
||||||
Result smMitMUninstall(const char *name);
|
|
||||||
Result smMitMAcknowledgeSession(Service *srv_out, u64 *pid_out, const char *name);
|
|
||||||
|
|
||||||
Result smMitMIsRegistered(const char *name);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -18,5 +18,4 @@
|
|||||||
|
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
|
||||||
#include "services/smm_ams.h"
|
|
||||||
#include "services/dmntcht.h"
|
#include "services/dmntcht.h"
|
@ -17,16 +17,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#include "sm/sm_types.hpp"
|
||||||
extern "C" {
|
#include "sm/sm_api.hpp"
|
||||||
#endif
|
#include "sm/sm_mitm_api.hpp"
|
||||||
|
|
||||||
Result smManagerAmsInitialize(void);
|
|
||||||
void smManagerAmsExit(void);
|
|
||||||
|
|
||||||
Result smManagerAmsEndInitialDefers(void);
|
|
||||||
Result smManagerAmsHasMitm(bool *out, const char* name);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
31
include/stratosphere/sm/sm_api.hpp
Normal file
31
include/stratosphere/sm/sm_api.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sm_types.hpp"
|
||||||
|
|
||||||
|
namespace sts::sm {
|
||||||
|
|
||||||
|
/* Ordinary SM API. */
|
||||||
|
Result GetService(Service *out, ServiceName name);
|
||||||
|
Result RegisterService(Handle *out, ServiceName name, size_t max_sessions, bool is_light);
|
||||||
|
Result UnregisterService(ServiceName name);
|
||||||
|
|
||||||
|
/* Atmosphere extensions. */
|
||||||
|
Result HasService(bool *out, ServiceName name);
|
||||||
|
|
||||||
|
}
|
31
include/stratosphere/sm/sm_manager_api.hpp
Normal file
31
include/stratosphere/sm/sm_manager_api.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sm_types.hpp"
|
||||||
|
|
||||||
|
namespace sts::sm::manager {
|
||||||
|
|
||||||
|
/* Manager API. */
|
||||||
|
Result RegisterProcess(u64 process_id, const void *acid, size_t acid_size, const void *aci, size_t aci_size);
|
||||||
|
Result UnregisterProcess(u64 process_id);
|
||||||
|
|
||||||
|
/* Atmosphere extensions. */
|
||||||
|
Result EndInitialDefers();
|
||||||
|
Result HasMitm(bool *out, ServiceName name);
|
||||||
|
|
||||||
|
}
|
30
include/stratosphere/sm/sm_mitm_api.hpp
Normal file
30
include/stratosphere/sm/sm_mitm_api.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sm_types.hpp"
|
||||||
|
|
||||||
|
namespace sts::sm::mitm {
|
||||||
|
|
||||||
|
/* Mitm API. */
|
||||||
|
Result InstallMitm(Handle *out_port, Handle *out_query, ServiceName name);
|
||||||
|
Result UninstallMitm(ServiceName name);
|
||||||
|
Result AssociateProcessIdAndTitleId(u64 process_id, u64 title_id);
|
||||||
|
Result AcknowledgeSession(Service *out_service, u64 *out_pid, ServiceName name);
|
||||||
|
Result HasMitm(bool *out, ServiceName name);
|
||||||
|
|
||||||
|
}
|
71
include/stratosphere/sm/sm_types.hpp
Normal file
71
include/stratosphere/sm/sm_types.hpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace sts::sm {
|
||||||
|
|
||||||
|
struct ServiceName {
|
||||||
|
static constexpr size_t MaxLength = 8;
|
||||||
|
|
||||||
|
char name[MaxLength];
|
||||||
|
|
||||||
|
static constexpr ServiceName Encode(const char *name, size_t name_size) {
|
||||||
|
ServiceName out{};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MaxLength; i++) {
|
||||||
|
if (i < name_size) {
|
||||||
|
out.name[i] = name[i];
|
||||||
|
} else {
|
||||||
|
out.name[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr ServiceName Encode(const char *name) {
|
||||||
|
return Encode(name, std::strlen(name));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static constexpr ServiceName InvalidServiceName = ServiceName::Encode("");
|
||||||
|
static_assert(alignof(ServiceName) == 1, "ServiceName definition!");
|
||||||
|
|
||||||
|
inline bool operator==(const ServiceName &lhs, const ServiceName &rhs) {
|
||||||
|
return std::memcmp(&lhs, &rhs, sizeof(ServiceName)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const ServiceName &lhs, const ServiceName &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For Debug Monitor extensions. */
|
||||||
|
struct ServiceRecord {
|
||||||
|
ServiceName service;
|
||||||
|
u64 owner_pid;
|
||||||
|
u64 max_sessions;
|
||||||
|
u64 mitm_pid;
|
||||||
|
u64 mitm_waiting_ack_pid;
|
||||||
|
bool is_light;
|
||||||
|
bool mitm_waiting_ack;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ServiceRecord) == 0x30, "ServiceRecord definition!");
|
||||||
|
|
||||||
|
/* For process validation. */
|
||||||
|
static constexpr u64 InvalidProcessId = static_cast<u64>(-1ull);
|
||||||
|
|
||||||
|
}
|
@ -19,7 +19,6 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "hossynch.hpp"
|
#include "hossynch.hpp"
|
||||||
#include "mitm/sm_mitm.h"
|
|
||||||
|
|
||||||
static inline uintptr_t GetIoMapping(const u64 io_addr, const u64 io_size) {
|
static inline uintptr_t GetIoMapping(const u64 io_addr, const u64 io_size) {
|
||||||
u64 vaddr;
|
u64 vaddr;
|
||||||
@ -117,7 +116,6 @@ static inline bool ShouldBlankProdInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HosRecursiveMutex &GetSmSessionMutex();
|
HosRecursiveMutex &GetSmSessionMutex();
|
||||||
HosRecursiveMutex &GetSmMitmSessionMutex();
|
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
static void DoWithSmSession(F f) {
|
static void DoWithSmSession(F f) {
|
||||||
@ -128,13 +126,3 @@ static void DoWithSmSession(F f) {
|
|||||||
smExit();
|
smExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
|
||||||
static void DoWithSmMitmSession(F f) {
|
|
||||||
std::scoped_lock<HosRecursiveMutex &> lk(GetSmMitmSessionMutex());
|
|
||||||
{
|
|
||||||
R_ASSERT(smMitMInitialize());
|
|
||||||
f();
|
|
||||||
smMitMExit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
309
source/sm/sm_ams.c
Normal file
309
source/sm/sm_ams.c
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <switch.h>
|
||||||
|
#include <switch/arm/atomics.h>
|
||||||
|
#include "sm_ams.h"
|
||||||
|
|
||||||
|
static Service g_smMitmSrv;
|
||||||
|
static u64 g_mitmRefCnt;
|
||||||
|
|
||||||
|
Result smAtmosphereHasService(bool *out, 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 = 65100;
|
||||||
|
raw->service_name = smEncodeName(name);
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(srv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
u8 has_service;
|
||||||
|
} *resp;
|
||||||
|
|
||||||
|
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||||
|
resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
*out = resp->has_service != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result smAtmosphereHasMitm(bool *out, 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 = 65004;
|
||||||
|
raw->service_name = smEncodeName(name);
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(srv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
u8 has_mitm;
|
||||||
|
} *resp;
|
||||||
|
|
||||||
|
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||||
|
resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
*out = resp->has_mitm != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result smAtmosphereMitmInitialize(void) {
|
||||||
|
atomicIncrement64(&g_mitmRefCnt);
|
||||||
|
|
||||||
|
if (serviceIsActive(&g_smMitmSrv))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Handle sm_handle;
|
||||||
|
Result rc = svcConnectToNamedPort(&sm_handle, "sm:");
|
||||||
|
while (R_VALUE(rc) == KERNELRESULT(NotFound)) {
|
||||||
|
svcSleepThread(50000000ul);
|
||||||
|
rc = svcConnectToNamedPort(&sm_handle, "sm:");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
serviceCreate(&g_smMitmSrv, sm_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
ipcSendPid(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u64 zero;
|
||||||
|
u64 reserved[2];
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(&g_smMitmSrv, &c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 0;
|
||||||
|
raw->zero = 0;
|
||||||
|
|
||||||
|
rc = serviceIpcDispatch(&g_smMitmSrv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp;
|
||||||
|
serviceIpcParse(&g_smMitmSrv, &r, sizeof(*resp));
|
||||||
|
|
||||||
|
resp = r.Raw;
|
||||||
|
rc = resp->result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
smAtmosphereMitmExit();
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void smAtmosphereMitmExit(void) {
|
||||||
|
if (atomicDecrement64(&g_mitmRefCnt) == 0) {
|
||||||
|
serviceClose(&g_smMitmSrv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, const char *name) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
Service *srv = &g_smMitmSrv;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u64 service_name;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 65000;
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
*handle_out = r.Handles[0];
|
||||||
|
*query_out = r.Handles[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result smAtmosphereMitmUninstall(const char *name) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
Service *srv = &g_smMitmSrv;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u64 service_name;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 65001;
|
||||||
|
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 smAtmosphereMitmAssociateProcessIdAndTitleId(u64 pid, u64 tid) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
Service *srv = &g_smMitmSrv;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u64 pid;
|
||||||
|
u64 tid;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 65002;
|
||||||
|
raw->pid = pid;
|
||||||
|
raw->tid = tid;
|
||||||
|
|
||||||
|
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 smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, const char *name) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
Service *srv = &g_smMitmSrv;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u64 service_name;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 65003;
|
||||||
|
raw->service_name = smEncodeName(name);
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(srv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
u64 pid;
|
||||||
|
} *resp;
|
||||||
|
|
||||||
|
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||||
|
resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
*pid_out = resp->pid;
|
||||||
|
serviceCreate(srv_out, r.Handles[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
27
source/sm/sm_ams.h
Normal file
27
source/sm/sm_ams.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* @file sm_ams.h
|
||||||
|
* @brief Service manager (sm) IPC wrapper for Atmosphere extensions.
|
||||||
|
* @author SciresM
|
||||||
|
* @copyright libnx Authors
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <switch.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Result smAtmosphereHasService(bool *out, const char *name);
|
||||||
|
Result smAtmosphereHasMitm(bool *out, const char *name);
|
||||||
|
|
||||||
|
Result smAtmosphereMitmInitialize(void);
|
||||||
|
void smAtmosphereMitmExit(void);
|
||||||
|
|
||||||
|
Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, const char *name);
|
||||||
|
Result smAtmosphereMitmUninstall(const char *name);
|
||||||
|
Result smAtmosphereMitmAssociateProcessIdAndTitleId(u64 pid, u64 tid);
|
||||||
|
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, const char *name);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
52
source/sm/sm_api.cpp
Normal file
52
source/sm/sm_api.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include <stratosphere/sm.hpp>
|
||||||
|
|
||||||
|
#include "sm_ams.h"
|
||||||
|
#include "sm_utils.hpp"
|
||||||
|
|
||||||
|
namespace sts::sm {
|
||||||
|
|
||||||
|
/* Ordinary SM API. */
|
||||||
|
Result GetService(Service *out, ServiceName name) {
|
||||||
|
return impl::DoWithUserSession([&]() {
|
||||||
|
return smGetService(out, name.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Result RegisterService(Handle *out, ServiceName name, size_t max_sessions, bool is_light) {
|
||||||
|
return impl::DoWithUserSession([&]() {
|
||||||
|
return smRegisterService(out, name.name, is_light, static_cast<int>(max_sessions));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Result UnregisterService(ServiceName name) {
|
||||||
|
return impl::DoWithUserSession([&]() {
|
||||||
|
return smUnregisterService(name.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Atmosphere extensions. */
|
||||||
|
Result HasService(bool *out, ServiceName name) {
|
||||||
|
return impl::DoWithUserSession([&]() {
|
||||||
|
return smAtmosphereHasService(out, name.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
44
source/sm/sm_manager_api.cpp
Normal file
44
source/sm/sm_manager_api.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include <stratosphere/sm.hpp>
|
||||||
|
#include <stratosphere/sm/sm_manager_api.hpp>
|
||||||
|
|
||||||
|
#include "smm_ams.h"
|
||||||
|
|
||||||
|
namespace sts::sm::manager {
|
||||||
|
|
||||||
|
/* Manager API. */
|
||||||
|
Result RegisterProcess(u64 process_id, const void *acid, size_t acid_size, const void *aci, size_t aci_size) {
|
||||||
|
return smManagerRegisterProcess(process_id, acid, acid_size, aci, aci_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result UnregisterProcess(u64 process_id) {
|
||||||
|
return smManagerUnregisterProcess(process_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Atmosphere extensions. */
|
||||||
|
Result EndInitialDefers() {
|
||||||
|
return smManagerAtmosphereEndInitialDefers();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result HasMitm(bool *out, ServiceName name) {
|
||||||
|
return smManagerAtmosphereHasMitm(out, name.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
source/sm/sm_mitm_api.cpp
Normal file
57
source/sm/sm_mitm_api.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include <stratosphere/sm.hpp>
|
||||||
|
|
||||||
|
#include "sm_ams.h"
|
||||||
|
#include "sm_utils.hpp"
|
||||||
|
|
||||||
|
namespace sts::sm::mitm {
|
||||||
|
|
||||||
|
/* Mitm API. */
|
||||||
|
Result InstallMitm(Handle *out_port, Handle *out_query, ServiceName name) {
|
||||||
|
return impl::DoWithMitmSession([&]() {
|
||||||
|
return smAtmosphereMitmInstall(out_port, out_query, name.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Result UninstallMitm(ServiceName name) {
|
||||||
|
return impl::DoWithMitmSession([&]() {
|
||||||
|
return smAtmosphereMitmUninstall(name.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Result AssociateProcessIdAndTitleId(u64 process_id, u64 title_id) {
|
||||||
|
return impl::DoWithMitmSession([&]() {
|
||||||
|
return smAtmosphereMitmAssociateProcessIdAndTitleId(process_id, title_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Result AcknowledgeSession(Service *out_service, u64 *out_pid, ServiceName name) {
|
||||||
|
return impl::DoWithMitmSession([&]() {
|
||||||
|
return smAtmosphereMitmAcknowledgeSession(out_service, out_pid, name.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Result HasMitm(bool *out, ServiceName name) {
|
||||||
|
return impl::DoWithUserSession([&]() {
|
||||||
|
return smAtmosphereHasMitm(out, name.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
source/sm/sm_utils.cpp
Normal file
38
source/sm/sm_utils.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sm_utils.hpp"
|
||||||
|
|
||||||
|
namespace sts::sm::impl {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/* Globals. */
|
||||||
|
HosRecursiveMutex g_user_session_mutex;
|
||||||
|
HosRecursiveMutex g_mitm_session_mutex;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utilities. */
|
||||||
|
HosRecursiveMutex &GetUserSessionMutex() {
|
||||||
|
return g_user_session_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
HosRecursiveMutex &GetMitmSessionMutex() {
|
||||||
|
return g_mitm_session_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
53
source/sm/sm_utils.hpp
Normal file
53
source/sm/sm_utils.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include <stratosphere/sm.hpp>
|
||||||
|
|
||||||
|
#include "sm_ams.h"
|
||||||
|
|
||||||
|
namespace sts::sm::impl {
|
||||||
|
|
||||||
|
/* Utilities. */
|
||||||
|
HosRecursiveMutex &GetUserSessionMutex();
|
||||||
|
HosRecursiveMutex &GetMitmSessionMutex();
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
Result DoWithUserSession(F f) {
|
||||||
|
std::scoped_lock<HosRecursiveMutex &> lk(GetUserSessionMutex());
|
||||||
|
{
|
||||||
|
R_ASSERT(smInitialize());
|
||||||
|
ON_SCOPE_EXIT { smExit(); };
|
||||||
|
|
||||||
|
return f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
Result DoWithMitmSession(F f) {
|
||||||
|
std::scoped_lock<HosRecursiveMutex &> lk(GetMitmSessionMutex());
|
||||||
|
{
|
||||||
|
R_ASSERT(smAtmosphereMitmInitialize());
|
||||||
|
ON_SCOPE_EXIT { smAtmosphereMitmExit(); };
|
||||||
|
|
||||||
|
return f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,41 +15,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <switch/arm/atomics.h>
|
#include "smm_ams.h"
|
||||||
#include <stratosphere/services/smm_ams.h>
|
|
||||||
|
|
||||||
static Service g_smManagerAmsSrv;
|
Result smManagerAtmosphereEndInitialDefers(void) {
|
||||||
static u64 g_smManagerAmsRefcnt;
|
|
||||||
|
|
||||||
Result smManagerAmsInitialize(void) {
|
|
||||||
atomicIncrement64(&g_smManagerAmsRefcnt);
|
|
||||||
|
|
||||||
if (serviceIsActive(&g_smManagerAmsSrv))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return smGetService(&g_smManagerAmsSrv, "sm:m");
|
|
||||||
}
|
|
||||||
|
|
||||||
void smManagerAmsExit(void) {
|
|
||||||
if (atomicDecrement64(&g_smManagerAmsRefcnt) == 0)
|
|
||||||
serviceClose(&g_smManagerAmsSrv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result smManagerAmsEndInitialDefers(void) {
|
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
|
Service *srv = smManagerGetServiceSession();
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
u64 cmd_id;
|
u64 cmd_id;
|
||||||
} *raw;
|
} *raw;
|
||||||
|
|
||||||
raw = serviceIpcPrepareHeader(&g_smManagerAmsSrv, &c, sizeof(*raw));
|
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||||
raw->magic = SFCI_MAGIC;
|
raw->magic = SFCI_MAGIC;
|
||||||
raw->cmd_id = 65000;
|
raw->cmd_id = 65000;
|
||||||
|
|
||||||
|
|
||||||
Result rc = serviceIpcDispatch(&g_smManagerAmsSrv);
|
Result rc = serviceIpcDispatch(srv);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcParsedCommand r;
|
IpcParsedCommand r;
|
||||||
@ -58,7 +41,7 @@ Result smManagerAmsEndInitialDefers(void) {
|
|||||||
u64 result;
|
u64 result;
|
||||||
} *resp;
|
} *resp;
|
||||||
|
|
||||||
serviceIpcParse(&g_smManagerAmsSrv, &r, sizeof(*resp));
|
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||||
resp = r.Raw;
|
resp = r.Raw;
|
||||||
|
|
||||||
rc = resp->result;
|
rc = resp->result;
|
||||||
@ -68,9 +51,10 @@ Result smManagerAmsEndInitialDefers(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result smManagerAmsHasMitm(bool *out, const char* name) {
|
Result smManagerAtmosphereHasMitm(bool *out, const char* name) {
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
|
Service *srv = smManagerGetServiceSession();
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
@ -78,12 +62,12 @@ Result smManagerAmsHasMitm(bool *out, const char* name) {
|
|||||||
u64 service_name;
|
u64 service_name;
|
||||||
} *raw;
|
} *raw;
|
||||||
|
|
||||||
raw = serviceIpcPrepareHeader(&g_smManagerAmsSrv, &c, sizeof(*raw));
|
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||||
raw->magic = SFCI_MAGIC;
|
raw->magic = SFCI_MAGIC;
|
||||||
raw->cmd_id = 65001;
|
raw->cmd_id = 65001;
|
||||||
raw->service_name = smEncodeName(name);
|
raw->service_name = smEncodeName(name);
|
||||||
|
|
||||||
Result rc = serviceIpcDispatch(&g_smManagerAmsSrv);
|
Result rc = serviceIpcDispatch(srv);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcParsedCommand r;
|
IpcParsedCommand r;
|
||||||
@ -93,7 +77,7 @@ Result smManagerAmsHasMitm(bool *out, const char* name) {
|
|||||||
u8 has_mitm;
|
u8 has_mitm;
|
||||||
} *resp;
|
} *resp;
|
||||||
|
|
||||||
serviceIpcParse(&g_smManagerAmsSrv, &r, sizeof(*resp));
|
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||||
resp = r.Raw;
|
resp = r.Raw;
|
||||||
|
|
||||||
rc = resp->result;
|
rc = resp->result;
|
19
source/sm/smm_ams.h
Normal file
19
source/sm/smm_ams.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* @file smm_ams.h
|
||||||
|
* @brief Service manager manager (sm:m) IPC wrapper for Atmosphere extensions.
|
||||||
|
* @author SciresM
|
||||||
|
* @copyright libnx Authors
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <switch.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Result smManagerAtmosphereEndInitialDefers(void);
|
||||||
|
Result smManagerAtmosphereHasMitm(bool *out, const char* name);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
230
source/sm_mitm.c
230
source/sm_mitm.c
@ -1,230 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <switch.h>
|
|
||||||
#include <switch/arm/atomics.h>
|
|
||||||
#include <stratosphere/mitm/sm_mitm.h>
|
|
||||||
|
|
||||||
static Handle g_smMitmHandle = INVALID_HANDLE;
|
|
||||||
static u64 g_refCnt;
|
|
||||||
|
|
||||||
Result smMitMInitialize(void) {
|
|
||||||
atomicIncrement64(&g_refCnt);
|
|
||||||
|
|
||||||
if (g_smMitmHandle != INVALID_HANDLE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Result rc = svcConnectToNamedPort(&g_smMitmHandle, "sm:");
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
ipcSendPid(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 zero;
|
|
||||||
u64 reserved[2];
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 0;
|
|
||||||
raw->zero = 0;
|
|
||||||
|
|
||||||
rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
smExit();
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void smMitMExit(void) {
|
|
||||||
if (atomicDecrement64(&g_refCnt) == 0) {
|
|
||||||
svcCloseHandle(g_smMitmHandle);
|
|
||||||
g_smMitmHandle = INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result smMitMGetService(Service* service_out, const char *name_str)
|
|
||||||
{
|
|
||||||
u64 name = smEncodeName(name_str);
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 service_name;
|
|
||||||
u64 reserved[2];
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 1;
|
|
||||||
raw->service_name = name;
|
|
||||||
|
|
||||||
Result rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
service_out->type = ServiceType_Normal;
|
|
||||||
service_out->handle = r.Handles[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Result smMitMInstall(Handle *handle_out, Handle *query_out, const char *name) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 service_name;
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 65000;
|
|
||||||
raw->service_name = smEncodeName(name);
|
|
||||||
|
|
||||||
Result rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
*handle_out = r.Handles[0];
|
|
||||||
*query_out = r.Handles[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result smMitMUninstall(const char *name) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 service_name;
|
|
||||||
u64 reserved;
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 65001;
|
|
||||||
raw->service_name = smEncodeName(name);
|
|
||||||
|
|
||||||
Result rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result smMitMAcknowledgeSession(Service *srv_out, u64 *pid_out, const char *name) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 service_name;
|
|
||||||
u64 reserved;
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 65003;
|
|
||||||
raw->service_name = smEncodeName(name);
|
|
||||||
|
|
||||||
Result rc = ipcDispatch(g_smMitmHandle);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
u64 pid;
|
|
||||||
} *resp = r.Raw;
|
|
||||||
|
|
||||||
rc = resp->result;
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
*pid_out = resp->pid;
|
|
||||||
serviceCreate(srv_out, r.Handles[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user