aboutsummaryrefslogtreecommitdiff
path: root/src/core/loader
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/loader')
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp85
-rw-r--r--src/core/loader/deconstructed_rom_directory.h11
-rw-r--r--src/core/loader/elf.cpp2
-rw-r--r--src/core/loader/loader.cpp55
-rw-r--r--src/core/loader/loader.h58
-rw-r--r--src/core/loader/nca.cpp56
-rw-r--r--src/core/loader/nca.h4
-rw-r--r--src/core/loader/nro.cpp10
-rw-r--r--src/core/loader/xci.cpp40
-rw-r--r--src/core/loader/xci.h5
10 files changed, 244 insertions, 82 deletions
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index b0277a875..de05f21d8 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,54 @@
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_" + std::string(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)
+ : AppLoader(directory->GetFile("main")), dir(std::move(directory)) {}
FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) {
if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) {
@@ -34,10 +81,15 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
return ResultStatus::ErrorAlreadyLoaded;
}
- const FileSys::VirtualDir dir = file->GetContainingDirectory();
+ if (dir == nullptr) {
+ if (file == nullptr)
+ return ResultStatus::ErrorNullFile;
+ dir = file->GetContainingDirectory();
+ }
+
const FileSys::VirtualFile npdm = dir->GetFile("main.npdm");
if (npdm == nullptr)
- return ResultStatus::ErrorInvalidFormat;
+ return ResultStatus::ErrorMissingNPDM;
ResultStatus result = metadata.Load(npdm);
if (result != ResultStatus::Success) {
@@ -47,7 +99,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};
if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) {
- return ResultStatus::ErrorUnsupportedArch;
+ return ResultStatus::Error32BitISA;
}
// Load NSO modules
@@ -91,9 +143,30 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) {
if (romfs == nullptr)
- return ResultStatus::ErrorNotUsed;
+ return ResultStatus::ErrorNoRomFS;
dir = romfs;
return ResultStatus::Success;
}
+ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& buffer) {
+ if (icon_data.empty())
+ return ResultStatus::ErrorNoIcon;
+ buffer = icon_data;
+ return ResultStatus::Success;
+}
+
+ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program_id) {
+ if (name.empty())
+ return ResultStatus::ErrorNoControl;
+ out_program_id = title_id;
+ return ResultStatus::Success;
+}
+
+ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) {
+ if (name.empty())
+ return ResultStatus::ErrorNoControl;
+ 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 7319ba6ea..b20804f75 100644
--- a/src/core/loader/deconstructed_rom_directory.h
+++ b/src/core/loader/deconstructed_rom_directory.h
@@ -22,6 +22,9 @@ class AppLoader_DeconstructedRomDirectory final : public AppLoader {
public:
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file);
+ // Overload to accept exefs directory. Must contain 'main' and 'main.npdm'
+ explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory);
+
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
@@ -36,10 +39,18 @@ public:
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
+ ResultStatus ReadIcon(std::vector<u8>& 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<u8> icon_data;
+ std::string name;
+ u64 title_id{};
};
} // namespace Loader
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index a7133f5a6..401cad3ab 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -390,7 +390,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
std::vector<u8> buffer = file->ReadAllBytes();
if (buffer.size() != file->GetSize())
- return ResultStatus::Error;
+ return ResultStatus::ErrorIncorrectELFFileSize;
ElfReader elf_reader(&buffer[0]);
SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR);
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 57e6c0365..1f2f31535 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -43,10 +43,6 @@ FileType IdentifyFile(FileSys::VirtualFile file) {
return FileType::Unknown;
}
-FileType IdentifyFile(const std::string& file_name) {
- return IdentifyFile(std::make_shared<FileSys::RealVfsFile>(file_name));
-}
-
FileType GuessFromFilename(const std::string& name) {
if (name == "main")
return FileType::DeconstructedRomDirectory;
@@ -68,7 +64,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";
@@ -90,6 +86,55 @@ const char* GetFileTypeString(FileType type) {
return "unknown";
}
+constexpr std::array<const char*, 36> RESULT_MESSAGES{
+ "The operation completed successfully.",
+ "The loader requested to load is already loaded.",
+ "The operation is not implemented.",
+ "The loader is not initialized properly.",
+ "The NPDM file has a bad header.",
+ "The NPDM has a bad ACID header.",
+ "The NPDM has a bad ACI header,",
+ "The NPDM file has a bad file access control.",
+ "The NPDM has a bad file access header.",
+ "The PFS/HFS partition has a bad header.",
+ "The PFS/HFS partition has incorrect size as determined by the header.",
+ "The NCA file has a bad header.",
+ "The general keyfile could not be found.",
+ "The NCA Header key could not be found.",
+ "The NCA Header key is incorrect or the header is invalid.",
+ "Support for NCA2-type NCAs is not implemented.",
+ "Support for NCA0-type NCAs is not implemented.",
+ "The titlekey for this Rights ID could not be found.",
+ "The titlekek for this crypto revision could not be found.",
+ "The Rights ID in the header is invalid.",
+ "The key area key for this application type and crypto revision could not be found.",
+ "The key area key is incorrect or the section header is invalid.",
+ "The titlekey and/or titlekek is incorrect or the section header is invalid.",
+ "The XCI file is missing a Program-type NCA.",
+ "The NCA file is not an application.",
+ "The ExeFS partition could not be found.",
+ "The XCI file has a bad header.",
+ "The XCI file is missing a partition.",
+ "The file could not be found or does not exist.",
+ "The game is missing a program metadata file (main.npdm).",
+ "The game uses the currently-unimplemented 32-bit architecture.",
+ "The RomFS could not be found.",
+ "The ELF file has incorrect size as determined by the header.",
+ "There was a general error loading the NRO into emulated memory.",
+ "There is no icon available.",
+ "There is no control data available.",
+};
+
+std::string GetMessageForResultStatus(ResultStatus status) {
+ return GetMessageForResultStatus(static_cast<u16>(status));
+}
+
+std::string GetMessageForResultStatus(u16 status) {
+ if (status >= 36)
+ return "";
+ return RESULT_MESSAGES[status];
+}
+
/**
* Get a loader for a file with a specific type
* @param file The file to load
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index e69ab85ef..285363549 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -43,14 +43,6 @@ enum class FileType {
FileType IdentifyFile(FileSys::VirtualFile file);
/**
- * Identifies the type of a bootable file based on the magic value in its header.
- * @param file_name path to file
- * @return FileType of file. Note: this will return FileType::Unknown if it is unable to determine
- * a filetype, and will never return FileType::Error.
- */
-FileType IdentifyFile(const std::string& file_name);
-
-/**
* Guess the type of a bootable file from its name
* @param name String name of bootable file
* @return FileType of file. Note: this will return FileType::Unknown if it is unable to determine
@@ -61,23 +53,51 @@ 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 {
+enum class ResultStatus : u16 {
Success,
- Error,
- ErrorInvalidFormat,
- ErrorNotImplemented,
- ErrorNotLoaded,
- ErrorNotUsed,
ErrorAlreadyLoaded,
- ErrorMemoryAllocationFailed,
- ErrorMissingKeys,
- ErrorDecrypting,
- ErrorUnsupportedArch,
+ ErrorNotImplemented,
+ ErrorNotInitialized,
+ ErrorBadNPDMHeader,
+ ErrorBadACIDHeader,
+ ErrorBadACIHeader,
+ ErrorBadFileAccessControl,
+ ErrorBadFileAccessHeader,
+ ErrorBadPFSHeader,
+ ErrorIncorrectPFSFileSize,
+ ErrorBadNCAHeader,
+ ErrorMissingProductionKeyFile,
+ ErrorMissingHeaderKey,
+ ErrorIncorrectHeaderKey,
+ ErrorNCA2,
+ ErrorNCA0,
+ ErrorMissingTitlekey,
+ ErrorMissingTitlekek,
+ ErrorInvalidRightsID,
+ ErrorMissingKeyAreaKey,
+ ErrorIncorrectKeyAreaKey,
+ ErrorIncorrectTitlekeyOrTitlekek,
+ ErrorXCIMissingProgramNCA,
+ ErrorNCANotProgram,
+ ErrorNoExeFS,
+ ErrorBadXCIHeader,
+ ErrorXCIMissingPartition,
+ ErrorNullFile,
+ ErrorMissingNPDM,
+ Error32BitISA,
+ ErrorNoRomFS,
+ ErrorIncorrectELFFileSize,
+ ErrorLoadingNRO,
+ ErrorNoIcon,
+ ErrorNoControl,
};
+std::string GetMessageForResultStatus(ResultStatus status);
+std::string GetMessageForResultStatus(u16 status);
+
/// Interface for loading an application
class AppLoader : NonCopyable {
public:
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index a1f8235d1..8498cc94b 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -22,7 +22,8 @@
namespace Loader {
-AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {}
+AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_)
+ : AppLoader(std::move(file_)), nca(std::make_unique<FileSys::NCA>(file)) {}
FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) {
FileSys::NCA nca(file);
@@ -39,53 +40,24 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
return ResultStatus::ErrorAlreadyLoaded;
}
- nca = std::make_unique<FileSys::NCA>(file);
- ResultStatus result = nca->GetStatus();
+ const auto result = nca->GetStatus();
if (result != ResultStatus::Success) {
return result;
}
if (nca->GetType() != FileSys::NCAContentType::Program)
- return ResultStatus::ErrorInvalidFormat;
+ return ResultStatus::ErrorNCANotProgram;
- auto exefs = nca->GetExeFS();
+ const auto exefs = nca->GetExeFS();
if (exefs == nullptr)
- return ResultStatus::ErrorInvalidFormat;
+ return ResultStatus::ErrorNoExeFS;
- result = metadata.Load(exefs->GetFile("main.npdm"));
- if (result != ResultStatus::Success) {
- return result;
- }
- metadata.Print();
-
- const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};
- if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) {
- return ResultStatus::ErrorUnsupportedArch;
- }
-
- VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
- for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
- "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
- const VAddr load_addr = next_load_addr;
-
- next_load_addr = AppLoader_NSO::LoadModule(exefs->GetFile(module), load_addr);
- if (next_load_addr) {
- LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
- // Register module with GDBStub
- GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
- } else {
- next_load_addr = load_addr;
- }
- }
+ directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs);
- process->program_id = metadata.GetTitleID();
- process->svc_access_mask.set();
- process->address_mappings = default_address_mappings;
- process->resource_limit =
- Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(),
- metadata.GetMainThreadStackSize());
+ const auto load_result = directory_loader->Load(process);
+ if (load_result != ResultStatus::Success)
+ return load_result;
if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0)
Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this));
@@ -97,16 +69,16 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) {
if (nca == nullptr)
- return ResultStatus::ErrorNotLoaded;
+ return ResultStatus::ErrorNotInitialized;
if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0)
- return ResultStatus::ErrorNotUsed;
+ return ResultStatus::ErrorNoRomFS;
dir = nca->GetRomFS();
return ResultStatus::Success;
}
ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) {
- if (nca == nullptr)
- return ResultStatus::ErrorNotLoaded;
+ if (nca == nullptr || nca->GetStatus() != ResultStatus::Success)
+ return ResultStatus::ErrorNotInitialized;
out_program_id = nca->GetTitleId();
return ResultStatus::Success;
}
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h
index e14d618b3..7f7d8ea0b 100644
--- a/src/core/loader/nca.h
+++ b/src/core/loader/nca.h
@@ -10,6 +10,7 @@
#include "core/file_sys/program_metadata.h"
#include "core/hle/kernel/object.h"
#include "core/loader/loader.h"
+#include "deconstructed_rom_directory.h"
namespace Loader {
@@ -32,7 +33,6 @@ public:
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
-
ResultStatus ReadProgramId(u64& out_program_id) override;
~AppLoader_NCA();
@@ -40,7 +40,9 @@ public:
private:
FileSys::ProgramMetadata metadata;
+ FileSys::NCAHeader header;
std::unique_ptr<FileSys::NCA> nca;
+ std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader;
};
} // namespace Loader
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index dc053cdad..908d91eab 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -182,7 +182,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR};
if (!LoadNro(file, base_addr)) {
- return ResultStatus::ErrorInvalidFormat;
+ return ResultStatus::ErrorLoadingNRO;
}
process->svc_access_mask.set();
@@ -197,7 +197,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) {
if (icon_data.empty()) {
- return ResultStatus::ErrorNotUsed;
+ return ResultStatus::ErrorNoIcon;
}
buffer = icon_data;
@@ -206,7 +206,7 @@ ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) {
ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) {
if (nacp == nullptr) {
- return ResultStatus::ErrorNotUsed;
+ return ResultStatus::ErrorNoControl;
}
out_program_id = nacp->GetTitleId();
@@ -215,7 +215,7 @@ ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) {
ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) {
if (romfs == nullptr) {
- return ResultStatus::ErrorNotUsed;
+ return ResultStatus::ErrorNoRomFS;
}
dir = romfs;
@@ -224,7 +224,7 @@ ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) {
ResultStatus AppLoader_NRO::ReadTitle(std::string& title) {
if (nacp == nullptr) {
- return ResultStatus::ErrorNotUsed;
+ return ResultStatus::ErrorNoControl;
}
title = nacp->GetApplicationName();
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
index eb4dee2c2..5d67fb186 100644
--- a/src/core/loader/xci.cpp
+++ b/src/core/loader/xci.cpp
@@ -26,7 +26,25 @@ namespace Loader {
AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
: AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
nca_loader(std::make_unique<AppLoader_NCA>(
- xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {}
+ xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {
+ if (xci->GetStatus() != ResultStatus::Success)
+ return;
+ const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
+ if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success)
+ return;
+ const auto romfs = FileSys::ExtractRomFS(control_nca->GetRomFS());
+ if (romfs == nullptr)
+ return;
+ for (const auto& language : FileSys::LANGUAGE_NAMES) {
+ icon_file = romfs->GetFile("icon_" + std::string(language) + ".dat");
+ if (icon_file != nullptr)
+ break;
+ }
+ const auto nacp_raw = romfs->GetFile("control.nacp");
+ if (nacp_raw == nullptr)
+ return;
+ nacp_file = std::make_shared<FileSys::NACP>(nacp_raw);
+}
AppLoader_XCI::~AppLoader_XCI() = default;
@@ -48,10 +66,13 @@ ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) {
return ResultStatus::ErrorAlreadyLoaded;
}
+ if (xci->GetStatus() != ResultStatus::Success)
+ return xci->GetStatus();
+
if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) {
if (!Core::Crypto::KeyManager::KeyFileExists(false))
- return ResultStatus::ErrorMissingKeys;
- return ResultStatus::ErrorDecrypting;
+ return ResultStatus::ErrorMissingProductionKeyFile;
+ return ResultStatus::ErrorXCIMissingProgramNCA;
}
auto result = nca_loader->Load(process);
@@ -71,4 +92,17 @@ ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
return nca_loader->ReadProgramId(out_program_id);
}
+ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) {
+ if (icon_file == nullptr)
+ return ResultStatus::ErrorNoControl;
+ buffer = icon_file->ReadAllBytes();
+ return ResultStatus::Success;
+}
+
+ResultStatus AppLoader_XCI::ReadTitle(std::string& title) {
+ if (nacp_file == nullptr)
+ return ResultStatus::ErrorNoControl;
+ title = nacp_file->GetApplicationName();
+ return ResultStatus::Success;
+}
} // namespace Loader
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h
index 0dbcfbdf8..973833050 100644
--- a/src/core/loader/xci.h
+++ b/src/core/loader/xci.h
@@ -33,12 +33,17 @@ public:
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
ResultStatus ReadProgramId(u64& out_program_id) override;
+ ResultStatus ReadIcon(std::vector<u8>& buffer) override;
+ ResultStatus ReadTitle(std::string& title) override;
private:
FileSys::ProgramMetadata metadata;
std::unique_ptr<FileSys::XCI> xci;
std::unique_ptr<AppLoader_NCA> nca_loader;
+
+ FileSys::VirtualFile icon_file;
+ std::shared_ptr<FileSys::NACP> nacp_file;
};
} // namespace Loader