diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/loader/loader.cpp | 9 | ||||
-rw-r--r-- | src/core/loader/loader.h | 4 | ||||
-rw-r--r-- | src/core/loader/nca.cpp | 19 | ||||
-rw-r--r-- | src/core/loader/nca.h | 2 | ||||
-rw-r--r-- | src/core/loader/xci.cpp | 74 | ||||
-rw-r--r-- | src/core/loader/xci.h | 44 |
6 files changed, 145 insertions, 7 deletions
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index cbc4177c6..57e6c0365 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -13,6 +13,7 @@ #include "core/loader/nca.h" #include "core/loader/nro.h" #include "core/loader/nso.h" +#include "core/loader/xci.h" namespace Loader { @@ -35,6 +36,7 @@ FileType IdentifyFile(FileSys::VirtualFile file) { CHECK_TYPE(NSO) CHECK_TYPE(NRO) CHECK_TYPE(NCA) + CHECK_TYPE(XCI) #undef CHECK_TYPE @@ -60,6 +62,8 @@ FileType GuessFromFilename(const std::string& name) { return FileType::NSO; if (extension == "nca") return FileType::NCA; + if (extension == "xci") + return FileType::XCI; return FileType::Unknown; } @@ -74,6 +78,8 @@ const char* GetFileTypeString(FileType type) { return "NSO"; case FileType::NCA: return "NCA"; + case FileType::XCI: + return "XCI"; case FileType::DeconstructedRomDirectory: return "Directory"; case FileType::Error: @@ -111,6 +117,9 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT case FileType::NCA: return std::make_unique<AppLoader_NCA>(std::move(file)); + case FileType::XCI: + return std::make_unique<AppLoader_XCI>(std::move(file)); + // NX deconstructed ROM directory. case FileType::DeconstructedRomDirectory: return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file)); diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 3ca6bcf8b..e69ab85ef 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -31,6 +31,7 @@ enum class FileType { NSO, NRO, NCA, + XCI, DeconstructedRomDirectory, }; @@ -72,7 +73,8 @@ enum class ResultStatus { ErrorNotUsed, ErrorAlreadyLoaded, ErrorMemoryAllocationFailed, - ErrorEncrypted, + ErrorMissingKeys, + ErrorDecrypting, ErrorUnsupportedArch, }; diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index c80df23be..a1f8235d1 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -25,12 +25,10 @@ namespace Loader { AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { - // TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support. - FileSys::NCAHeader header{}; - if (sizeof(FileSys::NCAHeader) != file->ReadObject(&header)) - return FileType::Error; + FileSys::NCA nca(file); - if (IsValidNCA(header) && header.content_type == FileSys::NCAContentType::Program) + if (nca.GetStatus() == ResultStatus::Success && + nca.GetType() == FileSys::NCAContentType::Program) return FileType::NCA; return FileType::Error; @@ -98,12 +96,21 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) { } ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { - if (nca == nullptr || nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) + if (nca == nullptr) + return ResultStatus::ErrorNotLoaded; + if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) return ResultStatus::ErrorNotUsed; dir = nca->GetRomFS(); return ResultStatus::Success; } +ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { + if (nca == nullptr) + return ResultStatus::ErrorNotLoaded; + out_program_id = nca->GetTitleId(); + return ResultStatus::Success; +} + AppLoader_NCA::~AppLoader_NCA() = default; } // namespace Loader diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index 2edd81cb9..e14d618b3 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -33,6 +33,8 @@ public: ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; + ResultStatus ReadProgramId(u64& out_program_id) override; + ~AppLoader_NCA(); private: diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp new file mode 100644 index 000000000..eb4dee2c2 --- /dev/null +++ b/src/core/loader/xci.cpp @@ -0,0 +1,74 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <vector> + +#include "common/file_util.h" +#include "common/logging/log.h" +#include "common/string_util.h" +#include "common/swap.h" +#include "core/core.h" +#include "core/file_sys/content_archive.h" +#include "core/file_sys/control_metadata.h" +#include "core/file_sys/program_metadata.h" +#include "core/file_sys/romfs.h" +#include "core/gdbstub/gdbstub.h" +#include "core/hle/kernel/process.h" +#include "core/hle/kernel/resource_limit.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/loader/nso.h" +#include "core/loader/xci.h" +#include "core/memory.h" + +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))) {} + +AppLoader_XCI::~AppLoader_XCI() = default; + +FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) { + FileSys::XCI xci(file); + + if (xci.GetStatus() == ResultStatus::Success && + xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr && + AppLoader_NCA::IdentifyType(xci.GetNCAFileByType(FileSys::NCAContentType::Program)) == + FileType::NCA) { + return FileType::XCI; + } + + return FileType::Error; +} + +ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) { + if (is_loaded) { + return ResultStatus::ErrorAlreadyLoaded; + } + + if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) { + if (!Core::Crypto::KeyManager::KeyFileExists(false)) + return ResultStatus::ErrorMissingKeys; + return ResultStatus::ErrorDecrypting; + } + + auto result = nca_loader->Load(process); + if (result != ResultStatus::Success) + return result; + + is_loaded = true; + + return ResultStatus::Success; +} + +ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& dir) { + return nca_loader->ReadRomFS(dir); +} + +ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) { + return nca_loader->ReadProgramId(out_program_id); +} + +} // namespace Loader diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h new file mode 100644 index 000000000..0dbcfbdf8 --- /dev/null +++ b/src/core/loader/xci.h @@ -0,0 +1,44 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> +#include "common/common_types.h" +#include "core/file_sys/card_image.h" +#include "core/loader/loader.h" +#include "core/loader/nca.h" + +namespace Loader { + +/// Loads an XCI file +class AppLoader_XCI final : public AppLoader { +public: + explicit AppLoader_XCI(FileSys::VirtualFile file); + ~AppLoader_XCI(); + + /** + * Returns the type of the file + * @param file std::shared_ptr<VfsFile> open file + * @return FileType found, or FileType::Error if this loader doesn't know it + */ + static FileType IdentifyType(const FileSys::VirtualFile& file); + + FileType GetFileType() override { + return IdentifyType(file); + } + + ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; + + ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; + ResultStatus ReadProgramId(u64& out_program_id) override; + +private: + FileSys::ProgramMetadata metadata; + + std::unique_ptr<FileSys::XCI> xci; + std::unique_ptr<AppLoader_NCA> nca_loader; +}; + +} // namespace Loader |