From 63d183042928fb75f163d7f283fb00743bfb00b8 Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Tue, 14 Nov 2023 10:33:58 +0100 Subject: [PATCH] Download TWL titles from NUS and list them in AM. (#7162) * Download TWL titles from NUS and list them in AM. * Remove duplicate entries. * Move TODO comment --- src/core/hle/service/am/am.cpp | 18 +++++++++++++++--- src/core/hle/service/am/am.h | 2 ++ src/core/system_titles.cpp | 32 +++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index ad463631f..b0cc00b11 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -646,6 +646,8 @@ std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, std: } std::string GetTitlePath(Service::FS::MediaType media_type, u64 tid) { + // TODO(PabloMK7) TWL titles should be in TWL Nand. Assuming CTR Nand for now. + u32 high = static_cast(tid >> 32); u32 low = static_cast(tid & 0xFFFFFFFF); @@ -698,9 +700,19 @@ void Module::ScanForTitles(Service::FS::MediaType media_type) { if (tid_string.length() == TITLE_ID_VALID_LENGTH) { const u64 tid = std::stoull(tid_string, nullptr, 16); - FileSys::NCCHContainer container(GetTitleContentPath(media_type, tid)); - if (container.Load() == Loader::ResultStatus::Success) - am_title_list[static_cast(media_type)].push_back(tid); + if (tid & TWL_TITLE_ID_FLAG) { + // TODO(PabloMK7) Move to TWL Nand, for now only check that + // the contents exists in CTR Nand as this is a SRL file + // instead of NCCH. + if (FileUtil::Exists(GetTitleContentPath(media_type, tid))) { + am_title_list[static_cast(media_type)].push_back(tid); + } + } else { + FileSys::NCCHContainer container(GetTitleContentPath(media_type, tid)); + if (container.Load() == Loader::ResultStatus::Success) { + am_title_list[static_cast(media_type)].push_back(tid); + } + } } } } diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 54749b212..7682e48a7 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -68,6 +68,8 @@ enum class InstallStatus : u32 { // Title ID valid length constexpr std::size_t TITLE_ID_VALID_LENGTH = 16; +constexpr u64 TWL_TITLE_ID_FLAG = 0x0000800000000000ULL; + // Progress callback for InstallCIA, receives bytes written and total bytes using ProgressCallback = void(std::size_t, std::size_t); diff --git a/src/core/system_titles.cpp b/src/core/system_titles.cpp index a0a8bd8ae..54c861b5d 100644 --- a/src/core/system_titles.cpp +++ b/src/core/system_titles.cpp @@ -21,7 +21,7 @@ struct SystemTitleCategory { std::vector titles; }; -static constexpr u32 NUM_SYSTEM_TITLE_CATEGORIES = 7; +static constexpr u32 NUM_SYSTEM_TITLE_CATEGORIES = 9; static constexpr u64 home_menu_title_id_high = 0x00040030; static constexpr SystemTitle home_menu_title = { @@ -1130,6 +1130,36 @@ static const std::array 0x20000202, 0x20000202, 0x20000202}, }, }}, + {.name = "TWL System Applications", + .title_id_high = 0x00048005, + .titles = + { + { + .name = "DS Internet", + .title_id_lows = {0x42383841, 0x42383841, 0x42383841, 0x42383841, + 0x42383841, 0x42383841, 0x42383841}, + }, + { + .name = "DS Download Play", + .title_id_lows = {0x484E4441, 0x484E4441, 0x484E4441, 0x484E4441, + 0x484E4443, 0x484E444B, 0x484E4441}, + }, + }}, + {.name = "TWL System Data Archives", + .title_id_high = 0x0004800F, + .titles = + { + { + .name = "DS Card Whitelist", + .title_id_lows = {0x484E4841, 0x484E4841, 0x484E4841, 0x484E4841, + 0x484E4841, 0x484E4841, 0x484E4841}, + }, + { + .name = "DS Version Data", + .title_id_lows = {0x484E4C41, 0x484E4C41, 0x484E4C41, 0x484E4C41, + 0x484E4C41, 0x484E4C41, 0x484E4C41}, + }, + }}, }}; std::vector GetSystemTitleIds(SystemTitleSet set, u32 region) {