diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index 4424441..9b7a761 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -19,6 +19,10 @@ 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 @@ 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 dded739..8fee7b5 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 b8f9c71..07cd225 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -93,6 +93,7 @@ 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 @@ 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 @@ 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 55511f5..66ab530 100644 --- a/stratosphere/loader/source/ldr_process_manager.cpp +++ b/stratosphere/loader/source/ldr_process_manager.cpp @@ -111,17 +111,21 @@ 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(); }