mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-23 04:12:02 +00:00
pm: address review comments.
This commit is contained in:
parent
08ad48fbf3
commit
a9f5b7728b
10 changed files with 135 additions and 145 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit d7d7cba3d35e5aa029ace71891e317e0d5412131
|
Subproject commit 45700a12e80404e3c49e2bc4893412489fc72040
|
|
@ -137,11 +137,6 @@ namespace sts::boot2 {
|
||||||
void LaunchTitle(u64 *out_process_id, const ncm::TitleLocation &loc, u32 launch_flags) {
|
void LaunchTitle(u64 *out_process_id, const ncm::TitleLocation &loc, u32 launch_flags) {
|
||||||
u64 process_id = 0;
|
u64 process_id = 0;
|
||||||
|
|
||||||
/* Don't launch a title twice during boot2. */
|
|
||||||
if (pm::info::HasLaunchedTitle(loc.title_id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (pm::shell::LaunchTitle(&process_id, loc, launch_flags)) {
|
switch (pm::shell::LaunchTitle(&process_id, loc, launch_flags)) {
|
||||||
case ResultKernelResourceExhausted:
|
case ResultKernelResourceExhausted:
|
||||||
/* Out of resource! */
|
/* Out of resource! */
|
||||||
|
@ -186,11 +181,9 @@ namespace sts::boot2 {
|
||||||
|
|
||||||
bool IsMaintenanceMode() {
|
bool IsMaintenanceMode() {
|
||||||
/* Contact set:sys, retrieve boot!force_maintenance. */
|
/* Contact set:sys, retrieve boot!force_maintenance. */
|
||||||
DoWithSmSession([&]() {
|
|
||||||
R_ASSERT(setsysInitialize());
|
|
||||||
});
|
|
||||||
{
|
{
|
||||||
ON_SCOPE_EXIT { setsysExit(); };
|
auto set_sys_holder = sm::ScopedServiceHolder<setsysInitialize, setsysExit>();
|
||||||
|
R_ASSERT(set_sys_holder.GetResult());
|
||||||
|
|
||||||
u8 force_maintenance = 1;
|
u8 force_maintenance = 1;
|
||||||
setsysGetSettingsItemValue("boot", "force_maintenance", &force_maintenance, sizeof(force_maintenance));
|
setsysGetSettingsItemValue("boot", "force_maintenance", &force_maintenance, sizeof(force_maintenance));
|
||||||
|
@ -200,50 +193,36 @@ namespace sts::boot2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Contact GPIO, read plus/minus buttons. */
|
/* Contact GPIO, read plus/minus buttons. */
|
||||||
DoWithSmSession([&]() {
|
|
||||||
R_ASSERT(gpioInitialize());
|
|
||||||
});
|
|
||||||
{
|
{
|
||||||
ON_SCOPE_EXIT { gpioExit(); };
|
auto gpio_holder = sm::ScopedServiceHolder<gpioInitialize, gpioExit>();
|
||||||
|
R_ASSERT(gpio_holder.GetResult());
|
||||||
|
|
||||||
return GetGpioPadLow(GpioPadName_ButtonVolUp) && GetGpioPadLow(GpioPadName_ButtonVolDown);
|
return GetGpioPadLow(GpioPadName_ButtonVolUp) && GetGpioPadLow(GpioPadName_ButtonVolDown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitForMitm(const char *service) {
|
|
||||||
const auto name = sts::sm::ServiceName::Encode(service);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
bool mitm_installed = false;
|
|
||||||
R_ASSERT(sts::sm::mitm::HasMitm(&mitm_installed, name));
|
|
||||||
if (mitm_installed) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
svcSleepThread(1'000'000ull);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaunchFlaggedProgramsFromSdCard() {
|
void LaunchFlaggedProgramsFromSdCard() {
|
||||||
/* Allow for user-customizable programs. */
|
/* Allow for user-customizable programs. */
|
||||||
DIR *titles_dir = opendir("sdmc:/atmosphere/titles");
|
DIR *titles_dir = opendir("sdmc:/atmosphere/titles");
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
if (titles_dir != NULL) {
|
if (titles_dir != nullptr) {
|
||||||
while ((ent = readdir(titles_dir)) != NULL) {
|
ON_SCOPE_EXIT { closedir(titles_dir); };
|
||||||
|
|
||||||
|
while ((ent = readdir(titles_dir)) != nullptr) {
|
||||||
if (strlen(ent->d_name) == 2 * sizeof(u64) && IsHexadecimal(ent->d_name)) {
|
if (strlen(ent->d_name) == 2 * sizeof(u64) && IsHexadecimal(ent->d_name)) {
|
||||||
ncm::TitleId title_id{strtoul(ent->d_name, NULL, 16)};
|
ncm::TitleId title_id{strtoul(ent->d_name, nullptr, 16)};
|
||||||
if (pm::info::HasLaunchedTitle(title_id)) {
|
if (pm::info::HasLaunchedTitle(title_id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char title_path[FS_MAX_PATH];
|
char title_path[FS_MAX_PATH];
|
||||||
std::snprintf(title_path, sizeof(title_path), "sdmc:/atmosphere/titles/%s/flags/boot2.flag", ent->d_name);
|
std::snprintf(title_path, sizeof(title_path), "sdmc:/atmosphere/titles/%s/flags/boot2.flag", ent->d_name);
|
||||||
FILE *f_flag = fopen(title_path, "rb");
|
FILE *f_flag = fopen(title_path, "rb");
|
||||||
if (f_flag != NULL) {
|
if (f_flag != nullptr) {
|
||||||
fclose(f_flag);
|
fclose(f_flag);
|
||||||
LaunchTitle(nullptr, ncm::TitleLocation::Make(title_id, ncm::StorageId::None), 0);
|
LaunchTitle(nullptr, ncm::TitleLocation::Make(title_id, ncm::StorageId::None), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(titles_dir);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +231,7 @@ namespace sts::boot2 {
|
||||||
/* Boot2 API. */
|
/* Boot2 API. */
|
||||||
void LaunchBootPrograms() {
|
void LaunchBootPrograms() {
|
||||||
/* Wait until fs.mitm has installed itself. We want this to happen as early as possible. */
|
/* Wait until fs.mitm has installed itself. We want this to happen as early as possible. */
|
||||||
WaitForMitm("fsp-srv");
|
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("fsp-srv")));
|
||||||
|
|
||||||
/* Launch programs required to mount the SD card. */
|
/* Launch programs required to mount the SD card. */
|
||||||
LaunchList(PreSdCardLaunchPrograms, NumPreSdCardLaunchPrograms);
|
LaunchList(PreSdCardLaunchPrograms, NumPreSdCardLaunchPrograms);
|
||||||
|
@ -268,10 +247,11 @@ namespace sts::boot2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for other atmosphere mitm modules to initialize. */
|
/* Wait for other atmosphere mitm modules to initialize. */
|
||||||
|
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("set:sys")));
|
||||||
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200) {
|
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200) {
|
||||||
WaitForMitm("bpc");
|
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc")));
|
||||||
} else {
|
} else {
|
||||||
WaitForMitm("bpc:c");
|
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc:c")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Launch Atmosphere dmnt, using FsStorageId_None to force SD card boot. */
|
/* Launch Atmosphere dmnt, using FsStorageId_None to force SD card boot. */
|
||||||
|
|
|
@ -86,63 +86,6 @@ namespace sts::pm::impl {
|
||||||
this->state = state;
|
this->state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSignalOnExit() {
|
|
||||||
this->SetFlag(Flag_SignalOnExit);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetExceptionOccurred() {
|
|
||||||
this->SetFlag(Flag_ExceptionOccurred);
|
|
||||||
this->SetFlag(Flag_ExceptionWaitingAttach);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearExceptionOccurred() {
|
|
||||||
this->ClearFlag(Flag_ExceptionOccurred);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearExceptionWaitingAttach() {
|
|
||||||
this->ClearFlag(Flag_ExceptionWaitingAttach);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetSignalOnDebugEvent() {
|
|
||||||
this->SetFlag(Flag_SignalOnDebugEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetSuspendedStateChanged() {
|
|
||||||
this->SetFlag(Flag_SuspendedStateChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearSuspendedStateChanged() {
|
|
||||||
this->ClearFlag(Flag_SuspendedStateChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetSuspended() {
|
|
||||||
this->SetFlag(Flag_Suspended);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearSuspended() {
|
|
||||||
this->ClearFlag(Flag_Suspended);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetApplication() {
|
|
||||||
this->SetFlag(Flag_Application);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetSignalOnStart() {
|
|
||||||
this->SetFlag(Flag_SignalOnStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearSignalOnStart() {
|
|
||||||
this->ClearFlag(Flag_SignalOnStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetStartedStateChanged() {
|
|
||||||
this->SetFlag(Flag_StartedStateChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearStartedStateChanged() {
|
|
||||||
this->ClearFlag(Flag_StartedStateChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasStarted() const {
|
bool HasStarted() const {
|
||||||
return this->state != ProcessState_Created && this->state != ProcessState_CreatedAttached;
|
return this->state != ProcessState_Created && this->state != ProcessState_CreatedAttached;
|
||||||
}
|
}
|
||||||
|
@ -151,41 +94,60 @@ namespace sts::pm::impl {
|
||||||
return this->state == ProcessState_Exited;
|
return this->state == ProcessState_Exited;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShouldSignalOnExit() const {
|
#define DEFINE_FLAG_SET(flag) \
|
||||||
return this->HasFlag(Flag_SignalOnExit);
|
void Set##flag() { \
|
||||||
|
this->SetFlag(Flag_##flag); \
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasExceptionOccurred() const {
|
#define DEFINE_FLAG_GET(get, flag) \
|
||||||
return this->HasFlag(Flag_ExceptionOccurred);
|
bool get##flag() const { \
|
||||||
|
return this->HasFlag(Flag_##flag); \
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasExceptionWaitingAttach() const {
|
#define DEFINE_FLAG_CLEAR(flag) \
|
||||||
return this->HasFlag(Flag_ExceptionWaitingAttach);
|
void Clear##flag() { \
|
||||||
|
this->ClearFlag(Flag_##flag); \
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShouldSignalOnDebugEvent() const {
|
DEFINE_FLAG_SET(SignalOnExit)
|
||||||
return this->HasFlag(Flag_SignalOnDebugEvent);
|
DEFINE_FLAG_GET(Should, SignalOnExit)
|
||||||
|
|
||||||
|
/* This needs a manual setter, because it sets two flags. */
|
||||||
|
void SetExceptionOccurred() {
|
||||||
|
this->SetFlag(Flag_ExceptionOccurred);
|
||||||
|
this->SetFlag(Flag_ExceptionWaitingAttach);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShouldSignalOnStart() const {
|
DEFINE_FLAG_GET(Has, ExceptionOccurred)
|
||||||
return this->HasFlag(Flag_SignalOnStart);
|
DEFINE_FLAG_GET(Has, ExceptionWaitingAttach)
|
||||||
}
|
DEFINE_FLAG_CLEAR(ExceptionOccurred)
|
||||||
|
DEFINE_FLAG_CLEAR(ExceptionWaitingAttach)
|
||||||
|
|
||||||
bool HasSuspendedStateChanged() const {
|
DEFINE_FLAG_SET(SignalOnDebugEvent)
|
||||||
return this->HasFlag(Flag_SuspendedStateChanged);
|
DEFINE_FLAG_GET(Should, SignalOnDebugEvent)
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSuspended() const {
|
DEFINE_FLAG_SET(SuspendedStateChanged)
|
||||||
return this->HasFlag(Flag_Suspended);
|
DEFINE_FLAG_GET(Has, SuspendedStateChanged)
|
||||||
}
|
DEFINE_FLAG_CLEAR(SuspendedStateChanged)
|
||||||
|
|
||||||
bool IsApplication() const {
|
DEFINE_FLAG_SET(Suspended)
|
||||||
return this->HasFlag(Flag_Application);
|
DEFINE_FLAG_GET(Is, Suspended)
|
||||||
}
|
DEFINE_FLAG_CLEAR(Suspended)
|
||||||
|
|
||||||
bool HasStartedStateChanged() const {
|
DEFINE_FLAG_SET(Application)
|
||||||
return this->HasFlag(Flag_StartedStateChanged);
|
DEFINE_FLAG_GET(Is, Application)
|
||||||
}
|
|
||||||
|
DEFINE_FLAG_SET(SignalOnStart)
|
||||||
|
DEFINE_FLAG_GET(Should, SignalOnStart)
|
||||||
|
DEFINE_FLAG_CLEAR(SignalOnStart)
|
||||||
|
|
||||||
|
DEFINE_FLAG_SET(StartedStateChanged)
|
||||||
|
DEFINE_FLAG_GET(Has, StartedStateChanged)
|
||||||
|
DEFINE_FLAG_CLEAR(StartedStateChanged)
|
||||||
|
|
||||||
|
#undef DEFINE_FLAG_SET
|
||||||
|
#undef DEFINE_FLAG_GET
|
||||||
|
#undef DEFINE_FLAG_CLEAR
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -195,7 +157,7 @@ namespace sts::pm::impl {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<ProcessInfo> process_info;
|
std::shared_ptr<ProcessInfo> process_info;
|
||||||
public:
|
public:
|
||||||
ProcessInfoWaiter(std::shared_ptr<ProcessInfo> p) : process_info(p) { /* ... */ }
|
ProcessInfoWaiter(std::shared_ptr<ProcessInfo> p) : process_info(std::move(p)) { /* ... */ }
|
||||||
|
|
||||||
/* IWaitable */
|
/* IWaitable */
|
||||||
Handle GetHandle() override {
|
Handle GetHandle() override {
|
||||||
|
@ -235,27 +197,27 @@ namespace sts::pm::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Remove(u64 process_id) {
|
void Remove(u64 process_id) {
|
||||||
for (size_t i = 0; i < this->processes.size(); i++) {
|
for (auto it = this->processes.begin(); it != this->processes.end(); it++) {
|
||||||
if (this->processes[i]->GetProcessId() == process_id) {
|
if ((*it)->GetProcessId() == process_id) {
|
||||||
this->processes.erase(this->processes.begin() + i);
|
this->processes.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ProcessInfo> Find(u64 process_id) {
|
std::shared_ptr<ProcessInfo> Find(u64 process_id) {
|
||||||
for (size_t i = 0; i < this->processes.size(); i++) {
|
for (auto it = this->processes.begin(); it != this->processes.end(); it++) {
|
||||||
if (this->processes[i]->GetProcessId() == process_id) {
|
if ((*it)->GetProcessId() == process_id) {
|
||||||
return this->processes[i];
|
return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ProcessInfo> Find(ncm::TitleId title_id) {
|
std::shared_ptr<ProcessInfo> Find(ncm::TitleId title_id) {
|
||||||
for (size_t i = 0; i < this->processes.size(); i++) {
|
for (auto it = this->processes.begin(); it != this->processes.end(); it++) {
|
||||||
if (this->processes[i]->GetTitleLocation().title_id == title_id) {
|
if ((*it)->GetTitleLocation().title_id == title_id) {
|
||||||
return this->processes[i];
|
return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -141,20 +141,20 @@ namespace sts::pm::impl {
|
||||||
|
|
||||||
/* Process Tracking globals. */
|
/* Process Tracking globals. */
|
||||||
HosThread g_process_track_thread;
|
HosThread g_process_track_thread;
|
||||||
SessionManagerBase *g_process_waitable_manager = nullptr;
|
auto g_process_waitable_manager = WaitableManager(1);
|
||||||
|
|
||||||
/* Process lists. */
|
/* Process lists. */
|
||||||
ProcessList g_process_list;
|
ProcessList g_process_list;
|
||||||
ProcessList g_dead_process_list;
|
ProcessList g_dead_process_list;
|
||||||
|
|
||||||
/* Global events. */
|
/* Global events. */
|
||||||
IEvent *g_process_event = nullptr;
|
IEvent *g_process_event = CreateWriteOnlySystemEvent();
|
||||||
IEvent *g_hook_to_create_process_event = nullptr;
|
IEvent *g_hook_to_create_process_event = CreateWriteOnlySystemEvent();
|
||||||
IEvent *g_hook_to_create_application_process_event = nullptr;
|
IEvent *g_hook_to_create_application_process_event = CreateWriteOnlySystemEvent();
|
||||||
IEvent *g_boot_finished_event = nullptr;
|
IEvent *g_boot_finished_event = CreateWriteOnlySystemEvent();
|
||||||
|
|
||||||
/* Process Launch synchronization globals. */
|
/* Process Launch synchronization globals. */
|
||||||
IEvent *g_process_launch_start_event = nullptr;
|
IEvent *g_process_launch_start_event = CreateWriteOnlySystemEvent();
|
||||||
HosSignal g_process_launch_finish_signal;
|
HosSignal g_process_launch_finish_signal;
|
||||||
Result g_process_launch_result = ResultSuccess;
|
Result g_process_launch_result = ResultSuccess;
|
||||||
LaunchProcessArgs g_process_launch_args = {};
|
LaunchProcessArgs g_process_launch_args = {};
|
||||||
|
@ -167,13 +167,9 @@ namespace sts::pm::impl {
|
||||||
void ProcessTrackingMain(void *arg) {
|
void ProcessTrackingMain(void *arg) {
|
||||||
/* This is the main loop of the process tracking thread. */
|
/* This is the main loop of the process tracking thread. */
|
||||||
|
|
||||||
/* Create waitable manager. */
|
|
||||||
static auto s_process_waiter = WaitableManager(1);
|
|
||||||
g_process_waitable_manager = &s_process_waiter;
|
|
||||||
|
|
||||||
/* Service processes. */
|
/* Service processes. */
|
||||||
g_process_waitable_manager->AddWaitable(g_process_launch_start_event);
|
g_process_waitable_manager.AddWaitable(g_process_launch_start_event);
|
||||||
g_process_waitable_manager->Process();
|
g_process_waitable_manager.Process();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u32 GetLoaderCreateProcessFlags(u32 launch_flags) {
|
inline u32 GetLoaderCreateProcessFlags(u32 launch_flags) {
|
||||||
|
@ -189,6 +185,18 @@ namespace sts::pm::impl {
|
||||||
return ldr_flags;
|
return ldr_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasApplicationProcess() {
|
||||||
|
ProcessListAccessor list(g_process_list);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < list->GetSize(); i++) {
|
||||||
|
if (list[i]->IsApplication()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Result StartProcess(std::shared_ptr<ProcessInfo> process_info, const ldr::ProgramInfo *program_info) {
|
Result StartProcess(std::shared_ptr<ProcessInfo> process_info, const ldr::ProgramInfo *program_info) {
|
||||||
R_TRY(svcStartProcess(process_info->GetHandle(), program_info->main_thread_priority, program_info->default_cpu_id, program_info->main_thread_stack_size));
|
R_TRY(svcStartProcess(process_info->GetHandle(), program_info->main_thread_priority, program_info->default_cpu_id, program_info->main_thread_stack_size));
|
||||||
process_info->SetState(ProcessState_Running);
|
process_info->SetState(ProcessState_Running);
|
||||||
|
@ -203,7 +211,7 @@ namespace sts::pm::impl {
|
||||||
const bool allow_debug = (program_info.flags & ldr::ProgramInfoFlag_AllowDebug) || GetRuntimeFirmwareVersion() < FirmwareVersion_200;
|
const bool allow_debug = (program_info.flags & ldr::ProgramInfoFlag_AllowDebug) || GetRuntimeFirmwareVersion() < FirmwareVersion_200;
|
||||||
|
|
||||||
/* Ensure we only try to run one application. */
|
/* Ensure we only try to run one application. */
|
||||||
if (is_application) {
|
if (is_application && HasApplicationProcess()) {
|
||||||
return ResultPmApplicationRunning;
|
return ResultPmApplicationRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +276,7 @@ namespace sts::pm::impl {
|
||||||
{
|
{
|
||||||
ProcessListAccessor list(g_process_list);
|
ProcessListAccessor list(g_process_list);
|
||||||
list->Add(process_info);
|
list->Add(process_info);
|
||||||
g_process_waitable_manager->AddWaitable(new ProcessInfoWaiter(process_info));
|
g_process_waitable_manager.AddWaitable(new ProcessInfoWaiter(process_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
*args->out_process_id = process_id;
|
*args->out_process_id = process_id;
|
||||||
|
@ -395,7 +403,7 @@ namespace sts::pm::impl {
|
||||||
Result LaunchTitle(u64 *out_process_id, const ncm::TitleLocation &loc, u32 flags) {
|
Result LaunchTitle(u64 *out_process_id, const ncm::TitleLocation &loc, u32 flags) {
|
||||||
/* Ensure we only try to launch one title at a time. */
|
/* Ensure we only try to launch one title at a time. */
|
||||||
static HosMutex s_lock;
|
static HosMutex s_lock;
|
||||||
std::scoped_lock<HosMutex> lk(s_lock);
|
std::scoped_lock lk(s_lock);
|
||||||
|
|
||||||
/* Set global arguments, signal, wait. */
|
/* Set global arguments, signal, wait. */
|
||||||
g_process_launch_args = {
|
g_process_launch_args = {
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace sts::pm::dmnt {
|
||||||
class DebugMonitorService final : public DebugMonitorServiceBase {
|
class DebugMonitorService final : public DebugMonitorServiceBase {
|
||||||
private:
|
private:
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
GetExceptionProcessIdList = 0,
|
GetExceptionProcessIdList = 0,
|
||||||
StartProcess = 1,
|
StartProcess = 1,
|
||||||
GetProcessId = 2,
|
GetProcessId = 2,
|
||||||
HookToCreateProcess = 3,
|
HookToCreateProcess = 3,
|
||||||
|
@ -83,7 +83,7 @@ namespace sts::pm::dmnt {
|
||||||
private:
|
private:
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
GetModuleIdList = 0,
|
GetModuleIdList = 0,
|
||||||
GetExceptionProcessIdList = 1,
|
GetExceptionProcessIdList = 1,
|
||||||
StartProcess = 2,
|
StartProcess = 2,
|
||||||
GetProcessId = 3,
|
GetProcessId = 3,
|
||||||
HookToCreateProcess = 4,
|
HookToCreateProcess = 4,
|
||||||
|
|
|
@ -72,9 +72,9 @@ void __libnx_initheap(void) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static constexpr u32 PrivilegedFileAccessHeader[0x1C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000};
|
constexpr u32 PrivilegedFileAccessHeader[0x1C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000};
|
||||||
static constexpr u32 PrivilegedFileAccessControl[0x2C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
|
constexpr u32 PrivilegedFileAccessControl[0x2C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
|
||||||
static constexpr size_t ProcessCountMax = 0x40;
|
constexpr size_t ProcessCountMax = 0x40;
|
||||||
|
|
||||||
/* This works around a bug fixed by FS in 4.0.0. */
|
/* This works around a bug fixed by FS in 4.0.0. */
|
||||||
/* Not doing so will cause KIPs with higher process IDs than 7 to be unable to use filesystem services. */
|
/* Not doing so will cause KIPs with higher process IDs than 7 to be unable to use filesystem services. */
|
||||||
|
|
|
@ -459,6 +459,17 @@ namespace sts::sm::impl {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result WaitService(ServiceName service) {
|
||||||
|
bool has_service = false;
|
||||||
|
R_TRY(impl::HasService(&has_service, service));
|
||||||
|
|
||||||
|
/* Wait until we have the service. */
|
||||||
|
if (!has_service) {
|
||||||
|
return ResultServiceFrameworkRequestDeferredByUser;
|
||||||
|
}
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
Result GetServiceHandle(Handle *out, u64 pid, ServiceName service) {
|
Result GetServiceHandle(Handle *out, u64 pid, ServiceName service) {
|
||||||
/* Validate service name. */
|
/* Validate service name. */
|
||||||
R_TRY(ValidateServiceName(service));
|
R_TRY(ValidateServiceName(service));
|
||||||
|
@ -564,6 +575,17 @@ namespace sts::sm::impl {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result WaitMitm(ServiceName service) {
|
||||||
|
bool has_mitm = false;
|
||||||
|
R_TRY(impl::HasMitm(&has_mitm, service));
|
||||||
|
|
||||||
|
/* Wait until we have the mitm. */
|
||||||
|
if (!has_mitm) {
|
||||||
|
return ResultServiceFrameworkRequestDeferredByUser;
|
||||||
|
}
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service) {
|
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service) {
|
||||||
/* Validate service name. */
|
/* Validate service name. */
|
||||||
R_TRY(ValidateServiceName(service));
|
R_TRY(ValidateServiceName(service));
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace sts::sm::impl {
|
||||||
|
|
||||||
/* Service management. */
|
/* Service management. */
|
||||||
Result HasService(bool *out, ServiceName service);
|
Result HasService(bool *out, ServiceName service);
|
||||||
|
Result WaitService(ServiceName service);
|
||||||
Result GetServiceHandle(Handle *out, u64 pid, ServiceName service);
|
Result GetServiceHandle(Handle *out, u64 pid, ServiceName service);
|
||||||
Result RegisterService(Handle *out, u64 pid, ServiceName service, size_t max_sessions, bool is_light);
|
Result RegisterService(Handle *out, u64 pid, ServiceName service, size_t max_sessions, bool is_light);
|
||||||
Result RegisterServiceForSelf(Handle *out, ServiceName service, size_t max_sessions);
|
Result RegisterServiceForSelf(Handle *out, ServiceName service, size_t max_sessions);
|
||||||
|
@ -33,6 +34,7 @@ namespace sts::sm::impl {
|
||||||
|
|
||||||
/* Mitm extensions. */
|
/* Mitm extensions. */
|
||||||
Result HasMitm(bool *out, ServiceName service);
|
Result HasMitm(bool *out, ServiceName service);
|
||||||
|
Result WaitMitm(ServiceName service);
|
||||||
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service);
|
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service);
|
||||||
Result UninstallMitm(u64 pid, ServiceName service);
|
Result UninstallMitm(u64 pid, ServiceName service);
|
||||||
Result AcknowledgeMitmSession(u64 *out_pid, Handle *out_hnd, u64 pid, ServiceName service);
|
Result AcknowledgeMitmSession(u64 *out_pid, Handle *out_hnd, u64 pid, ServiceName service);
|
||||||
|
|
|
@ -75,9 +75,19 @@ namespace sts::sm {
|
||||||
return impl::HasMitm(out.GetPointer(), service);
|
return impl::HasMitm(out.GetPointer(), service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result UserService::AtmosphereWaitMitm(ServiceName service) {
|
||||||
|
R_TRY(this->EnsureInitialized());
|
||||||
|
return impl::WaitMitm(service);
|
||||||
|
}
|
||||||
|
|
||||||
Result UserService::AtmosphereHasService(Out<bool> out, ServiceName service) {
|
Result UserService::AtmosphereHasService(Out<bool> out, ServiceName service) {
|
||||||
R_TRY(this->EnsureInitialized());
|
R_TRY(this->EnsureInitialized());
|
||||||
return impl::HasService(out.GetPointer(), service);
|
return impl::HasService(out.GetPointer(), service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result UserService::AtmosphereWaitService(ServiceName service) {
|
||||||
|
R_TRY(this->EnsureInitialized());
|
||||||
|
return impl::WaitService(service);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,10 @@ namespace sts::sm {
|
||||||
AtmosphereAssociatePidTidForMitm = 65002,
|
AtmosphereAssociatePidTidForMitm = 65002,
|
||||||
AtmosphereAcknowledgeMitmSession = 65003,
|
AtmosphereAcknowledgeMitmSession = 65003,
|
||||||
AtmosphereHasMitm = 65004,
|
AtmosphereHasMitm = 65004,
|
||||||
|
AtmosphereWaitMitm = 65005,
|
||||||
|
|
||||||
AtmosphereHasService = 65100,
|
AtmosphereHasService = 65100,
|
||||||
|
AtmosphereWaitService = 65101,
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
u64 pid = InvalidProcessId;
|
u64 pid = InvalidProcessId;
|
||||||
|
@ -57,8 +59,10 @@ namespace sts::sm {
|
||||||
virtual Result AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid);
|
virtual Result AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid);
|
||||||
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service);
|
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service);
|
||||||
virtual Result AtmosphereHasMitm(Out<bool> out, ServiceName service);
|
virtual Result AtmosphereHasMitm(Out<bool> out, ServiceName service);
|
||||||
|
virtual Result AtmosphereWaitMitm(ServiceName service);
|
||||||
|
|
||||||
virtual Result AtmosphereHasService(Out<bool> out, ServiceName service);
|
virtual Result AtmosphereHasService(Out<bool> out, ServiceName service);
|
||||||
|
virtual Result AtmosphereWaitService(ServiceName service);
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, Initialize),
|
MAKE_SERVICE_COMMAND_META(UserService, Initialize),
|
||||||
|
@ -71,8 +75,10 @@ namespace sts::sm {
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAssociatePidTidForMitm),
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAssociatePidTidForMitm),
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAcknowledgeMitmSession),
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAcknowledgeMitmSession),
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasMitm),
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasMitm),
|
||||||
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereWaitMitm),
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasService),
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasService),
|
||||||
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereWaitService),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue