mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 10:44:49 +01:00 
			
		
		
		
	Use more descriptive error codes and messages
This commit is contained in:
		
							parent
							
								
									9d59b96ef9
								
							
						
					
					
						commit
						187d8e215f
					
				| @ -101,8 +101,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file | ||||
|                      static_cast<int>(system_mode.second)); | ||||
| 
 | ||||
|         switch (system_mode.second) { | ||||
|         case Loader::ResultStatus::ErrorEncrypted: | ||||
|             return ResultStatus::ErrorLoader_ErrorEncrypted; | ||||
|         case Loader::ResultStatus::ErrorMissingKeys: | ||||
|             return ResultStatus::ErrorLoader_ErrorMissingKeys; | ||||
|         case Loader::ResultStatus::ErrorDecrypting: | ||||
|             return ResultStatus::ErrorLoader_ErrorDecrypting; | ||||
|         case Loader::ResultStatus::ErrorInvalidFormat: | ||||
|             return ResultStatus::ErrorLoader_ErrorInvalidFormat; | ||||
|         case Loader::ResultStatus::ErrorUnsupportedArch: | ||||
| @ -126,8 +128,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file | ||||
|         System::Shutdown(); | ||||
| 
 | ||||
|         switch (load_result) { | ||||
|         case Loader::ResultStatus::ErrorEncrypted: | ||||
|             return ResultStatus::ErrorLoader_ErrorEncrypted; | ||||
|         case Loader::ResultStatus::ErrorMissingKeys: | ||||
|             return ResultStatus::ErrorLoader_ErrorMissingKeys; | ||||
|         case Loader::ResultStatus::ErrorDecrypting: | ||||
|             return ResultStatus::ErrorLoader_ErrorDecrypting; | ||||
|         case Loader::ResultStatus::ErrorInvalidFormat: | ||||
|             return ResultStatus::ErrorLoader_ErrorInvalidFormat; | ||||
|         case Loader::ResultStatus::ErrorUnsupportedArch: | ||||
|  | ||||
| @ -43,12 +43,14 @@ public: | ||||
| 
 | ||||
|     /// Enumeration representing the return values of the System Initialize and Load process.
 | ||||
|     enum class ResultStatus : u32 { | ||||
|         Success,                    ///< Succeeded
 | ||||
|         ErrorNotInitialized,        ///< Error trying to use core prior to initialization
 | ||||
|         ErrorGetLoader,             ///< Error finding the correct application loader
 | ||||
|         ErrorSystemMode,            ///< Error determining the system mode
 | ||||
|         ErrorLoader,                ///< Error loading the specified application
 | ||||
|         ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption
 | ||||
|         Success,                      ///< Succeeded
 | ||||
|         ErrorNotInitialized,          ///< Error trying to use core prior to initialization
 | ||||
|         ErrorGetLoader,               ///< Error finding the correct application loader
 | ||||
|         ErrorSystemMode,              ///< Error determining the system mode
 | ||||
|         ErrorLoader,                  ///< Error loading the specified application
 | ||||
|         ErrorLoader_ErrorMissingKeys, ///< Error because the key/keys needed to run could not be
 | ||||
|                                       ///< found.
 | ||||
|         ErrorLoader_ErrorDecrypting,  ///< Error loading the specified application due to encryption
 | ||||
|         ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an
 | ||||
|                                         /// invalid format
 | ||||
|         ErrorSystemFiles,               ///< Error in finding system files
 | ||||
|  | ||||
| @ -53,8 +53,8 @@ std::array<u8, 32> operator""_array32(const char* str, size_t len) { | ||||
| 
 | ||||
| KeyManager::KeyManager() { | ||||
|     // Initialize keys
 | ||||
|     std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); | ||||
|     std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); | ||||
|     const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); | ||||
|     const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); | ||||
|     if (Settings::values.use_dev_keys) { | ||||
|         dev_mode = true; | ||||
|         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) { | ||||
| 
 | ||||
| void KeyManager::AttemptLoadKeyFile(std::string_view dir1_, std::string_view dir2_, | ||||
|                                     std::string_view filename_, bool title) { | ||||
|     std::string dir1(dir1_); | ||||
|     std::string dir2(dir2_); | ||||
|     std::string filename(filename_); | ||||
|     const std::string dir1(dir1_); | ||||
|     const std::string dir2(dir2_); | ||||
|     const std::string filename(filename_); | ||||
|     if (FileUtil::Exists(dir1 + DIR_SEP + filename)) | ||||
|         LoadFromFile(dir1 + DIR_SEP + filename, title); | ||||
|     else if (FileUtil::Exists(dir2 + DIR_SEP + filename)) | ||||
| @ -146,6 +146,23 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { | ||||
|     s256_keys[{id, field1, field2}] = key; | ||||
| } | ||||
| 
 | ||||
| bool KeyManager::KeyFileExists(bool title) { | ||||
|     const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); | ||||
|     const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); | ||||
|     if (title) { | ||||
|         return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "title.keys") || | ||||
|                FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "title.keys"); | ||||
|     } | ||||
| 
 | ||||
