diff options
Diffstat (limited to 'src/core/loader')
| -rw-r--r-- | src/core/loader/deconstructed_rom_directory.cpp | 14 | ||||
| -rw-r--r-- | src/core/loader/elf.cpp | 2 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 49 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 46 | ||||
| -rw-r--r-- | src/core/loader/nca.cpp | 10 | ||||
| -rw-r--r-- | src/core/loader/nro.cpp | 10 | ||||
| -rw-r--r-- | src/core/loader/xci.cpp | 11 |
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 | ||
| 144 | ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) { | 144 | ResultStatus 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 | ||
| 151 | ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& buffer) { | 151 | ResultStatus 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 | ||
| 158 | ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program_id) { | 158 | ResultStatus 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 | ||
| 165 | ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) { | 165 | ResultStatus 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 | ||
| 89 | constexpr 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 | |||
| 128 | std::string GetMessageForResultStatus(ResultStatus status) { | ||
| 129 | return GetMessageForResultStatus(static_cast<size_t>(status)); | ||
| 130 | } | ||
| 131 | |||
| 132 | std::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 |
| 59 | enum class ResultStatus { | 59 | enum 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 | ||
| 98 | std::string GetMessageForResultStatus(ResultStatus status); | ||
| 99 | std::string GetMessageForResultStatus(u16 status); | ||
| 100 | |||
| 73 | /// Interface for loading an application | 101 | /// Interface for loading an application |
| 74 | class AppLoader : NonCopyable { | 102 | class AppLoader : NonCopyable { |
| 75 | public: | 103 | public: |
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 | ||
| 70 | ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { | 70 | ResultStatus 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 | ||
| 79 | ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { | 79 | ResultStatus 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 | ||
| 198 | ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) { | 198 | ResultStatus 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 | ||
| 207 | ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) { | 207 | ResultStatus 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 | ||
| 216 | ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) { | 216 | ResultStatus 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 | ||
| 225 | ResultStatus AppLoader_NRO::ReadTitle(std::string& title) { | 225 | ResultStatus 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 | ||
| 92 | ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) { | 95 | ResultStatus 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 | ||
| 99 | ResultStatus AppLoader_XCI::ReadTitle(std::string& title) { | 102 | ResultStatus 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 | } |