summaryrefslogtreecommitdiff
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.cpp14
-rw-r--r--src/core/loader/elf.cpp2
-rw-r--r--src/core/loader/loader.cpp49
-rw-r--r--src/core/loader/loader.h46
-rw-r--r--src/core/loader/nca.cpp10
-rw-r--r--src/core/loader/nro.cpp10
-rw-r--r--src/core/loader/xci.cpp11
7 files changed, 111 insertions, 31 deletions
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 915d525b0..de05f21d8 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -83,13 +83,13 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
83 83
84 if (dir == nullptr) { 84 if (dir == nullptr) {
85 if (file == nullptr) 85 if (file == nullptr)
86 return ResultStatus::ErrorInvalidFormat; 86 return ResultStatus::ErrorNullFile;
87 dir = file->GetContainingDirectory(); 87 dir = file->GetContainingDirectory();
88 } 88 }
89 89
90 const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); 90 const FileSys::VirtualFile npdm = dir->GetFile("main.npdm");
91 if (npdm == nullptr) 91 if (npdm == nullptr)
92 return ResultStatus::ErrorInvalidFormat; 92 return ResultStatus::ErrorMissingNPDM;
93 93
94 ResultStatus result = metadata.Load(npdm); 94 ResultStatus result = metadata.Load(npdm);
95 if (result != ResultStatus::Success) { 95 if (result != ResultStatus::Success) {
@@ -99,7 +99,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
99 99
100 const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; 100 const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};
101 if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) { 101 if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) {
102 return ResultStatus::ErrorUnsupportedArch; 102 return ResultStatus::Error32BitISA;
103 } 103 }
104 104
105 // Load NSO modules 105 // Load NSO modules
@@ -143,28 +143,28 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
143 143
144ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) { 144ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) {
145 if (romfs == nullptr) 145 if (romfs == nullptr)
146 return ResultStatus::ErrorNotUsed; 146 return ResultStatus::ErrorNoRomFS;
147 dir = romfs; 147 dir = romfs;
148 return ResultStatus::Success; 148 return ResultStatus::Success;
149} 149}
150 150
151ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& buffer) { 151ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& buffer) {
152 if (icon_data.empty()) 152 if (icon_data.empty())
153 return ResultStatus::ErrorNotUsed; 153 return ResultStatus::ErrorNoIcon;
154 buffer = icon_data; 154 buffer = icon_data;
155 return ResultStatus::Success; 155 return ResultStatus::Success;
156} 156}
157 157
158ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program_id) { 158ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program_id) {
159 if (name.empty()) 159 if (name.empty())
160 return ResultStatus::ErrorNotUsed; 160 return ResultStatus::ErrorNoControl;
161 out_program_id = title_id; 161 out_program_id = title_id;
162 return ResultStatus::Success; 162 return ResultStatus::Success;
163} 163}
164 164
165ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) { 165ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) {
166 if (name.empty()) 166 if (name.empty())
167 return ResultStatus::ErrorNotUsed; 167 return ResultStatus::ErrorNoControl;
168 title = name; 168 title = name;
169 return ResultStatus::Success; 169 return ResultStatus::Success;
170} 170}
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) {
390 390
391 std::vector<u8> buffer = file->ReadAllBytes(); 391 std::vector<u8> buffer = file->ReadAllBytes();
392 if (buffer.size() != file->GetSize()) 392 if (buffer.size() != file->GetSize())
393 return ResultStatus::Error; 393 return ResultStatus::ErrorIncorrectELFFileSize;
394 394
395 ElfReader elf_reader(&buffer[0]); 395 ElfReader elf_reader(&buffer[0]);
396 SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); 396 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 a288654df..2f5bfc67c 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -86,6 +86,55 @@ std::string GetFileTypeString(FileType type) {
86 return "unknown"; 86 return "unknown";
87} 87}
88 88
89constexpr std::array<const char*, 36> RESULT_MESSAGES{
90 "The operation completed successfully.",
91 "The loader requested to load is already loaded.",
92 "The operation is not implemented.",
93 "The loader is not initialized properly.",
94 "The NPDM file has a bad header.",
95 "The NPDM has a bad ACID header.",
96 "The NPDM has a bad ACI header,",
97 "The NPDM file has a bad file access control.",
98 "The NPDM has a bad file access header.",
99 "The PFS/HFS partition has a bad header.",
100 "The PFS/HFS partition has incorrect size as determined by the header.",
101 "The NCA file has a bad header.",
102 "The general keyfile could not be found.",
103 "The NCA Header key could not be found.",
104 "The NCA Header key is incorrect or the header is invalid.",
105 "Support for NCA2-type NCAs is not implemented.",
106 "Support for NCA0-type NCAs is not implemented.",
107 "The titlekey for this Rights ID could not be found.",
108 "The titlekek for this crypto revision could not be found.",
109 "The Rights ID in the header is invalid.",
110 "The key area key for this application type and crypto revision could not be found.",
111 "The key area key is incorrect or the section header is invalid.",
112 "The titlekey and/or titlekek is incorrect or the section header is invalid.",
113 "The XCI file is missing a Program-type NCA.",
114 "The NCA file is not an application.",
115 "The ExeFS partition could not be found.",
116 "The XCI file has a bad header.",
117 "The XCI file is missing a partition.",
118 "The file could not be found or does not exist.",
119 "The game is missing a program metadata file (main.npdm).",
120 "The game uses the currently-unimplemented 32-bit architecture.",
121 "The RomFS could not be found.",
122 "The ELF file has incorrect size as determined by the header.",
123 "There was a general error loading the NRO into emulated memory.",
124 "There is no icon available.",
125 "There is no control data available.",
126};
127
128std::string GetMessageForResultStatus(ResultStatus status) {
129 return GetMessageForResultStatus(static_cast<size_t>(status));
130}
131
132std::string GetMessageForResultStatus(u16 status) {
133 if (status >= 36)
134 return "";
135 return RESULT_MESSAGES[status];
136}
137
89/** 138/**
90 * Get a loader for a file with a specific type 139 * Get a loader for a file with a specific type
91 * @param file The file to load 140 * @param file The file to load
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 6a9e5a68b..cfdadbee3 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -58,18 +58,46 @@ std::string GetFileTypeString(FileType type);
58/// Return type for functions in Loader namespace 58/// Return type for functions in Loader namespace
59enum class ResultStatus { 59enum class ResultStatus {
60 Success, 60 Success,
61 Error,
62 ErrorInvalidFormat,
63 ErrorNotImplemented,
64 ErrorNotLoaded,
65 ErrorNotUsed,
66 ErrorAlreadyLoaded, 61 ErrorAlreadyLoaded,
67 ErrorMemoryAllocationFailed, 62 ErrorNotImplemented,
68 ErrorMissingKeys, 63 ErrorNotInitialized,
69 ErrorDecrypting, 64 ErrorBadNPDMHeader,
70 ErrorUnsupportedArch, 65 ErrorBadACIDHeader,
66 ErrorBadACIHeader,
67 ErrorBadFileAccessControl,
68 ErrorBadFileAccessHeader,
69 ErrorBadPFSHeader,
70 ErrorIncorrectPFSFileSize,
71 ErrorBadNCAHeader,
72 ErrorMissingProductionKeyFile,
73 ErrorMissingHeaderKey,
74 ErrorIncorrectHeaderKey,
75 ErrorNCA2,
76 ErrorNCA0,
77 ErrorMissingTitlekey,
78 ErrorMissingTitlekek,
79 ErrorInvalidRightsID,
80 ErrorMissingKeyAreaKey,
81 ErrorIncorrectKeyAreaKey,
82 ErrorIncorrectTitlekeyOrTitlekek,
83 ErrorXCIMissingProgramNCA,
84 ErrorNCANotProgram,
85 ErrorNoExeFS,
86 ErrorBadXCIHeader,
87 ErrorXCIMissingPartition,
88 ErrorNullFile,
89 ErrorMissingNPDM,
90 Error32BitISA,
91 ErrorNoRomFS,
92 ErrorIncorrectELFFileSize,
93 ErrorLoadingNRO,
94 ErrorNoIcon,
95 ErrorNoControl,
71}; 96};
72 97
98std::string GetMessageForResultStatus(ResultStatus status);
99std::string GetMessageForResultStatus(u16 status);
100
73/// Interface for loading an application 101/// Interface for loading an application
74class AppLoader : NonCopyable { 102class AppLoader : NonCopyable {
75public: 103public:
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index 46f5cd393..8498cc94b 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -46,12 +46,12 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
46 } 46 }
47 47
48 if (nca->GetType() != FileSys::NCAContentType::Program) 48 if (nca->GetType() != FileSys::NCAContentType::Program)
49 return ResultStatus::ErrorInvalidFormat; 49 return ResultStatus::ErrorNCANotProgram;
50 50
51 const auto exefs = nca->GetExeFS(); 51 const auto exefs = nca->GetExeFS();
52 52
53 if (exefs == nullptr) 53 if (exefs == nullptr)
54 return ResultStatus::ErrorInvalidFormat; 54 return ResultStatus::ErrorNoExeFS;
55 55
56 directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs); 56 directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs);
57 57
@@ -69,16 +69,16 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
69 69
70ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { 70ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) {
71 if (nca == nullptr) 71 if (nca == nullptr)
72 return ResultStatus::ErrorNotLoaded; 72 return ResultStatus::ErrorNotInitialized;
73 if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) 73 if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0)
74 return ResultStatus::ErrorNotUsed; 74 return ResultStatus::ErrorNoRomFS;
75 dir = nca->GetRomFS(); 75 dir = nca->GetRomFS();
76 return ResultStatus::Success; 76 return ResultStatus::Success;
77} 77}
78 78
79ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { 79ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) {
80 if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) 80 if (nca == nullptr || nca->GetStatus() != ResultStatus::Success)
81 return ResultStatus::ErrorInvalidFormat; 81 return ResultStatus::ErrorNotInitialized;
82 out_program_id = nca->GetTitleId(); 82 out_program_id = nca->GetTitleId();
83 return ResultStatus::Success; 83 return ResultStatus::Success;
84} 84}
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) {
182 static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR}; 182 static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR};
183 183
184 if (!LoadNro(file, base_addr)) { 184 if (!LoadNro(file, base_addr)) {
185 return ResultStatus::ErrorInvalidFormat; 185 return ResultStatus::ErrorLoadingNRO;
186 } 186 }
187 187
188 process->svc_access_mask.set(); 188 process->svc_access_mask.set();
@@ -197,7 +197,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
197 197
198ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) { 198ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) {
199 if (icon_data.empty()) { 199 if (icon_data.empty()) {
200 return ResultStatus::ErrorNotUsed; 200 return ResultStatus::ErrorNoIcon;
201 } 201 }
202 202
203 buffer = icon_data; 203 buffer = icon_data;
@@ -206,7 +206,7 @@ ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) {
206 206
207ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) { 207ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) {
208 if (nacp == nullptr) { 208 if (nacp == nullptr) {
209 return ResultStatus::ErrorNotUsed; 209 return ResultStatus::ErrorNoControl;
210 } 210 }
211 211
212 out_program_id = nacp->GetTitleId(); 212 out_program_id = nacp->GetTitleId();
@@ -215,7 +215,7 @@ ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) {
215 215
216ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) { 216ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) {
217 if (romfs == nullptr) { 217 if (romfs == nullptr) {
218 return ResultStatus::ErrorNotUsed; 218 return ResultStatus::ErrorNoRomFS;
219 } 219 }
220 220
221 dir = romfs; 221 dir = romfs;
@@ -224,7 +224,7 @@ ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) {
224 224
225ResultStatus AppLoader_NRO::ReadTitle(std::string& title) { 225ResultStatus AppLoader_NRO::ReadTitle(std::string& title) {
226 if (nacp == nullptr) { 226 if (nacp == nullptr) {
227 return ResultStatus::ErrorNotUsed; 227 return ResultStatus::ErrorNoControl;
228 } 228 }
229 229
230 title = nacp->GetApplicationName(); 230 title = nacp->GetApplicationName();
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
index d3fe24419..5d67fb186 100644
--- a/src/core/loader/xci.cpp
+++ b/src/core/loader/xci.cpp
@@ -66,10 +66,13 @@ ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) {
66 return ResultStatus::ErrorAlreadyLoaded; 66 return ResultStatus::ErrorAlreadyLoaded;
67 } 67 }
68 68
69 if (xci->GetStatus() != ResultStatus::Success)
70 return xci->GetStatus();
71
69 if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) { 72 if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) {
70 if (!Core::Crypto::KeyManager::KeyFileExists(false)) 73 if (!Core::Crypto::KeyManager::KeyFileExists(false))
71 return ResultStatus::ErrorMissingKeys; 74 return ResultStatus::ErrorMissingProductionKeyFile;
72 return ResultStatus::ErrorDecrypting; 75 return ResultStatus::ErrorXCIMissingProgramNCA;
73 } 76 }
74 77
75 auto result = nca_loader->Load(process); 78 auto result = nca_loader->Load(process);
@@ -91,14 +94,14 @@ ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
91 94
92ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) { 95ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) {
93 if (icon_file == nullptr) 96 if (icon_file == nullptr)
94 return ResultStatus::ErrorInvalidFormat; 97 return ResultStatus::ErrorNoControl;
95 buffer = icon_file->ReadAllBytes(); 98 buffer = icon_file->ReadAllBytes();
96 return ResultStatus::Success; 99 return ResultStatus::Success;
97} 100}
98 101
99ResultStatus AppLoader_XCI::ReadTitle(std::string& title) { 102ResultStatus AppLoader_XCI::ReadTitle(std::string& title) {
100 if (nacp_file == nullptr) 103 if (nacp_file == nullptr)
101 return ResultStatus::ErrorInvalidFormat; 104 return ResultStatus::ErrorNoControl;
102 title = nacp_file->GetApplicationName(); 105 title = nacp_file->GetApplicationName();
103 return ResultStatus::Success; 106 return ResultStatus::Success;
104} 107}