diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index 4424441e1..9b7a76194 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -19,6 +19,10 @@ Result ContentManagement::MountCode(u64 tid, FsStorageId sid) { if (!g_has_initialized_fs_dev) { TryMountSdCard(); } + + if (kernelAbove200() && g_has_initialized_fs_dev && R_SUCCEEDED(MountCodeNspOnSd(tid))) { + return 0x0; + } if (R_FAILED(rc = ResolveContentPath(path, tid, sid))) { @@ -53,6 +57,18 @@ Result ContentManagement::UnmountCode() { return 0; } +Result ContentManagement::MountCodeNspOnSd(u64 tid) { + char path[FS_MAX_PATH+1] = {0}; + snprintf(path, FS_MAX_PATH, "sdmc:/atmosphere/titles/%016lx/exefs.nsp", tid); + Result rc = fsOpenFileSystemWithId(&g_CodeFileSystem, 0, FsFileSystemType_ApplicationPackage, path); + + if (R_SUCCEEDED(rc)) { + fsdevMountDevice("code", g_CodeFileSystem); + } + + return rc; +} + Result ContentManagement::MountCodeForTidSid(Registration::TidSid *tid_sid) { return MountCode(tid_sid->title_id, tid_sid->storage_id); } diff --git a/stratosphere/loader/source/ldr_content_management.hpp b/stratosphere/loader/source/ldr_content_management.hpp index dded7398e..8fee7b5ac 100644 --- a/stratosphere/loader/source/ldr_content_management.hpp +++ b/stratosphere/loader/source/ldr_content_management.hpp @@ -6,6 +6,7 @@ class ContentManagement { public: static Result MountCode(u64 tid, FsStorageId sid); + static Result MountCodeNspOnSd(u64 tid); static Result UnmountCode(); static Result MountCodeForTidSid(Registration::TidSid *tid_sid); diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index b8f9c71c4..07cd225a6 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -93,6 +93,7 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc Registration::Process *target_process; Handle process_h = 0; u64 process_id = 0; + bool mounted_code = false; Result rc; /* Get the process from the registration queue. */ @@ -107,6 +108,11 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc if (R_FAILED(rc)) { return rc; } + mounted_code = true; + } else { + if (R_SUCCEEDED(ContentManagement::MountCodeNspOnSd(target_process->tid_sid.title_id))) { + mounted_code = true; + } } /* Load the process's NPDM. */ @@ -193,10 +199,12 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc rc = 0; CREATE_PROCESS_END: - if (R_SUCCEEDED(rc) && target_process->tid_sid.storage_id != FsStorageId_None) { - rc = ContentManagement::UnmountCode(); - } else { - ContentManagement::UnmountCode(); + if (mounted_code) { + if (R_SUCCEEDED(rc) && target_process->tid_sid.storage_id != FsStorageId_None) { + rc = ContentManagement::UnmountCode(); + } else { + ContentManagement::UnmountCode(); + } } if (R_SUCCEEDED(rc)) { *out_process_h = process_h; diff --git a/stratosphere/loader/source/ldr_process_manager.cpp b/stratosphere/loader/source/ldr_process_manager.cpp index 55511f56c..66ab5308b 100644 --- a/stratosphere/loader/source/ldr_process_manager.cpp +++ b/stratosphere/loader/source/ldr_process_manager.cpp @@ -111,17 +111,21 @@ std::tuple ProcessManagerService::unregister_title(u64 index) { Result ProcessManagerService::populate_program_info_buffer(ProcessManagerService::ProgramInfo *out, Registration::TidSid *tid_sid) { NpdmUtils::NpdmInfo info; Result rc; + bool mounted_code = false; if (tid_sid->storage_id != FsStorageId_None) { rc = ContentManagement::MountCodeForTidSid(tid_sid); if (R_FAILED(rc)) { return rc; } + mounted_code = true; + } else if (R_SUCCEEDED(ContentManagement::MountCodeNspOnSd(tid_sid->title_id))) { + mounted_code = true; } rc = NpdmUtils::LoadNpdm(tid_sid->title_id, &info); - if (tid_sid->storage_id != FsStorageId_None) { + if (mounted_code) { ContentManagement::UnmountCode(); }