Merge branch 'master' into npdmfixup
This commit is contained in:
@@ -21,7 +21,7 @@ TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
INCLUDES := include ../../common/include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
DEFINES := -DDISABLE_IPC
|
||||
@@ -34,7 +34,7 @@ ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DSM_ENABLE_SMHAX -DSM_ENABLE_MITM -DSM_MINIMUM_SESSION_LIMIT=8
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DSM_ENABLE_SMHAX -DSM_ENABLE_MITM -DSM_ENABLE_INIT_DEFERS -DSM_MINIMUM_SESSION_LIMIT=8
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "sm",
|
||||
"title_id": "0x0100000000000004",
|
||||
"main_thread_stack_size": "0x1000",
|
||||
"main_thread_stack_size": "0x2000",
|
||||
"main_thread_priority": 27,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
@@ -13,58 +13,59 @@
|
||||
{
|
||||
"type": "syscalls",
|
||||
"value": {
|
||||
"svcSetHeapSize": "0x01",
|
||||
"svcSetMemoryPermission": "0x02",
|
||||
"svcSetMemoryAttribute": "0x03",
|
||||
"svcMapMemory": "0x04",
|
||||
"svcUnmapMemory": "0x05",
|
||||
"svcQueryMemory": "0x06",
|
||||
"svcExitProcess": "0x07",
|
||||
"svcCreateThread": "0x08",
|
||||
"svcStartThread": "0x09",
|
||||
"svcExitThread": "0x0A",
|
||||
"svcSleepThread": "0x0B",
|
||||
"svcGetThreadPriority": "0x0C",
|
||||
"svcSetThreadPriority": "0x0D",
|
||||
"svcGetThreadCoreMask": "0x0E",
|
||||
"svcSetThreadCoreMask": "0x0F",
|
||||
"svcGetCurrentProcessorNumber": "0x10",
|
||||
"svcSignalEvent": "0x11",
|
||||
"svcClearEvent": "0x12",
|
||||
"svcMapSharedMemory": "0x13",
|
||||
"svcUnmapSharedMemory": "0x14",
|
||||
"svcCreateTransferMemory": "0x15",
|
||||
"svcCloseHandle": "0x16",
|
||||
"svcResetSignal": "0x17",
|
||||
"svcWaitSynchronization": "0x18",
|
||||
"svcCancelSynchronization": "0x19",
|
||||
"svcArbitrateLock": "0x1A",
|
||||
"svcArbitrateUnlock": "0x1B",
|
||||
"svcWaitProcessWideKeyAtomic": "0x1C",
|
||||
"svcSignalProcessWideKey": "0x1D",
|
||||
"svcGetSystemTick": "0x1E",
|
||||
"svcConnectToNamedPort": "0x1F",
|
||||
"svcSendSyncRequestLight": "0x20",
|
||||
"svcSendSyncRequest": "0x21",
|
||||
"svcSendSyncRequestWithUserBuffer": "0x22",
|
||||
"svcSendAsyncRequestWithUserBuffer": "0x23",
|
||||
"svcGetProcessId": "0x24",
|
||||
"svcGetThreadId": "0x25",
|
||||
"svcBreak": "0x26",
|
||||
"svcOutputDebugString": "0x27",
|
||||
"svcReturnFromException": "0x28",
|
||||
"svcGetInfo": "0x29",
|
||||
"svcWaitForAddress": "0x34",
|
||||
"svcSignalToAddress": "0x35",
|
||||
"svcCreateSession": "0x40",
|
||||
"svcAcceptSession": "0x41",
|
||||
"svcReplyAndReceiveLight": "0x42",
|
||||
"svcReplyAndReceive": "0x43",
|
||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||
"svcGetMemoryInfo": "0x6F",
|
||||
"svcCreatePort": "0x70",
|
||||
"svcManageNamedPort": "0x71",
|
||||
"svcConnectToPort": "0x72"
|
||||
"svcSetHeapSize" : "0x01",
|
||||
"svcSetMemoryPermission" : "0x02",
|
||||
"svcSetMemoryAttribute" : "0x03",
|
||||
"svcMapMemory" : "0x04",
|
||||
"svcUnmapMemory" : "0x05",
|
||||
"svcQueryMemory" : "0x06",
|
||||
"svcExitProcess" : "0x07",
|
||||
"svcCreateThread" : "0x08",
|
||||
"svcStartThread" : "0x09",
|
||||
"svcExitThread" : "0x0A",
|
||||
"svcSleepThread" : "0x0B",
|
||||
"svcGetThreadPriority" : "0x0C",
|
||||
"svcSetThreadPriority" : "0x0D",
|
||||
"svcGetThreadCoreMask" : "0x0E",
|
||||
"svcSetThreadCoreMask" : "0x0F",
|
||||
"svcGetCurrentProcessorNumber" : "0x10",
|
||||
"svcSignalEvent" : "0x11",
|
||||
"svcClearEvent" : "0x12",
|
||||
"svcMapSharedMemory" : "0x13",
|
||||
"svcUnmapSharedMemory" : "0x14",
|
||||
"svcCreateTransferMemory" : "0x15",
|
||||
"svcCloseHandle" : "0x16",
|
||||
"svcResetSignal" : "0x17",
|
||||
"svcWaitSynchronization" : "0x18",
|
||||
"svcCancelSynchronization" : "0x19",
|
||||
"svcArbitrateLock" : "0x1A",
|
||||
"svcArbitrateUnlock" : "0x1B",
|
||||
"svcWaitProcessWideKeyAtomic" : "0x1C",
|
||||
"svcSignalProcessWideKey" : "0x1D",
|
||||
"svcGetSystemTick" : "0x1E",
|
||||
"svcConnectToNamedPort" : "0x1F",
|
||||
"svcSendSyncRequestLight" : "0x20",
|
||||
"svcSendSyncRequest" : "0x21",
|
||||
"svcSendSyncRequestWithUserBuffer" : "0x22",
|
||||
"svcSendAsyncRequestWithUserBuffer" : "0x23",
|
||||
"svcGetProcessId" : "0x24",
|
||||
"svcGetThreadId" : "0x25",
|
||||
"svcBreak" : "0x26",
|
||||
"svcOutputDebugString" : "0x27",
|
||||
"svcReturnFromException" : "0x28",
|
||||
"svcGetInfo" : "0x29",
|
||||
"svcWaitForAddress" : "0x34",
|
||||
"svcSignalToAddress" : "0x35",
|
||||
"svcCreateSession" : "0x40",
|
||||
"svcAcceptSession" : "0x41",
|
||||
"svcReplyAndReceiveLight" : "0x42",
|
||||
"svcReplyAndReceive" : "0x43",
|
||||
"svcReplyAndReceiveWithUserBuffer" : "0x44",
|
||||
"svcCreateEvent" : "0x45",
|
||||
"svcGetMemoryInfo" : "0x6F",
|
||||
"svcCreatePort" : "0x70",
|
||||
"svcManageNamedPort" : "0x71",
|
||||
"svcConnectToPort" : "0x72"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -61,15 +61,18 @@ void __appExit(void) {
|
||||
/* Nothing to clean up, because we're sm. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
consoleDebugInit(debugDevice_SVC);
|
||||
|
||||
/* TODO: What's a good timeout value to use here? */
|
||||
WaitableManager *server_manager = new WaitableManager(U64_MAX);
|
||||
|
||||
auto server_manager = new WaitableManager(1);
|
||||
|
||||
/* Create sm:, (and thus allow things to register to it). */
|
||||
server_manager->add_waitable(new ManagedPortServer<UserService>("sm:", 0x40));
|
||||
server_manager->AddWaitable(new ManagedPortServer<UserService>("sm:", 0x40));
|
||||
|
||||
/* Create sm:m manually. */
|
||||
Handle smm_h;
|
||||
@@ -78,10 +81,10 @@ int main(int argc, char **argv)
|
||||
while (1) { }
|
||||
}
|
||||
|
||||
server_manager->add_waitable(new ExistingPortServer<ManagerService>(smm_h, 1));
|
||||
|
||||
server_manager->AddWaitable(new ExistingPortServer<ManagerService>(smm_h, 1));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
server_manager->process();
|
||||
server_manager->Process();
|
||||
|
||||
/* Cleanup. */
|
||||
delete server_manager;
|
||||
|
||||
@@ -19,31 +19,15 @@
|
||||
#include "sm_manager_service.hpp"
|
||||
#include "sm_registration.hpp"
|
||||
|
||||
Result ManagerService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
||||
Result rc = 0xF601;
|
||||
switch ((ManagerServiceCmd)cmd_id) {
|
||||
case Manager_Cmd_RegisterProcess:
|
||||
rc = WrapIpcCommandImpl<&ManagerService::register_process>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
case Manager_Cmd_UnregisterProcess:
|
||||
rc = WrapIpcCommandImpl<&ManagerService::unregister_process>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
Result ManagerService::RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac) {
|
||||
return Registration::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements);
|
||||
}
|
||||
|
||||
Result ManagerService::handle_deferred() {
|
||||
/* This service is never deferrable. */
|
||||
return 0;
|
||||
Result ManagerService::UnregisterProcess(u64 pid) {
|
||||
return Registration::UnregisterProcess(pid);
|
||||
}
|
||||
|
||||
|
||||
std::tuple<Result> ManagerService::register_process(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac) {
|
||||
return {Registration::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements)};
|
||||
void ManagerService::AtmosphereEndInitDefers() {
|
||||
Registration::EndInitDefers();
|
||||
}
|
||||
|
||||
std::tuple<Result> ManagerService::unregister_process(u64 pid) {
|
||||
return {Registration::UnregisterProcess(pid)};
|
||||
}
|
||||
|
||||
@@ -16,24 +16,27 @@
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere/iserviceobject.hpp>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
enum ManagerServiceCmd {
|
||||
Manager_Cmd_RegisterProcess = 0,
|
||||
Manager_Cmd_UnregisterProcess = 1
|
||||
Manager_Cmd_UnregisterProcess = 1,
|
||||
|
||||
|
||||
Manager_Cmd_AtmosphereEndInitDefers = 65000,
|
||||
};
|
||||
|
||||
class ManagerService final : public IServiceObject {
|
||||
public:
|
||||
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override;
|
||||
Result handle_deferred() override;
|
||||
|
||||
ManagerService *clone() override {
|
||||
return new ManagerService();
|
||||
}
|
||||
|
||||
private:
|
||||
/* Actual commands. */
|
||||
std::tuple<Result> register_process(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac);
|
||||
std::tuple<Result> unregister_process(u64 pid);
|
||||
virtual Result RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac);
|
||||
virtual Result UnregisterProcess(u64 pid);
|
||||
virtual void AtmosphereEndInitDefers();
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MakeServiceCommandMeta<Manager_Cmd_RegisterProcess, &ManagerService::RegisterProcess>(),
|
||||
MakeServiceCommandMeta<Manager_Cmd_UnregisterProcess, &ManagerService::UnregisterProcess>(),
|
||||
|
||||
MakeServiceCommandMeta<Manager_Cmd_AtmosphereEndInitDefers, &ManagerService::AtmosphereEndInitDefers>(),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include <switch.h>
|
||||
#include <algorithm>
|
||||
#include <stratosphere/servicesession.hpp>
|
||||
#include <stratosphere.hpp>
|
||||
#include "sm_registration.hpp"
|
||||
#include "meta_tools.hpp"
|
||||
|
||||
@@ -26,6 +26,7 @@ static std::array<Registration::Service, REGISTRATION_LIST_MAX_SERVICE> g_servic
|
||||
static u64 g_initial_process_id_low = 0;
|
||||
static u64 g_initial_process_id_high = 0;
|
||||
static bool g_determined_initial_process_ids = false;
|
||||
static bool g_end_init_defers = false;
|
||||
|
||||
u64 GetServiceNameLength(u64 service) {
|
||||
u64 service_name_len = 0;
|
||||
@@ -36,6 +37,38 @@ u64 GetServiceNameLength(u64 service) {
|
||||
return service_name_len;
|
||||
}
|
||||
|
||||
/* Atmosphere extension utilities. */
|
||||
void Registration::EndInitDefers() {
|
||||
g_end_init_defers = true;
|
||||
}
|
||||
|
||||
constexpr u64 EncodeNameConstant(const char *name) {
|
||||
u64 service = 0;
|
||||
for (unsigned int i = 0; i < sizeof(service); i++) {
|
||||
if (name[i] == '\x00') {
|
||||
break;
|
||||
}
|
||||
service |= ((u64)name[i]) << (8 * i);
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
bool Registration::ShouldInitDefer(u64 service) {
|
||||
/* Only enable if compile-time generated. */
|
||||
#ifndef SM_ENABLE_INIT_DEFERS
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (g_end_init_defers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This is a mechanism by which certain services will always be deferred until sm:m receives a special command. */
|
||||
/* This can be extended with more services as needed at a later date. */
|
||||
constexpr u64 FSP_SRV = EncodeNameConstant("fsp-srv");
|
||||
return service == FSP_SRV;
|
||||
}
|
||||
|
||||
/* Utilities. */
|
||||
Registration::Process *Registration::GetProcessForPid(u64 pid) {
|
||||
auto process_it = std::find_if(g_process_list.begin(), g_process_list.end(), member_equals_fn(&Process::pid, pid));
|
||||
@@ -188,11 +221,13 @@ bool Registration::HasService(u64 service) {
|
||||
|
||||
Result Registration::GetServiceHandle(u64 pid, u64 service, Handle *out) {
|
||||
Registration::Service *target_service = GetService(service);
|
||||
if (target_service == NULL) {
|
||||
if (target_service == NULL || ShouldInitDefer(service)) {
|
||||
/* Note: This defers the result until later. */
|
||||
return RESULT_DEFER_SESSION;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
*out = 0;
|
||||
Result rc;
|
||||
if (target_service->mitm_pid == 0 || target_service->mitm_pid == pid) {
|
||||
@@ -215,7 +250,7 @@ Result Registration::GetServiceHandle(u64 pid, u64 service, Handle *out) {
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 should_mitm;
|
||||
bool should_mitm;
|
||||
} *resp = ((decltype(resp))r.Raw);
|
||||
rc = resp->result;
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
|
||||
@@ -46,6 +46,9 @@ class Registration {
|
||||
};
|
||||
|
||||
/* Utilities. */
|
||||
static void EndInitDefers();
|
||||
static bool ShouldInitDefer(u64 service);
|
||||
|
||||
static Registration::Process *GetProcessForPid(u64 pid);
|
||||
static Registration::Process *GetFreeProcess();
|
||||
static Registration::Service *GetService(u64 service);
|
||||
|
||||
22
stratosphere/sm/source/sm_types.hpp
Normal file
22
stratosphere/sm/source/sm_types.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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
|
||||
struct SmServiceName {
|
||||
char name[sizeof(u64)];
|
||||
};
|
||||
|
||||
static_assert(__alignof__(SmServiceName) == 1, "SmServiceName definition!");
|
||||
@@ -15,116 +15,90 @@
|
||||
*/
|
||||
|
||||
#include <switch.h>
|
||||
#include <stratosphere/servicesession.hpp>
|
||||
#include <stratosphere.hpp>
|
||||
#include "sm_user_service.hpp"
|
||||
#include "sm_registration.hpp"
|
||||
|
||||
Result UserService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
||||
Result rc = 0xF601;
|
||||
switch ((UserServiceCmd)cmd_id) {
|
||||
case User_Cmd_Initialize:
|
||||
rc = WrapIpcCommandImpl<&UserService::initialize>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
case User_Cmd_GetService:
|
||||
rc = WrapIpcCommandImpl<&UserService::get_service>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
case User_Cmd_RegisterService:
|
||||
rc = WrapIpcCommandImpl<&UserService::register_service>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
case User_Cmd_UnregisterService:
|
||||
rc = WrapIpcCommandImpl<&UserService::unregister_service>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
#ifdef SM_ENABLE_MITM
|
||||
case User_Cmd_AtmosphereInstallMitm:
|
||||
rc = WrapIpcCommandImpl<&UserService::install_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
case User_Cmd_AtmosphereUninstallMitm:
|
||||
rc = WrapIpcCommandImpl<&UserService::uninstall_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
case User_Cmd_AtmosphereAssociatePidTidForMitm:
|
||||
rc = WrapIpcCommandImpl<&UserService::associate_pid_tid_for_mitm>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
Result UserService::Initialize(PidDescriptor pid) {
|
||||
this->pid = pid.pid;
|
||||
this->has_initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result UserService::GetService(Out<MovedHandle> out_h, SmServiceName service) {
|
||||
Handle session_h = 0;
|
||||
Result rc = 0x415;
|
||||
|
||||
#ifdef SM_ENABLE_SMHAX
|
||||
if (!this->has_initialized) {
|
||||
rc = Registration::GetServiceForPid(Registration::GetInitialProcessId(), smEncodeName(service.name), &session_h);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
if (this->has_initialized) {
|
||||
rc = Registration::GetServiceForPid(this->pid, smEncodeName(service.name), &session_h);
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
out_h.SetValue(session_h);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result UserService::handle_deferred() {
|
||||
/* If we're deferred, GetService failed. */
|
||||
return WrapDeferredIpcCommandImpl<&UserService::deferred_get_service>(this, this->deferred_service);;
|
||||
}
|
||||
|
||||
|
||||
std::tuple<Result> UserService::initialize(PidDescriptor pid) {
|
||||
this->pid = pid.pid;
|
||||
this->has_initialized = true;
|
||||
return {0};
|
||||
}
|
||||
|
||||
std::tuple<Result, MovedHandle> UserService::get_service(u64 service) {
|
||||
Handle session_h = 0;
|
||||
Result rc = 0x415;
|
||||
#ifdef SM_ENABLE_SMHAX
|
||||
if (!this->has_initialized) {
|
||||
rc = Registration::GetServiceForPid(Registration::GetInitialProcessId(), service, &session_h);
|
||||
}
|
||||
#endif
|
||||
if (this->has_initialized) {
|
||||
rc = Registration::GetServiceForPid(this->pid, service, &session_h);
|
||||
}
|
||||
/* It's possible that this will end up deferring us...take that into account. */
|
||||
if (rc == RESULT_DEFER_SESSION) {
|
||||
this->deferred_service = service;
|
||||
}
|
||||
return {rc, MovedHandle{session_h}};
|
||||
}
|
||||
|
||||
std::tuple<Result, MovedHandle> UserService::deferred_get_service(u64 service) {
|
||||
Handle session_h = 0;
|
||||
Result rc = Registration::GetServiceHandle(this->pid, service, &session_h);
|
||||
return {rc, MovedHandle{session_h}};
|
||||
}
|
||||
|
||||
std::tuple<Result, MovedHandle> UserService::register_service(u64 service, u8 is_light, u32 max_sessions) {
|
||||
Result UserService::RegisterService(Out<MovedHandle> out_h, SmServiceName service, u32 max_sessions, bool is_light) {
|
||||
Handle service_h = 0;
|
||||
Result rc = 0x415;
|
||||
#ifdef SM_ENABLE_SMHAX
|
||||
if (!this->has_initialized) {
|
||||
rc = Registration::RegisterServiceForPid(Registration::GetInitialProcessId(), service, max_sessions, (is_light & 1) != 0, &service_h);
|
||||
rc = Registration::RegisterServiceForPid(Registration::GetInitialProcessId(), smEncodeName(service.name), max_sessions, (is_light & 1) != 0, &service_h);
|
||||
}
|
||||
#endif
|
||||
if (this->has_initialized) {
|
||||
rc = Registration::RegisterServiceForPid(this->pid, service, max_sessions, (is_light & 1) != 0, &service_h);
|
||||
rc = Registration::RegisterServiceForPid(this->pid, smEncodeName(service.name), max_sessions, (is_light & 1) != 0, &service_h);
|
||||
}
|
||||
return {rc, MovedHandle{service_h}};
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
out_h.SetValue(service_h);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
std::tuple<Result> UserService::unregister_service(u64 service) {
|
||||
Result UserService::UnregisterService(SmServiceName service) {
|
||||
Result rc = 0x415;
|
||||
#ifdef SM_ENABLE_SMHAX
|
||||
if (!this->has_initialized) {
|
||||
rc = Registration::UnregisterServiceForPid(Registration::GetInitialProcessId(), service);
|
||||
rc = Registration::UnregisterServiceForPid(Registration::GetInitialProcessId(), smEncodeName(service.name));
|
||||
}
|
||||
#endif
|
||||
if (this->has_initialized) {
|
||||
rc = Registration::UnregisterServiceForPid(this->pid, service);
|
||||
rc = Registration::UnregisterServiceForPid(this->pid, smEncodeName(service.name));
|
||||
}
|
||||
return {rc};
|
||||
return rc;
|
||||
}
|
||||
|
||||
std::tuple<Result, MovedHandle, MovedHandle> UserService::install_mitm(u64 service) {
|
||||
Result UserService::AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, SmServiceName service) {
|
||||
Handle service_h = 0;
|
||||
Handle query_h = 0;
|
||||
Result rc = 0x415;
|
||||
if (this->has_initialized) {
|
||||
rc = Registration::InstallMitmForPid(this->pid, service, &service_h, &query_h);
|
||||
rc = Registration::InstallMitmForPid(this->pid, smEncodeName(service.name), &service_h, &query_h);
|
||||
}
|
||||
return {rc, MovedHandle{service_h}, MovedHandle{query_h}};
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
srv_h.SetValue(service_h);
|
||||
qry_h.SetValue(query_h);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
std::tuple<Result> UserService::associate_pid_tid_for_mitm(u64 pid, u64 tid) {
|
||||
Result UserService::AtmosphereUninstallMitm(SmServiceName service) {
|
||||
Result rc = 0x415;
|
||||
if (this->has_initialized) {
|
||||
rc = Registration::UninstallMitmForPid(this->pid, smEncodeName(service.name));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result UserService::AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid) {
|
||||
Result rc = 0x415;
|
||||
if (this->has_initialized) {
|
||||
if (Registration::IsInitialProcess(pid)) {
|
||||
@@ -133,13 +107,5 @@ std::tuple<Result> UserService::associate_pid_tid_for_mitm(u64 pid, u64 tid) {
|
||||
rc = Registration::AssociatePidTidForMitm(pid, tid);
|
||||
}
|
||||
}
|
||||
return {rc};
|
||||
return rc;
|
||||
}
|
||||
|
||||
std::tuple<Result> UserService::uninstall_mitm(u64 service) {
|
||||
Result rc = 0x415;
|
||||
if (this->has_initialized) {
|
||||
rc = Registration::UninstallMitmForPid(this->pid, service);
|
||||
}
|
||||
return {rc};
|
||||
}
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere/iserviceobject.hpp>
|
||||
#include <stratosphere.hpp>
|
||||
#include "sm_types.hpp"
|
||||
|
||||
enum UserServiceCmd {
|
||||
User_Cmd_Initialize = 0,
|
||||
@@ -30,32 +31,31 @@ enum UserServiceCmd {
|
||||
};
|
||||
|
||||
class UserService final : public IServiceObject {
|
||||
u64 pid = U64_MAX;
|
||||
bool has_initialized = false;
|
||||
u64 deferred_service = 0;
|
||||
|
||||
public:
|
||||
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override;
|
||||
Result handle_deferred() override;
|
||||
|
||||
UserService *clone() override {
|
||||
auto new_srv = new UserService();
|
||||
new_srv->pid = pid;
|
||||
new_srv->has_initialized = has_initialized;
|
||||
new_srv->deferred_service = deferred_service;
|
||||
return new_srv;
|
||||
}
|
||||
|
||||
private:
|
||||
u64 pid = U64_MAX;
|
||||
bool has_initialized = false;
|
||||
|
||||
/* Actual commands. */
|
||||
std::tuple<Result> initialize(PidDescriptor pid);
|
||||
std::tuple<Result, MovedHandle> get_service(u64 service);
|
||||
std::tuple<Result, MovedHandle> deferred_get_service(u64 service);
|
||||
std::tuple<Result, MovedHandle> register_service(u64 service, u8 is_light, u32 max_sessions);
|
||||
std::tuple<Result> unregister_service(u64 service);
|
||||
virtual Result Initialize(PidDescriptor pid);
|
||||
virtual Result GetService(Out<MovedHandle> out_h, SmServiceName service);
|
||||
virtual Result RegisterService(Out<MovedHandle> out_h, SmServiceName service, u32 max_sessions, bool is_light);
|
||||
virtual Result UnregisterService(SmServiceName service);
|
||||
|
||||
/* Atmosphere commands. */
|
||||
std::tuple<Result, MovedHandle, MovedHandle> install_mitm(u64 service);
|
||||
std::tuple<Result> uninstall_mitm(u64 service);
|
||||
std::tuple<Result> associate_pid_tid_for_mitm(u64 pid, u64 tid);
|
||||
virtual Result AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, SmServiceName service);
|
||||
virtual Result AtmosphereUninstallMitm(SmServiceName service);
|
||||
virtual Result AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MakeServiceCommandMeta<User_Cmd_Initialize, &UserService::Initialize>(),
|
||||
MakeServiceCommandMeta<User_Cmd_GetService, &UserService::GetService>(),
|
||||
MakeServiceCommandMeta<User_Cmd_RegisterService, &UserService::RegisterService>(),
|
||||
MakeServiceCommandMeta<User_Cmd_UnregisterService, &UserService::UnregisterService>(),
|
||||
|
||||
#ifdef SM_ENABLE_MITM
|
||||
MakeServiceCommandMeta<User_Cmd_AtmosphereInstallMitm, &UserService::AtmosphereInstallMitm>(),
|
||||
MakeServiceCommandMeta<User_Cmd_AtmosphereUninstallMitm, &UserService::AtmosphereUninstallMitm>(),
|
||||
MakeServiceCommandMeta<User_Cmd_AtmosphereAssociatePidTidForMitm, &UserService::AtmosphereAssociatePidTidForMitm>(),
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user