|     if (Settings::values.use_dev_keys) { | ||||
|         return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") || | ||||
|                FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys"); | ||||
|     } | ||||
| 
 | ||||
|     return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") || | ||||
|            FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys"); | ||||
| } | ||||
| 
 | ||||
| const std::unordered_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = { | ||||
|     {"master_key_00", {S128KeyType::Master, 0, 0}}, | ||||
|     {"master_key_01", {S128KeyType::Master, 1, 0}}, | ||||
|  | ||||
| @ -102,6 +102,8 @@ public: | ||||
|     void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); | ||||
|     void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); | ||||
| 
 | ||||
|     static bool KeyFileExists(bool title); | ||||
| 
 | ||||
| private: | ||||
|     std::unordered_map<KeyIndex<S128KeyType>, Key128> s128_keys; | ||||
|     std::unordered_map<KeyIndex<S256KeyType>, Key256> s256_keys; | ||||
|  | ||||
| @ -156,9 +156,9 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | ||||
|             encrypted = true; | ||||
|         } else { | ||||
|             if (!keys.HasKey(Core::Crypto::S256KeyType::Header)) | ||||
|                 status = Loader::ResultStatus::ErrorEncrypted; | ||||
|                 status = Loader::ResultStatus::ErrorMissingKeys; | ||||
|             else | ||||
|                 status = Loader::ResultStatus::ErrorInvalidFormat; | ||||
|                 status = Loader::ResultStatus::ErrorDecrypting; | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| @ -194,6 +194,9 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | ||||
|             if (dec != nullptr) { | ||||
|                 files.emplace_back(); | ||||
|                 romfs = files.back(); | ||||
|             } else { | ||||
|                 status = Loader::ResultStatus::ErrorMissingKeys; | ||||
|                 return; | ||||
|             } | ||||
|         } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) { | ||||
|             u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) * | ||||
| @ -211,6 +214,9 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | ||||
|                     if (IsDirectoryExeFS(dirs.back())) | ||||
|                         exefs = dirs.back(); | ||||
|                 } | ||||
|             } else { | ||||
|                 status = Loader::ResultStatus::ErrorMissingKeys; | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -73,7 +73,8 @@ enum class ResultStatus { | ||||
|     ErrorNotUsed, | ||||
|     ErrorAlreadyLoaded, | ||||
|     ErrorMemoryAllocationFailed, | ||||
|     ErrorEncrypted, | ||||
|     ErrorMissingKeys, | ||||
|     ErrorDecrypting, | ||||
|     ErrorUnsupportedArch, | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -49,7 +49,7 @@ ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) { | ||||
|     } | ||||
| 
 | ||||
|     if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) { | ||||
|         return ResultStatus::ErrorEncrypted; | ||||
|         return ResultStatus::ErrorDecrypting; | ||||
|     } | ||||
| 
 | ||||
|     auto result = nca_loader->Load(process); | ||||
|  | ||||
| @ -425,18 +425,49 @@ bool GMainWindow::LoadROM(const QString& filename) { | ||||
|                                   tr("Could not determine the system mode.")); | ||||
|             break; | ||||
| 
 | ||||
