diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index f4726c18c..702e4dc0e 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -211,6 +211,31 @@ Result ContentManagement::RedirectContentPathForTidSid(const char *path, Registr return RedirectContentPath(path, tid_sid->title_id, tid_sid->storage_id); } +void ContentManagement::RedirectHtmlDocumentPathForHbl(u64 tid, FsStorageId sid) { + LrLocationResolver lr; + char path[FS_MAX_PATH] = {0}; + + /* Open resolver. */ + if (R_FAILED(lrOpenLocationResolver(sid, &lr))) { + return; + } + + /* Ensure close on exit. */ + ON_SCOPE_EXIT { serviceClose(&lr.s); }; + + /* Only redirect the HTML document path if there is not one already. */ + if (R_SUCCEEDED(lrLrResolveApplicationHtmlDocumentPath(&lr, tid, path))) { + return; + } + + /* We just need to set this to any valid NCA path. Let's use the executable path. */ + if (R_FAILED(lrLrResolveProgramPath(&lr, tid, path))) { + return; + } + + lrLrRedirectApplicationHtmlDocumentPath(&lr, tid, path); +} + bool ContentManagement::HasCreatedTitle(u64 tid) { return std::find(g_created_titles.begin(), g_created_titles.end(), tid) != g_created_titles.end(); } diff --git a/stratosphere/loader/source/ldr_content_management.hpp b/stratosphere/loader/source/ldr_content_management.hpp index 60b01d7e2..69d02c8ca 100644 --- a/stratosphere/loader/source/ldr_content_management.hpp +++ b/stratosphere/loader/source/ldr_content_management.hpp @@ -36,12 +36,14 @@ class ContentManagement { static Result RedirectContentPath(const char *path, u64 tid, FsStorageId sid); static Result ResolveContentPathForTidSid(char *out_path, Registration::TidSid *tid_sid); static Result RedirectContentPathForTidSid(const char *path, Registration::TidSid *tid_sid); - + + static void RedirectHtmlDocumentPathForHbl(u64 tid, FsStorageId sid); + static bool HasCreatedTitle(u64 tid); static void SetCreatedTitle(u64 tid); static void RefreshConfigurationData(); static void TryMountSdCard(); - + static OverrideKey GetTitleOverrideKey(u64 tid); static bool ShouldOverrideContentsWithSD(u64 tid); static bool ShouldOverrideContentsWithHBL(u64 tid); diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index 76f9c85e2..8d861da64 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -221,10 +221,16 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc /* Send the pid/tid pair to anyone interested in man-in-the-middle-attacking it. */ Registration::AssociatePidTidForMitM(index); - rc = 0; + rc = 0; + + /* If HBL, override HTML document path. */ + if (ContentManagement::ShouldOverrideContentsWithHBL(target_process->tid_sid.title_id)) { + ContentManagement::RedirectHtmlDocumentPathForHbl(target_process->tid_sid.title_id, target_process->tid_sid.storage_id); + } /* ECS is a one-shot operation, but we don't clear on failure. */ ContentManagement::ClearExternalContentSource(target_process->tid_sid.title_id); + if (mounted_code) { if (R_SUCCEEDED(rc) && target_process->tid_sid.storage_id != FsStorageId_None) { rc = ContentManagement::UnmountCode();