mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-05 11:58:00 +00:00
sm: refactor mitm service handle acquisition
This commit is contained in:
parent
cead8a36ea
commit
44725c8910
2 changed files with 69 additions and 49 deletions
|
@ -227,6 +227,71 @@ bool Registration::HasMitm(u64 service) {
|
||||||
return target_service != NULL && target_service->mitm_pid != 0;
|
return target_service != NULL && target_service->mitm_pid != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result Registration::GetMitmServiceHandleImpl(Registration::Service *target_service, u64 pid, Handle *out) {
|
||||||
|
/* Send command to query if we should mitm. */
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u64 pid;
|
||||||
|
} *info = ((decltype(info))ipcPrepareHeader(&c, sizeof(*info)));
|
||||||
|
info->magic = SFCI_MAGIC;
|
||||||
|
info->cmd_id = 65000;
|
||||||
|
info->pid = pid;
|
||||||
|
R_TRY(ipcDispatch(target_service->mitm_query_h));
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we shouldn't mitm, give normal session. */
|
||||||
|
if (!should_mitm) {
|
||||||
|
return svcConnectToPort(out, target_service->port_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create both handles. If the second fails, close the first to prevent leak. */
|
||||||
|
R_TRY(svcConnectToPort(&target_service->mitm_fwd_sess_h, target_service->port_h));
|
||||||
|
R_TRY_CLEANUP(svcConnectToPort(out, target_service->mitm_port_h), {
|
||||||
|
svcCloseHandle(target_service->mitm_fwd_sess_h);
|
||||||
|
target_service->mitm_fwd_sess_h = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
target_service->mitm_waiting_ack_pid = pid;
|
||||||
|
target_service->mitm_waiting_ack = true;
|
||||||
|
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Registration::GetServiceHandleImpl(Registration::Service *target_service, u64 pid, Handle *out) {
|
||||||
|
/* Clear handle output. */
|
||||||
|
*out = 0;
|
||||||
|
|
||||||
|
/* If not mitm'd or mitm service is requesting, get normal session. */
|
||||||
|
if (target_service->mitm_pid == 0 || target_service->mitm_pid == pid) {
|
||||||
|
return svcConnectToPort(out, target_service->port_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're mitm'd. */
|
||||||
|
if (R_FAILED(GetMitmServiceHandleImpl(target_service, pid, out))) {
|
||||||
|
/* If the Mitm service is dead, just give a normal session. */
|
||||||
|
return svcConnectToPort(out, target_service->port_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
Result Registration::GetServiceHandle(u64 pid, u64 service, Handle *out) {
|
Result Registration::GetServiceHandle(u64 pid, u64 service, Handle *out) {
|
||||||
Registration::Service *target_service = GetService(service);
|
Registration::Service *target_service = GetService(service);
|
||||||
if (target_service == NULL || ShouldInitDefer(service) || target_service->mitm_waiting_ack) {
|
if (target_service == NULL || ShouldInitDefer(service) || target_service->mitm_waiting_ack) {
|
||||||
|
@ -234,55 +299,8 @@ Result Registration::GetServiceHandle(u64 pid, u64 service, Handle *out) {
|
||||||
return ResultServiceFrameworkRequestDeferredByUser;
|
return ResultServiceFrameworkRequestDeferredByUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = 0;
|
R_TRY_CATCH(GetServiceHandleImpl(target_service, pid, out)) {
|
||||||
Result rc;
|
/* Convert Kernel result to SM result. */
|
||||||
if (target_service->mitm_pid == 0 || target_service->mitm_pid == pid) {
|
|
||||||
rc = svcConnectToPort(out, target_service->port_h);
|
|
||||||
} else {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
u64 pid;
|
|
||||||
} *info = ((decltype(info))ipcPrepareHeader(&c, sizeof(*info)));
|
|
||||||
info->magic = SFCI_MAGIC;
|
|
||||||
info->cmd_id = 65000;
|
|
||||||
info->pid = pid;
|
|
||||||
rc = ipcDispatch(target_service->mitm_query_h);
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
IpcParsedCommand r;
|
|
||||||
ipcParse(&r);
|
|
||||||
struct {
|
|
||||||
u64 magic;
|
|
||||||
u64 result;
|
|
||||||
bool should_mitm;
|
|
||||||
} *resp = ((decltype(resp))r.Raw);
|
|
||||||
rc = resp->result;
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
if (resp->should_mitm) {
|
|
||||||
rc = svcConnectToPort(&target_service->mitm_fwd_sess_h, target_service->port_h);
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
rc = svcConnectToPort(out, target_service->mitm_port_h);
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
target_service->mitm_waiting_ack_pid = pid;
|
|
||||||
target_service->mitm_waiting_ack = true;
|
|
||||||
} else {
|
|
||||||
svcCloseHandle(target_service->mitm_fwd_sess_h);
|
|
||||||
target_service->mitm_fwd_sess_h = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rc = svcConnectToPort(out, target_service->port_h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (R_FAILED(rc)) {
|
|
||||||
rc = svcConnectToPort(out, target_service->port_h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Convert Kernel result to SM result. */
|
|
||||||
R_TRY_CATCH(rc) {
|
|
||||||
R_CATCH(ResultKernelOutOfSessions) {
|
R_CATCH(ResultKernelOutOfSessions) {
|
||||||
return ResultSmInsufficientSessions;
|
return ResultSmInsufficientSessions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,8 @@ class Registration {
|
||||||
/* Service management. */
|
/* Service management. */
|
||||||
static bool HasService(u64 service);
|
static bool HasService(u64 service);
|
||||||
static bool HasMitm(u64 service);
|
static bool HasMitm(u64 service);
|
||||||
|
static Result GetMitmServiceHandleImpl(Registration::Service *service, u64 pid, Handle *out);
|
||||||
|
static Result GetServiceHandleImpl(Registration::Service *service, u64 pid, Handle *out);
|
||||||
static Result GetServiceHandle(u64 pid, u64 service, Handle *out);
|
static Result GetServiceHandle(u64 pid, u64 service, Handle *out);
|
||||||
static Result GetServiceForPid(u64 pid, u64 service, Handle *out);
|
static Result GetServiceForPid(u64 pid, u64 service, Handle *out);
|
||||||
static Result RegisterServiceForPid(u64 pid, u64 service, u64 max_sessions, bool is_light, Handle *out);
|
static Result RegisterServiceForPid(u64 pid, u64 service, u64 max_sessions, bool is_light, Handle *out);
|
||||||
|
|
Loading…
Reference in a new issue