diff options
| author | 2018-07-30 12:46:23 -0400 | |
|---|---|---|
| committer | 2018-08-01 00:16:54 -0400 | |
| commit | 187d8e215fb157edaa9f3976bebba9a9a7ed103d (patch) | |
| tree | 140cbfbd109281adc87c9c79ee07976ba54888cd | |
| parent | Use static const instead of const static (diff) | |
| download | yuzu-187d8e215fb157edaa9f3976bebba9a9a7ed103d.tar.gz yuzu-187d8e215fb157edaa9f3976bebba9a9a7ed103d.tar.xz yuzu-187d8e215fb157edaa9f3976bebba9a9a7ed103d.zip | |
Use more descriptive error codes and messages
| -rw-r--r-- | src/core/core.cpp | 12 | ||||
| -rw-r--r-- | src/core/core.h | 14 | ||||
| -rw-r--r-- | src/core/crypto/key_manager.cpp | 27 | ||||
| -rw-r--r-- | src/core/crypto/key_manager.h | 2 | ||||
| -rw-r--r-- | src/core/file_sys/content_archive.cpp | 10 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 3 | ||||
| -rw-r--r-- | src/core/loader/xci.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 51 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 14 |
9 files changed, 101 insertions, 34 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index b7f4b4532..0ef6af3fe 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -101,8 +101,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file | |||
| 101 | static_cast<int>(system_mode.second)); | 101 | static_cast<int>(system_mode.second)); |
| 102 | 102 | ||
| 103 | switch (system_mode.second) { | 103 | switch (system_mode.second) { |
| 104 | case Loader::ResultStatus::ErrorEncrypted: | 104 | case Loader::ResultStatus::ErrorMissingKeys: |
| 105 | return ResultStatus::ErrorLoader_ErrorEncrypted; | 105 | return ResultStatus::ErrorLoader_ErrorMissingKeys; |
| 106 | case Loader::ResultStatus::ErrorDecrypting: | ||
| 107 | return ResultStatus::ErrorLoader_ErrorDecrypting; | ||
| 106 | case Loader::ResultStatus::ErrorInvalidFormat: | 108 | case Loader::ResultStatus::ErrorInvalidFormat: |
| 107 | return ResultStatus::ErrorLoader_ErrorInvalidFormat; | 109 | return ResultStatus::ErrorLoader_ErrorInvalidFormat; |
| 108 | case Loader::ResultStatus::ErrorUnsupportedArch: | 110 | case Loader::ResultStatus::ErrorUnsupportedArch: |
| @@ -126,8 +128,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file | |||
| 126 | System::Shutdown(); | 128 | System::Shutdown(); |
| 127 | 129 | ||
| 128 | switch (load_result) { | 130 | switch (load_result) { |
| 129 | case Loader::ResultStatus::ErrorEncrypted: | 131 | case Loader::ResultStatus::ErrorMissingKeys: |
| 130 | return ResultStatus::ErrorLoader_ErrorEncrypted; | 132 | return ResultStatus::ErrorLoader_ErrorMissingKeys; |
| 133 | case Loader::ResultStatus::ErrorDecrypting: | ||
| 134 | return ResultStatus::ErrorLoader_ErrorDecrypting; | ||
| 131 | case Loader::ResultStatus::ErrorInvalidFormat: | 135 | case Loader::ResultStatus::ErrorInvalidFormat: |
| 132 | return ResultStatus::ErrorLoader_ErrorInvalidFormat; | 136 | return ResultStatus::ErrorLoader_ErrorInvalidFormat; |
| 133 | case Loader::ResultStatus::ErrorUnsupportedArch: | 137 | case Loader::ResultStatus::ErrorUnsupportedArch: |
diff --git a/src/core/core.h b/src/core/core.h index c123fe401..a90bff3df 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -43,12 +43,14 @@ public: | |||
| 43 | 43 | ||
| 44 | /// Enumeration representing the return values of the System Initialize and Load process. | 44 | /// Enumeration representing the return values of the System Initialize and Load process. |
| 45 | enum class ResultStatus : u32 { | 45 | enum class ResultStatus : u32 { |
| 46 | Success, ///< Succeeded | 46 | Success, ///< Succeeded |
| 47 | ErrorNotInitialized, ///< Error trying to use core prior to initialization | 47 | ErrorNotInitialized, ///< Error trying to use core prior to initialization |
| 48 | ErrorGetLoader, ///< Error finding the correct application loader | 48 | ErrorGetLoader, ///< Error finding the correct application loader |
| 49 | ErrorSystemMode, ///< Error determining the system mode | 49 | ErrorSystemMode, ///< Error determining the system mode |
| 50 | ErrorLoader, ///< Error loading the specified application | 50 | ErrorLoader, ///< Error loading the specified application |
| 51 | ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption | 51 | ErrorLoader_ErrorMissingKeys, ///< Error because the key/keys needed to run could not be |
| 52 | ///< found. | ||
| 53 | ErrorLoader_ErrorDecrypting, ///< Error loading the specified application due to encryption | ||
| 52 | ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an | 54 | ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an |
| 53 | /// invalid format | 55 | /// invalid format |
| 54 | ErrorSystemFiles, ///< Error in finding system files | 56 | ErrorSystemFiles, ///< Error in finding system files |
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 33633de7e..678ac5752 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -53,8 +53,8 @@ std::array<u8, 32> operator""_array32(const char* str, size_t len) { | |||
| 53 | 53 | ||
| 54 | KeyManager::KeyManager() { | 54 | KeyManager::KeyManager() { |
| 55 | // Initialize keys | 55 | // Initialize keys |
| 56 | std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); | 56 | const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); |
| 57 | std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); | 57 | const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); |
| 58 | if (Settings::values.use_dev_keys) { | 58 | if (Settings::values.use_dev_keys) { |
| 59 | dev_mode = true; | 59 | dev_mode = true; |
| 60 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); | 60 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); |
| @@ -109,9 +109,9 @@ void KeyManager::LoadFromFile(std::string_view filename_, bool is_title_keys) { | |||
| 109 | 109 | ||
| 110 | void KeyManager::AttemptLoadKeyFile(std::string_view dir1_, std::string_view dir2_, | 110 | void KeyManager::AttemptLoadKeyFile(std::string_view dir1_, std::string_view dir2_, |
| 111 | std::string_view filename_, bool title) { | 111 | std::string_view filename_, bool title) { |
| 112 | std::string dir1(dir1_); | 112 | const std::string dir1(dir1_); |
| 113 | std::string dir2(dir2_); | 113 | const std::string dir2(dir2_); |
| 114 | std::string filename(filename_); | 114 | const std::string filename(filename_); |
| 115 | if (FileUtil::Exists(dir1 + DIR_SEP + filename)) | 115 | if (FileUtil::Exists(dir1 + DIR_SEP + filename)) |
| 116 | LoadFromFile(dir1 + DIR_SEP + filename, title); | 116 | LoadFromFile(dir1 + DIR_SEP + filename, title); |
| 117 | else if (FileUtil::Exists(dir2 + DIR_SEP + filename)) | 117 | else if (FileUtil::Exists(dir2 + DIR_SEP + filename)) |
| @@ -146,6 +146,23 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { | |||
| 146 | s256_keys[{id, field1, field2}] = key; | 146 | s256_keys[{id, field1, field2}] = key; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | bool KeyManager::KeyFileExists(bool title) { | ||
| 150 | const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); | ||
| 151 | const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); | ||
| 152 | if (title) { | ||
| 153 | return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "title.keys") || | ||
| 154 | FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "title.keys"); | ||
| 155 | } | ||
| 156 | |||
| 157 | if (Settings::values.use_dev_keys) { | ||
| 158 | return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") || | ||
| 159 | FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys"); | ||
| 160 | } | ||
| 161 | |||
| 162 | return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") || | ||
| 163 | FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys"); | ||
| 164 | } | ||
| 165 | |||
| 149 | const std::unordered_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = { | 166 | const std::unordered_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = { |
| 150 | {"master_key_00", {S128KeyType::Master, 0, 0}}, | 167 | {"master_key_00", {S128KeyType::Master, 0, 0}}, |
| 151 | {"master_key_01", {S128KeyType::Master, 1, 0}}, | 168 | {"master_key_01", {S128KeyType::Master, 1, 0}}, |
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index c09a6197e..03152a12c 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h | |||
| @@ -102,6 +102,8 @@ public: | |||
| 102 | void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); | 102 | void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); |
| 103 | void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); | 103 | void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); |
| 104 | 104 | ||
| 105 | static bool KeyFileExists(bool title); | ||
| 106 | |||
| 105 | private: | 107 | private: |
| 106 | std::unordered_map<KeyIndex<S128KeyType>, Key128> s128_keys; | 108 | std::unordered_map<KeyIndex<S128KeyType>, Key128> s128_keys; |
| 107 | std::unordered_map<KeyIndex<S256KeyType>, Key256> s256_keys; | 109 | std::unordered_map<KeyIndex<S256KeyType>, Key256> s256_keys; |
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index cb59c0a2b..2deb727cc 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp | |||
| @@ -156,9 +156,9 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | |||
| 156 | encrypted = true; | 156 | encrypted = true; |
| 157 | } else { | 157 | } else { |
| 158 | if (!keys.HasKey(Core::Crypto::S256KeyType::Header)) | 158 | if (!keys.HasKey(Core::Crypto::S256KeyType::Header)) |
| 159 | status = Loader::ResultStatus::ErrorEncrypted; | 159 | status = Loader::ResultStatus::ErrorMissingKeys; |
| 160 | else | 160 | else |
| 161 | status = Loader::ResultStatus::ErrorInvalidFormat; | 161 | status = Loader::ResultStatus::ErrorDecrypting; |
| 162 | return; | 162 | return; |
| 163 | } | 163 | } |
| 164 | } | 164 | } |
| @@ -194,6 +194,9 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | |||
| 194 | if (dec != nullptr) { | 194 | if (dec != nullptr) { |
| 195 | files.emplace_back(); | 195 | files.emplace_back(); |
| 196 | romfs = files.back(); | 196 | romfs = files.back(); |
| 197 | } else { | ||
| 198 | status = Loader::ResultStatus::ErrorMissingKeys; | ||
| 199 | return; | ||
| 197 | } | 200 | } |
| 198 | } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) { | 201 | } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) { |
| 199 | u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) * | 202 | u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) * |
| @@ -211,6 +214,9 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | |||
| 211 | if (IsDirectoryExeFS(dirs.back())) | 214 | if (IsDirectoryExeFS(dirs.back())) |
| 212 | exefs = dirs.back(); | 215 | exefs = dirs.back(); |
| 213 | } | 216 | } |
| 217 | } else { | ||
| 218 | status = Loader::ResultStatus::ErrorMissingKeys; | ||
| 219 | return; | ||
| 214 | } | 220 | } |
| 215 | } | 221 | } |
| 216 | } | 222 | } |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index dc8d28311..cd8b41bb6 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -73,7 +73,8 @@ enum class ResultStatus { | |||
| 73 | ErrorNotUsed, | 73 | ErrorNotUsed, |
| 74 | ErrorAlreadyLoaded, | 74 | ErrorAlreadyLoaded, |
| 75 | ErrorMemoryAllocationFailed, | 75 | ErrorMemoryAllocationFailed, |
| 76 | ErrorEncrypted, | 76 | ErrorMissingKeys, |
| 77 | ErrorDecrypting, | ||
| 77 | ErrorUnsupportedArch, | 78 | ErrorUnsupportedArch, |
| 78 | }; | 79 | }; |
| 79 | 80 | ||
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 74940fb83..d757862f0 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp | |||
| @@ -49,7 +49,7 @@ ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) { | |||
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) { | 51 | if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) { |
| 52 | return ResultStatus::ErrorEncrypted; | 52 | return ResultStatus::ErrorDecrypting; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | auto result = nca_loader->Load(process); | 55 | auto result = nca_loader->Load(process); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index c274e5e2b..5bdf41ea4 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -425,18 +425,49 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 425 | tr("Could not determine the system mode.")); | 425 | tr("Could not determine the system mode.")); |
| 426 | break; | 426 | break; |
| 427 | 427 | ||
| 428 | case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: { | 428 | case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: { |
| 429 | const auto reg_found = Core::Crypto::KeyManager::KeyFileExists(false); | ||
| 430 | const auto title_found = Core::Crypto::KeyManager::KeyFileExists(true); | ||
| 431 | |||
| 432 | std::string file_text; | ||
| 433 | |||
| 434 | if (!reg_found && !title_found) { | ||
| 435 | file_text = "A proper key file (prod.keys, dev.keys, or title.keys) could not be " | ||
| 436 | "found. You will need to dump your keys from your switch to continue."; | ||
| 437 | } else if (reg_found && title_found) { | ||
| 438 | file_text = | ||
| 439 | "Both key files were found in your config directory, but the correct key could" | ||
| 440 | "not be found. You may be missing a titlekey or general key, depending on " | ||
| 441 | "the game."; | ||
| 442 | } else if (reg_found) { | ||
| 443 | file_text = | ||
| 444 | "The regular keys file (prod.keys/dev.keys) was found in your config, but the " | ||
| 445 | "titlekeys file (title.keys) was not. You are either missing the correct " | ||
| 446 | "titlekey or missing a general key required to decrypt the game."; | ||
| 447 | } else { | ||
| 448 | file_text = "The title keys file (title.keys) was found in your config, but " | ||
| 449 | "the regular keys file (prod.keys/dev.keys) was not. Unfortunately, " | ||
| 450 | "having the titlekey is not enough, you need additional general keys " | ||
| 451 | "to properly decrypt the game. You should double-check to make sure " | ||
| 452 | "your keys are correct."; | ||
| 453 | } | ||
| 454 | |||
| 455 | QMessageBox::critical( | ||
| 456 | this, tr("Error while loading ROM!"), | ||
| 457 | tr(("The game you are trying to load is encrypted and the required keys to load " | ||
| 458 | "the game could not be found in your configuration. " + | ||
| 459 | file_text + " Please refer to <a href=''>How to Dump Keys</a> for help.") | ||
| 460 | .c_str())); | ||
| 461 | break; | ||
| 462 | } | ||
| 463 | case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: { | ||
| 429 | QMessageBox::critical( | 464 | QMessageBox::critical( |
| 430 | this, tr("Error while loading ROM!"), | 465 | this, tr("Error while loading ROM!"), |
| 431 | tr("The game that you are trying to load must be decrypted before being used with " | 466 | tr("There was a general error while decrypting the game. This means that the keys " |
| 432 | "yuzu. A real Switch is required.<br/><br/>" | 467 | "necessary were found, but were either incorrect, the game itself was not a " |
| 433 | "For more information on dumping and decrypting games, please see the following " | 468 | "valid game or the game uses an unhandled cryptographic scheme. Please refer to " |
| 434 | "wiki pages: <ul>" | 469 | "<a href=''>How to Dump Keys</a> to double check that you have the correct " |
| 435 | "<li><a href='https://yuzu-emu.org/wiki/dumping-game-cartridges/'>Dumping Game " | 470 | "keys.")); |
| 436 | "Cartridges</a></li>" | ||
| 437 | "<li><a href='https://yuzu-emu.org/wiki/dumping-installed-titles/'>Dumping " | ||
| 438 | "Installed Titles</a></li>" | ||
| 439 | "</ul>")); | ||
| 440 | break; | 471 | break; |
| 441 | } | 472 | } |
| 442 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: | 473 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 97a8e13f0..5970cdb4e 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -173,11 +173,15 @@ int main(int argc, char** argv) { | |||
| 173 | case Core::System::ResultStatus::ErrorLoader: | 173 | case Core::System::ResultStatus::ErrorLoader: |
| 174 | LOG_CRITICAL(Frontend, "Failed to load ROM!"); | 174 | LOG_CRITICAL(Frontend, "Failed to load ROM!"); |
| 175 | return -1; | 175 | return -1; |
| 176 | case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: | 176 | case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: |
| 177 | LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before " | 177 | LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and the keys required " |
| 178 | "being used with yuzu. \n\n For more information on dumping and " | 178 | "could not be found. Please refer to <LINK> for help"); |
| 179 | "decrypting games, please refer to: " | 179 | return -1; |
| 180 | "https://yuzu-emu.org/wiki/dumping-game-cartridges/"); | 180 | case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: |
| 181 | LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and there was a " | ||
| 182 | "general error while decrypting. This could mean that the keys are " | ||
| 183 | "incorrect, game is invalid or game uses an unsupported method of " | ||
| 184 | "crypto. Please refer to <LINK> to double-check your keys"); | ||
| 181 | return -1; | 185 | return -1; |
| 182 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: | 186 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: |
| 183 | LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); | 187 | LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); |