summaryrefslogtreecommitdiff
path: root/src/core/loader
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/loader')
-rw-r--r--src/core/loader/loader.cpp9
-rw-r--r--src/core/loader/loader.h4
-rw-r--r--src/core/loader/nca.cpp19
-rw-r--r--src/core/loader/nca.h2
-rw-r--r--src/core/loader/xci.cpp74
-rw-r--r--src/core/loader/xci.h44
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 @@
13#include "core/loader/nca.h" 13#include "core/loader/nca.h"
14#include "core/loader/nro.h" 14#include "core/loader/nro.h"
15#include "core/loader/nso.h" 15#include "core/loader/nso.h"
16#include "core/loader/xci.h"
16 17
17namespace Loader { 18namespace Loader {
18 19
@@ -35,6 +36,7 @@ FileType IdentifyFile(FileSys::VirtualFile file) {
35 CHECK_TYPE(NSO) 36 CHECK_TYPE(NSO)
36 CHECK_TYPE(NRO) 37 CHECK_TYPE(NRO)
37 CHECK_TYPE(NCA) 38 CHECK_TYPE(NCA)
39 CHECK_TYPE(XCI)
38 40
39#undef CHECK_TYPE 41#undef CHECK_TYPE
40 42
@@ -60,6 +62,8 @@ FileType GuessFromFilename(const std::string& name) {
60 return FileType::NSO; 62 return FileType::NSO;
61 if (extension == "nca") 63 if (extension == "nca")
62 return FileType::NCA; 64 return FileType::NCA;
65 if (extension == "xci")
66 return FileType::XCI;
63 67
64 return FileType::Unknown; 68 return FileType::Unknown;
65} 69}
@@ -74,6 +78,8 @@ const char* GetFileTypeString(FileType type) {
74 return "NSO"; 78 return "NSO";
75 case FileType::NCA: 79 case FileType::NCA:
76 return "NCA"; 80 return "NCA";
81 case FileType::XCI:
82 return "XCI";
77 case FileType::DeconstructedRomDirectory: 83 case FileType::DeconstructedRomDirectory:
78 return "Directory"; 84 return "Directory";
79 case FileType::Error: 85 case FileType::Error:
@@ -111,6 +117,9 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT
111 case FileType::NCA: 117 case FileType::NCA:
112 return std::make_unique<AppLoader_NCA>(std::move(file)); 118 return std::make_unique<AppLoader_NCA>(std::move(file));
113 119
120 case FileType::XCI:
121 return std::make_unique<AppLoader_XCI>(std::move(file));
122
114 // NX deconstructed ROM directory. 123 // NX deconstructed ROM directory.
115 case FileType::DeconstructedRomDirectory: 124 case FileType::DeconstructedRomDirectory:
116 return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file)); 125 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 {
31 NSO, 31 NSO,
32 NRO, 32 NRO,
33 NCA, 33 NCA,
34 XCI,
34 DeconstructedRomDirectory, 35 DeconstructedRomDirectory,
35}; 36};
36 37
@@ -72,7 +73,8 @@ enum class ResultStatus {
72 ErrorNotUsed, 73 ErrorNotUsed,
73 ErrorAlreadyLoaded, 74 ErrorAlreadyLoaded,
74 ErrorMemoryAllocationFailed, 75 ErrorMemoryAllocationFailed,
75 ErrorEncrypted, 76 ErrorMissingKeys,
77 ErrorDecrypting,
76 ErrorUnsupportedArch, 78 ErrorUnsupportedArch,
77}; 79};
78 80
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 {
25AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} 25AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {}
26 26
27FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { 27FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) {
28 // TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support. 28 FileSys::NCA nca(file);
29 FileSys::NCAHeader header{};
30 if (sizeof(FileSys::NCAHeader) != file->ReadObject(&header))
31 return FileType::Error;
32 29
33 if (IsValidNCA(header) && header.content_type == FileSys::NCAContentType::Program) 30 if (nca.GetStatus() == ResultStatus::Success &&
31 nca.GetType() == FileSys::NCAContentType::Program)
34 return FileType::NCA; 32 return FileType::NCA;
35 33
36 return FileType::Error; 34 return FileType::Error;
@@ -98,12 +96,21 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
98} 96}
99 97
100ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { 98ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) {
101 if (nca == nullptr || nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) 99 if (nca == nullptr)
100 return ResultStatus::ErrorNotLoaded;
101 if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0)
102 return ResultStatus::ErrorNotUsed; 102 return ResultStatus::ErrorNotUsed;
103 dir = nca->GetRomFS(); 103 dir = nca->GetRomFS();
104 return ResultStatus::Success; 104 return ResultStatus::Success;
105} 105}
106 106
107ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) {
108 if (nca == nullptr)
109 return ResultStatus::ErrorNotLoaded;
110 out_program_id = nca->GetTitleId();
111 return ResultStatus::Success;
112}
113
107AppLoader_NCA::~AppLoader_NCA() = default; 114AppLoader_NCA::~AppLoader_NCA() = default;
108 115
109} // namespace Loader 116} // 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:
33 33
34 ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; 34 ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
35 35
36 ResultStatus ReadProgramId(u64& out_program_id) override;
37
36 ~AppLoader_NCA(); 38 ~AppLoader_NCA();
37 39
38private: 40private:
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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <vector>
6
7#include "common/file_util.h"
8#include "common/logging/log.h"
9#include "common/string_util.h"
10#include "common/swap.h"
11#include "core/core.h"
12#include "core/file_sys/content_archive.h"
13#include "core/file_sys/control_metadata.h"
14#include "core/file_sys/program_metadata.h"
15#include "core/file_sys/romfs.h"
16#include "core/gdbstub/gdbstub.h"
17#include "core/hle/kernel/process.h"
18#include "core/hle/kernel/resource_limit.h"
19#include "core/hle/service/filesystem/filesystem.h"
20#include "core/loader/nso.h"
21#include "core/loader/xci.h"
22#include "core/memory.h"
23
24namespace Loader {
25
26AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
27 : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
28 nca_loader(std::make_unique<AppLoader_NCA>(
29 xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {}
30
31AppLoader_XCI::~AppLoader_XCI() = default;
32
33FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) {
34 FileSys::XCI xci(file);
35
36 if (xci.GetStatus() == ResultStatus::Success &&
37 xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr &&
38 AppLoader_NCA::IdentifyType(xci.GetNCAFileByType(FileSys::NCAContentType::Program)) ==
39 FileType::NCA) {
40 return FileType::XCI;
41 }
42
43 return FileType::Error;
44}
45
46ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) {
47 if (is_loaded) {
48 return ResultStatus::ErrorAlreadyLoaded;
49 }
50
51 if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) {
52 if (!Core::Crypto::KeyManager::KeyFileExists(false))
53 return ResultStatus::ErrorMissingKeys;
54 return ResultStatus::ErrorDecrypting;
55 }
56
57 auto result = nca_loader->Load(process);
58 if (result != ResultStatus::Success)
59 return result;
60
61 is_loaded = true;
62
63 return ResultStatus::Success;
64}
65
66ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& dir) {
67 return nca_loader->ReadRomFS(dir);
68}
69
70ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
71 return nca_loader->ReadProgramId(out_program_id);
72}
73
74} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "common/common_types.h"
9#include "core/file_sys/card_image.h"
10#include "core/loader/loader.h"
11#include "core/loader/nca.h"
12
13namespace Loader {
14
15/// Loads an XCI file
16class AppLoader_XCI final : public AppLoader {
17public:
18 explicit AppLoader_XCI(FileSys::VirtualFile file);
19 ~AppLoader_XCI();
20
21 /**
22 * Returns the type of the file
23 * @param file std::shared_ptr<VfsFile> open file
24 * @return FileType found, or FileType::Error if this loader doesn't know it
25 */
26 static FileType IdentifyType(const FileSys::VirtualFile& file);
27
28 FileType GetFileType() override {
29 return IdentifyType(file);
30 }
31
32 ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
33
34 ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
35 ResultStatus ReadProgramId(u64& out_program_id) override;
36
37private:
38 FileSys::ProgramMetadata metadata;
39
40 std::unique_ptr<FileSys::XCI> xci;
41 std::unique_ptr<AppLoader_NCA> nca_loader;
42};
43
44} // namespace Loader