From c91ccbd0ba4118554d7377bbc3bd4c64f9bccf84 Mon Sep 17 00:00:00 2001 From: Max Thomas Date: Mon, 25 Sep 2017 00:17:38 -0600 Subject: Loader/NCCH: Add support for loading application updates (#2927) * loader/ncch: split NCCH parsing into its own file * loader/ncch: add support for loading update NCCHs from the SD card * loader/ncch: fix formatting * file_sys/ncch_container: Return a value for OpenFile * loader/ncch: cleanup, always instantiate overlay_ncch to base_ncch * file_sys/ncch_container: better encryption checks, allow non-app NCCHs to load properly and for the existence of NCCH structures to be checked * file_sys/ncch_container: pass filepath as a const reference --- src/core/file_sys/archive_selfncch.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'src/core/file_sys/archive_selfncch.cpp') diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index 298a37a44..7dc91a405 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp @@ -102,8 +102,7 @@ public: switch (static_cast(file_path.type)) { case SelfNCCHFilePathType::UpdateRomFS: - LOG_WARNING(Service_FS, "(STUBBED) open update RomFS"); - return OpenRomFS(); + return OpenUpdateRomFS(); case SelfNCCHFilePathType::RomFS: return OpenRomFS(); @@ -179,6 +178,17 @@ private: } } + ResultVal> OpenUpdateRomFS() const { + if (ncch_data.update_romfs_file) { + return MakeResult>(std::make_unique( + ncch_data.update_romfs_file, ncch_data.update_romfs_offset, + ncch_data.update_romfs_size)); + } else { + LOG_INFO(Service_FS, "Unable to read update RomFS"); + return ERROR_ROMFS_NOT_FOUND; + } + } + ResultVal> OpenExeFS(const std::string& filename) const { if (filename == "icon") { if (ncch_data.icon) { @@ -218,11 +228,19 @@ private: }; ArchiveFactory_SelfNCCH::ArchiveFactory_SelfNCCH(Loader::AppLoader& app_loader) { - std::shared_ptr romfs_file_; + std::shared_ptr romfs_file; + if (Loader::ResultStatus::Success == + app_loader.ReadRomFS(romfs_file, ncch_data.romfs_offset, ncch_data.romfs_size)) { + + ncch_data.romfs_file = std::move(romfs_file); + } + + std::shared_ptr update_romfs_file; if (Loader::ResultStatus::Success == - app_loader.ReadRomFS(romfs_file_, ncch_data.romfs_offset, ncch_data.romfs_size)) { + app_loader.ReadUpdateRomFS(update_romfs_file, ncch_data.update_romfs_offset, + ncch_data.update_romfs_size)) { - ncch_data.romfs_file = std::move(romfs_file_); + ncch_data.update_romfs_file = std::move(update_romfs_file); } std::vector buffer; -- cgit v1.2.3 From 774e7deae8655a6f09530770c56ae2e75d55309b Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 23 Sep 2017 20:32:18 -0500 Subject: HLE/Archives: Allow multiple loaded applications to access their SelfNCCH archive independently. The loaders now register each loaded ROM with the SelfNCCH factory, which keeps the data around for the duration of the emulation session. When opening the SelfNCCH archive, the factory queries the current program's programid and uses that as a key to the map that contains the NCCHData structure (RomFS, Icon, Banner, etc). 3dsx files do not have a programid and will use a default of 0 for this value, thus, only 1 3dsx file with RomFS is loadable at the same time. --- src/core/file_sys/archive_selfncch.cpp | 43 +++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'src/core/file_sys/archive_selfncch.cpp') diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index 7dc91a405..a16941c70 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp @@ -3,12 +3,14 @@ // Refer to the license.txt file included. #include +#include #include "common/common_types.h" #include "common/logging/log.h" #include "common/swap.h" #include "core/file_sys/archive_selfncch.h" #include "core/file_sys/errors.h" #include "core/file_sys/ivfc_archive.h" +#include "core/hle/kernel/process.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace @@ -227,38 +229,57 @@ private: NCCHData ncch_data; }; -ArchiveFactory_SelfNCCH::ArchiveFactory_SelfNCCH(Loader::AppLoader& app_loader) { - std::shared_ptr romfs_file; +void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) { + u64 program_id = 0; + if (app_loader.ReadProgramId(program_id) != Loader::ResultStatus::Success) { + LOG_WARNING( + Service_FS, + "Could not read program id when registering with SelfNCCH, this might be a 3dsx file"); + } + + LOG_DEBUG(Service_FS, "Registering program %016" PRIX64 " with the SelfNCCH archive factory", + program_id); + + if (ncch_data.find(program_id) != ncch_data.end()) { + LOG_WARNING(Service_FS, "Registering program %016" PRIX64 + " with SelfNCCH will override existing mapping", + program_id); + } + + NCCHData& data = ncch_data[program_id]; + + std::shared_ptr romfs_file_; if (Loader::ResultStatus::Success == - app_loader.ReadRomFS(romfs_file, ncch_data.romfs_offset, ncch_data.romfs_size)) { + app_loader.ReadRomFS(romfs_file_, data.romfs_offset, data.romfs_size)) { - ncch_data.romfs_file = std::move(romfs_file); + data.romfs_file = std::move(romfs_file_); } std::shared_ptr update_romfs_file; if (Loader::ResultStatus::Success == - app_loader.ReadUpdateRomFS(update_romfs_file, ncch_data.update_romfs_offset, - ncch_data.update_romfs_size)) { + app_loader.ReadUpdateRomFS(update_romfs_file, data.update_romfs_offset, + data.update_romfs_size)) { - ncch_data.update_romfs_file = std::move(update_romfs_file); + data.update_romfs_file = std::move(update_romfs_file); } std::vector buffer; if (Loader::ResultStatus::Success == app_loader.ReadIcon(buffer)) - ncch_data.icon = std::make_shared>(std::move(buffer)); + data.icon = std::make_shared>(std::move(buffer)); buffer.clear(); if (Loader::ResultStatus::Success == app_loader.ReadLogo(buffer)) - ncch_data.logo = std::make_shared>(std::move(buffer)); + data.logo = std::make_shared>(std::move(buffer)); buffer.clear(); if (Loader::ResultStatus::Success == app_loader.ReadBanner(buffer)) - ncch_data.banner = std::make_shared>(std::move(buffer)); + data.banner = std::make_shared>(std::move(buffer)); } ResultVal> ArchiveFactory_SelfNCCH::Open(const Path& path) { - auto archive = std::make_unique(ncch_data); + auto archive = std::make_unique( + ncch_data[Kernel::g_current_process->codeset->program_id]); return MakeResult>(std::move(archive)); } -- cgit v1.2.3