|         case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: { | ||||
|         case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: { | ||||
|             const auto reg_found = Core::Crypto::KeyManager::KeyFileExists(false); | ||||
|             const auto title_found = Core::Crypto::KeyManager::KeyFileExists(true); | ||||
| 
 | ||||
|             std::string file_text; | ||||
| 
 | ||||
|             if (!reg_found && !title_found) { | ||||
|                 file_text = "A proper key file (prod.keys, dev.keys, or title.keys) could not be " | ||||
|                             "found. You will need to dump your keys from your switch to continue."; | ||||
|             } else if (reg_found && title_found) { | ||||
|                 file_text = | ||||
|                     "Both key files were found in your config directory, but the correct key could" | ||||
|                     "not be found. You may be missing a titlekey or general key, depending on " | ||||
|                     "the game."; | ||||
|             } else if (reg_found) { | ||||
|                 file_text = | ||||
|                     "The regular keys file (prod.keys/dev.keys) was found in your config, but the " | ||||
|                     "titlekeys file (title.keys) was not. You are either missing the correct " | ||||
|                     "titlekey or missing a general key required to decrypt the game."; | ||||
|             } else { | ||||
|                 file_text = "The title keys file (title.keys) was found in your config, but " | ||||
|                             "the regular keys file (prod.keys/dev.keys) was not. Unfortunately, " | ||||
|                             "having the titlekey is not enough, you need additional general keys " | ||||
|                             "to properly decrypt the game. You should double-check to make sure " | ||||
|                             "your keys are correct."; | ||||
|             } | ||||
| 
 | ||||
|             QMessageBox::critical( | ||||
|                 this, tr("Error while loading ROM!"), | ||||
|                 tr("The game that you are trying to load must be decrypted before being used with " | ||||
|                    "yuzu. A real Switch is required.<br/><br/>" | ||||
|                    "For more information on dumping and decrypting games, please see the following " | ||||
|                    "wiki pages: <ul>" | ||||
|                    "<li><a href='https://yuzu-emu.org/wiki/dumping-game-cartridges/'>Dumping Game " | ||||
|                    "Cartridges</a></li>" | ||||
|                    "<li><a href='https://yuzu-emu.org/wiki/dumping-installed-titles/'>Dumping " | ||||
|                    "Installed Titles</a></li>" | ||||
|                    "</ul>")); | ||||
|                 tr(("The game you are trying to load is encrypted and the required keys to load " | ||||
|                     "the game could not be found in your configuration. " + | ||||
|                     file_text + " Please refer to <a href=''>How to Dump Keys</a> for help.") | ||||
|                        .c_str())); | ||||
|             break; | ||||
|         } | ||||
|         case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: { | ||||
|             QMessageBox::critical( | ||||
|                 this, tr("Error while loading ROM!"), | ||||
|                 tr("There was a general error while decrypting the game. This means that the keys " | ||||
|                    "necessary were found, but were either incorrect, the game itself was not a " | ||||
|                    "valid game or the game uses an unhandled cryptographic scheme. Please refer to " | ||||
|                    "<a href=''>How to Dump Keys</a> to double check that you have the correct " | ||||
|                    "keys.")); | ||||
|             break; | ||||
|         } | ||||
|         case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: | ||||
|  | ||||
| @ -173,11 +173,15 @@ int main(int argc, char** argv) { | ||||
|     case Core::System::ResultStatus::ErrorLoader: | ||||
|         LOG_CRITICAL(Frontend, "Failed to load ROM!"); | ||||
|         return -1; | ||||
|     case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: | ||||
|         LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before " | ||||
|                                "being used with yuzu. \n\n For more information on dumping and " | ||||
|                                "decrypting games, please refer to: " | ||||
|                                "https://yuzu-emu.org/wiki/dumping-game-cartridges/"); | ||||
|     case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: | ||||
|         LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and the keys required " | ||||
|                                "could not be found. Please refer to <LINK> for help"); | ||||
|         return -1; | ||||
|     case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: | ||||
|         LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and there was a " | ||||
|                                "general error while decrypting. This could mean that the keys are " | ||||
|                                "incorrect, game is invalid or game uses an unsupported method of " | ||||
|                                "crypto. Please refer to <LINK> to double-check your keys"); | ||||
|         return -1; | ||||
|     case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: | ||||
|         LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user