From 9e88f03e7591bd3b91d7af9b9995a727c0b92ac9 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 28 Jul 2018 12:32:16 -0400 Subject: Avoid parsing RomFS to directory in NCA --- src/core/file_sys/control_metadata.h | 7 +++ src/core/loader/deconstructed_rom_directory.cpp | 68 ++++++++++++++++++++++++- src/core/loader/deconstructed_rom_directory.h | 7 +++ src/core/loader/loader.cpp | 2 +- src/core/loader/loader.h | 2 +- src/core/loader/nca.cpp | 4 +- src/core/loader/nca.h | 2 + 7 files changed, 86 insertions(+), 6 deletions(-) (limited to 'src/core') diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index cc3b745f7..9fc02612a 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h @@ -62,6 +62,13 @@ enum class Language : u8 { Chinese = 14, }; +static std::array LANGUAGE_NAMES = { + "AmericanEnglish", "BritishEnglish", "Japanese", + "French", "German", "LatinAmericanSpanish", + "Spanish", "Italian", "Dutch", + "CanadianFrench", "Portugese", "Russian", + "Korean", "Taiwanese", "Chinese"}; + // A class representing the format used by NX metadata files, typically named Control.nacp. // These store application name, dev name, title id, and other miscellaneous data. class NACP { diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 076927dff..cc88a44b6 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -7,6 +7,7 @@ #include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/content_archive.h" +#include "core/file_sys/control_metadata.h" #include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" @@ -17,8 +18,50 @@ namespace Loader { -AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file) - : AppLoader(std::move(file)) {} +AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_) + : AppLoader(std::move(file_)) { + const auto dir = file->GetContainingDirectory(); + + // Icon + FileSys::VirtualFile icon_file = nullptr; + for (const auto& language : FileSys::LANGUAGE_NAMES) { + icon_file = dir->GetFile("icon_" + language + ".dat"); + if (icon_file != nullptr) { + icon_data = icon_file->ReadAllBytes(); + break; + } + } + + if (icon_data.empty()) { + // Any png, jpeg, or bmp file + const auto& files = dir->GetFiles(); + const auto icon_iter = + std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { + return file->GetExtension() == "png" || file->GetExtension() == "jpg" || + file->GetExtension() == "bmp" || file->GetExtension() == "jpeg"; + }); + if (icon_iter != files.end()) + icon_data = (*icon_iter)->ReadAllBytes(); + } + + // Metadata + FileSys::VirtualFile nacp_file = dir->GetFile("control.nacp"); + if (nacp_file == nullptr) { + const auto& files = dir->GetFiles(); + const auto nacp_iter = + std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { + return file->GetExtension() == "nacp"; + }); + if (nacp_iter != files.end()) + nacp_file = *nacp_iter; + } + + if (nacp_file != nullptr) { + FileSys::NACP nacp(nacp_file); + title_id = nacp.GetTitleId(); + name = nacp.GetApplicationName(); + } +} AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory( FileSys::VirtualDir directory) @@ -105,4 +148,25 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile return ResultStatus::Success; } +ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector& buffer) { + if (icon_data.empty()) + return ResultStatus::ErrorNotUsed; + buffer = icon_data; + return ResultStatus::Success; +} + +ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program_id) { + if (name.empty()) + return ResultStatus::ErrorNotUsed; + out_program_id = title_id; + return ResultStatus::Success; +} + +ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) { + if (name.empty()) + return ResultStatus::ErrorNotUsed; + title = name; + return ResultStatus::Success; +} + } // namespace Loader diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 7d5433563..b20804f75 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h @@ -39,11 +39,18 @@ public: ResultStatus Load(Kernel::SharedPtr& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; + ResultStatus ReadIcon(std::vector& buffer) override; + ResultStatus ReadProgramId(u64& out_program_id) override; + ResultStatus ReadTitle(std::string& title) override; private: FileSys::ProgramMetadata metadata; FileSys::VirtualFile romfs; FileSys::VirtualDir dir; + + std::vector icon_data; + std::string name; + u64 title_id{}; }; } // namespace Loader diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 57e6c0365..0781fb8c1 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -68,7 +68,7 @@ FileType GuessFromFilename(const std::string& name) { return FileType::Unknown; } -const char* GetFileTypeString(FileType type) { +std::string GetFileTypeString(FileType type) { switch (type) { case FileType::ELF: return "ELF"; diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index e69ab85ef..7bd0adedb 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -61,7 +61,7 @@ FileType GuessFromFilename(const std::string& name); /** * Convert a FileType into a string which can be displayed to the user. */ -const char* GetFileTypeString(FileType type); +std::string GetFileTypeString(FileType type); /// Return type for functions in Loader namespace enum class ResultStatus { diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index dbc67c0b5..46f5cd393 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -77,8 +77,8 @@ ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { } ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { - if (nca == nullptr) - return ResultStatus::ErrorNotLoaded; + if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) + return ResultStatus::ErrorInvalidFormat; out_program_id = nca->GetTitleId(); return ResultStatus::Success; } diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index 0fd2d0417..443bc1202 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -33,6 +33,7 @@ public: ResultStatus Load(Kernel::SharedPtr& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; + ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadProgramId(u64& out_program_id) override; @@ -41,6 +42,7 @@ public: private: FileSys::ProgramMetadata metadata; + FileSys::NCAHeader header; std::unique_ptr nca; std::unique_ptr directory_loader; }; -- cgit v1.2.3