Avoid parsing RomFS to directory in NCA

This commit is contained in:
Zach Hilman 2018-07-28 12:32:16 -04:00
parent 826b1394e8
commit 9e88f03e75
18 changed files with 438 additions and 18 deletions

View file

@ -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<u8>& 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

View file

@ -39,11 +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

View file

@ -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";

View file

@ -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 {

View file

@ -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;
}

View file

@ -33,6 +33,7 @@ public:
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& 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<FileSys::NCA> nca;
std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader;
};