diff options
Diffstat (limited to 'src/core/loader')
| -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 | 
