From 22ebf68b90584349934325d76e4feb524422f330 Mon Sep 17 00:00:00 2001 From: Pengfei Date: Wed, 4 Aug 2021 09:58:17 +0800 Subject: [PATCH] Remove ResultStatus And instead use bool to represent result, which is simpler and more consistent, as there's no error reporting anyways. --- src/core/CMakeLists.txt | 1 - src/core/importer.cpp | 25 ++-- src/core/ncch/cia_builder.cpp | 8 +- src/core/ncch/ncch_container.cpp | 195 +++++++++++++++---------------- src/core/ncch/ncch_container.h | 31 ++--- src/core/ncch/title_metadata.cpp | 26 ++--- src/core/ncch/title_metadata.h | 7 +- src/core/result_status.h | 19 --- 8 files changed, 137 insertions(+), 175 deletions(-) delete mode 100644 src/core/result_status.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 322a4c9..06381fa 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -31,7 +31,6 @@ add_library(core STATIC ncch/title_metadata.h quick_decryptor.cpp quick_decryptor.h - result_status.h savegame.cpp savegame.h title_db.cpp diff --git a/src/core/importer.cpp b/src/core/importer.cpp index fd13e5f..d655b44 100644 --- a/src/core/importer.cpp +++ b/src/core/importer.cpp @@ -506,10 +506,9 @@ bool SDMCImporter::LoadTMD(ContentType type, u64 id, TitleMetadata& out) const { LOG_ERROR(Core, "Could not open {} or file too big", tmd_path); return false; } - return out.Load(file.GetData()) == ResultStatus::Success; + return out.Load(file.GetData()); } else { - return out.Load(decryptor->DecryptFile(tmd_path.substr(config.sdmc_path.size() - 1))) == - ResultStatus::Success; + return out.Load(decryptor->DecryptFile(tmd_path.substr(config.sdmc_path.size() - 1))); } } @@ -530,7 +529,7 @@ TitleData LoadTitleData(NCCHContainer& ncch) { } std::vector smdh_buffer; - if (ncch.LoadSectionExeFS("icon", smdh_buffer) != ResultStatus::Success) { + if (!ncch.LoadSectionExeFS("icon", smdh_buffer)) { LOG_WARNING(Core, "Failed to load icon in ExeFS"); TitleData data{}; std::get<0>(data) = std::move(title_name_from_codeset); @@ -590,8 +589,7 @@ static std::string GetTitleFileName(NCCHContainer& ncch) { ncch.ReadProgramId(program_id); std::vector smdh_buffer; - if (ncch.LoadSectionExeFS("icon", smdh_buffer) != ResultStatus::Success || - smdh_buffer.size() != sizeof(SMDH)) { + if (!ncch.LoadSectionExeFS("icon", smdh_buffer) || smdh_buffer.size() != sizeof(SMDH)) { LOG_WARNING(Core, "Failed to load icon in ExeFS or size incorrect"); return NormalizeFilename( fmt::format("{:016x} {} ({})", program_id, codeset_name, product_code)); @@ -636,13 +634,12 @@ bool SDMCImporter::DumpCXI(const ContentSpecifier& specifier, std::string destin return false; } - if (dump_cxi_ncch->DecryptToFile(std::make_shared(destination, "wb"), - callback) == ResultStatus::Success) { - return true; + if (!dump_cxi_ncch->DecryptToFile(std::make_shared(destination, "wb"), + callback)) { + FileUtil::Delete(destination); + return false; } - - FileUtil::Delete(destination); - return false; + return true; } void SDMCImporter::AbortDumpCXI() { @@ -828,7 +825,7 @@ void SDMCImporter::ListTitle(std::vector& out) const { virtual_name, tmd.GetBootContentID()); NCCHContainer ncch( std::make_shared(sdmc_path, boot_content_path, "rb")); - if (ncch.Load() != ResultStatus::Success) { + if (!ncch.Load()) { LOG_WARNING(Core, "Could not load NCCH {}", boot_content_path); out.push_back({type, id, FileUtil::Exists(citra_path + "content/"), FileUtil::GetDirectoryTreeSize(directory + virtual_name + @@ -907,7 +904,7 @@ void SDMCImporter::ListNandTitle(std::vector& out) const { fmt::format("{}{:08x}.app", content_path, tmd.GetBootContentID()); NCCHContainer ncch( std::make_shared(boot_content_path, "rb")); - if (ncch.Load() != ResultStatus::Success) { + if (!ncch.Load()) { LOG_WARNING(Core, "Could not load NCCH {}", boot_content_path); out.push_back({ContentType::SystemTitle, id, FileUtil::Exists(citra_path + "content/"), diff --git a/src/core/ncch/cia_builder.cpp b/src/core/ncch/cia_builder.cpp index f0ea10f..60fa1df 100644 --- a/src/core/ncch/cia_builder.cpp +++ b/src/core/ncch/cia_builder.cpp @@ -243,7 +243,7 @@ private: }; bool CIABuilder::AddContent(u16 content_id, NCCHContainer& ncch) { - if (ncch.Load() != ResultStatus::Success) { + if (!ncch.Load()) { return false; } @@ -267,7 +267,7 @@ bool CIABuilder::AddContent(u16 content_id, NCCHContainer& ncch) { abort_ncch = nullptr; } - if (ret != ResultStatus::Success) { + if (!ret) { return false; } file->GetHash(tmd_chunk.hash.data()); @@ -332,7 +332,7 @@ bool CIABuilder::AddContent(u16 content_id, NCCHContainer& ncch) { meta.core_version = ncch.exheader_header.arm11_system_local_caps.core_version; std::vector smdh_buffer; - if (ncch.LoadSectionExeFS("icon", smdh_buffer) != ResultStatus::Success) { + if (!ncch.LoadSectionExeFS("icon", smdh_buffer)) { LOG_WARNING(Core, "Failed to load icon in ExeFS"); return true; } @@ -355,7 +355,7 @@ bool CIABuilder::Finalize() { tmd.FixHashes(); } file->Seek(tmd_offset, SEEK_SET); - if (tmd.Save(*file) != ResultStatus::Success) { + if (!tmd.Save(*file)) { return false; } diff --git a/src/core/ncch/ncch_container.cpp b/src/core/ncch/ncch_container.cpp index 8dbea31..3fb6eb2 100644 --- a/src/core/ncch/ncch_container.cpp +++ b/src/core/ncch/ncch_container.cpp @@ -27,34 +27,37 @@ static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes) NCCHContainer::NCCHContainer(std::shared_ptr file_) : file(std::move(file_)) {} -ResultStatus NCCHContainer::OpenFile(std::shared_ptr file_) { +bool NCCHContainer::OpenFile(std::shared_ptr file_) { file = std::move(file_); if (!file->IsOpen()) { LOG_WARNING(Service_FS, "Failed to open"); - return ResultStatus::Error; + return false; } LOG_DEBUG(Service_FS, "Opened"); - return ResultStatus::Success; + return true; } -ResultStatus NCCHContainer::Load() { +bool NCCHContainer::Load() { if (is_loaded) - return ResultStatus::Success; + return true; if (file->IsOpen()) { // Reset read pointer in case this file has been read before. file->Seek(0, SEEK_SET); - if (file->ReadBytes(&ncch_header, sizeof(NCCH_Header)) != sizeof(NCCH_Header)) - return ResultStatus::Error; + if (file->ReadBytes(&ncch_header, sizeof(NCCH_Header)) != sizeof(NCCH_Header)) { + LOG_ERROR(Service_FS, "Could not read from file"); + return false; + } // Verify we are loading the correct file type... - if (MakeMagic('N', 'C', 'C', 'H') != ncch_header.magic) - return ResultStatus::ErrorInvalidFormat; + if (MakeMagic('N', 'C', 'C', 'H') != ncch_header.magic) { + LOG_ERROR(Service_FS, "Invalid magic, file may be corrupted"); + return false; + } - has_header = true; bool failed_to_decrypt = false; if (!ncch_header.no_crypto) { is_encrypted = true; @@ -173,13 +176,10 @@ ResultStatus NCCHContainer::Load() { // System archives and DLC don't have an extended header but have RomFS if (ncch_header.extended_header_size) { - auto read_exheader = [this](FileUtil::IOFile& file) { - const std::size_t size = sizeof(exheader_header); - return file && file.ReadBytes(&exheader_header, size) == size; - }; - - if (!read_exheader(*file)) { - return ResultStatus::Error; + if (file->ReadBytes(&exheader_header, + sizeof(exheader_header) != sizeof(exheader_header))) { + LOG_ERROR(Service_FS, "Could not read exheader from file"); + return false; } if (is_encrypted) { @@ -193,7 +193,7 @@ ResultStatus NCCHContainer::Load() { } else { if (failed_to_decrypt) { LOG_ERROR(Service_FS, "Failed to decrypt"); - return ResultStatus::ErrorEncrypted; + return false; } CryptoPP::byte* data = reinterpret_cast(&exheader_header); CryptoPP::CTR_Mode::Decryption( @@ -235,8 +235,10 @@ ResultStatus NCCHContainer::Load() { LOG_DEBUG(Service_FS, "ExeFS offset: 0x{:08X}", exefs_offset); LOG_DEBUG(Service_FS, "ExeFS size: 0x{:08X}", exefs_size); file->Seek(exefs_offset, SEEK_SET); - if (file->ReadBytes(&exefs_header, sizeof(ExeFs_Header)) != sizeof(ExeFs_Header)) - return ResultStatus::Error; + if (file->ReadBytes(&exefs_header, sizeof(ExeFs_Header)) != sizeof(ExeFs_Header)) { + LOG_ERROR(Service_FS, "Could not read ExeFS header from file"); + return false; + } if (is_encrypted) { CryptoPP::byte* data = reinterpret_cast(&exefs_header); @@ -254,16 +256,18 @@ ResultStatus NCCHContainer::Load() { } is_loaded = true; - return ResultStatus::Success; + return true; } -ResultStatus NCCHContainer::LoadSectionExeFS(const char* name, std::vector& buffer) { - ResultStatus result = Load(); - if (result != ResultStatus::Success) - return result; +bool NCCHContainer::LoadSectionExeFS(const char* name, std::vector& buffer) { + if (!Load()) { + return false; + } - if (!exefs_file || !exefs_file->IsOpen()) - return ResultStatus::Error; + if (!exefs_file || !exefs_file->IsOpen()) { + LOG_ERROR(Service_FS, "NCCH does not have ExeFS"); + return false; + } LOG_DEBUG(Service_FS, "{} sections:", kMaxSections); // Iterate through the ExeFs archive until we find a section with the specified name... @@ -283,36 +287,36 @@ ResultStatus NCCHContainer::LoadSectionExeFS(const char* name, std::vector& buffer.resize(section.size); if (exefs_file->ReadBytes(&buffer[0], section.size) != section.size) - return ResultStatus::Error; + return false; if (is_encrypted) { dec.ProcessData(&buffer[0], &buffer[0], section.size); } - return ResultStatus::Success; + return true; } } - return ResultStatus::ErrorNotUsed; + LOG_ERROR(Service_FS, "Section {} not found", name); + return false; } -ResultStatus NCCHContainer::ReadProgramId(u64_le& program_id) { - ResultStatus result = Load(); - if (result != ResultStatus::Success) - return result; - - if (!has_header) - return ResultStatus::ErrorNotUsed; +bool NCCHContainer::ReadProgramId(u64_le& program_id) { + if (!Load()) { + return false; + } program_id = ncch_header.program_id; - return ResultStatus::Success; + return true; } -ResultStatus NCCHContainer::ReadExtdataId(u64& extdata_id) { - ResultStatus result = Load(); - if (result != ResultStatus::Success) - return result; +bool NCCHContainer::ReadExtdataId(u64& extdata_id) { + if (!Load()) { + return false; + } - if (!has_exheader) - return ResultStatus::ErrorNotUsed; + if (!has_exheader) { + LOG_ERROR(Service_FS, "NCCH does not have ExHeader"); + return false; + } if (exheader_header.arm11_system_local_caps.storage_info.other_attributes >> 1) { // Using extended save data access @@ -330,65 +334,65 @@ ResultStatus NCCHContainer::ReadExtdataId(u64& extdata_id) { if (id) { // Found a non-zero ID, use it extdata_id = id; - return ResultStatus::Success; + return true; } } - return ResultStatus::ErrorNotUsed; + LOG_INFO(Service_FS, "Title does not have extdata ID"); + return false; } extdata_id = exheader_header.arm11_system_local_caps.storage_info.ext_save_data_id; - return ResultStatus::Success; + return true; } bool NCCHContainer::HasExeFS() { - ResultStatus result = Load(); - if (result != ResultStatus::Success) + if (!Load()) { return false; + } return has_exefs; } bool NCCHContainer::HasExHeader() { - ResultStatus result = Load(); - if (result != ResultStatus::Success) + if (!Load()) { return false; + } return has_exheader; } -ResultStatus NCCHContainer::ReadCodesetName(std::string& name) { - ResultStatus result = Load(); - if (result != ResultStatus::Success) - return result; +bool NCCHContainer::ReadCodesetName(std::string& name) { + if (!Load()) { + return false; + } - if (!has_exheader) - return ResultStatus::ErrorNotUsed; + if (!has_exheader) { + LOG_ERROR(Service_FS, "NCCH does not have ExHeader"); + return false; + } std::array name_data{}; std::memcpy(name_data.data(), exheader_header.codeset_info.name, 8); name = name_data.data(); - return ResultStatus::Success; + return true; } -ResultStatus NCCHContainer::ReadProductCode(std::string& product_code) { - ResultStatus result = Load(); - if (result != ResultStatus::Success) - return result; +bool NCCHContainer::ReadProductCode(std::string& product_code) { + if (!Load()) { + return false; + } std::array data{}; std::memcpy(data.data(), ncch_header.product_code, 16); product_code = data.data(); - return ResultStatus::Success; + return true; } -ResultStatus NCCHContainer::ReadEncryptionType(EncryptionType& encryption) { - ResultStatus result = Load(); - if (result != ResultStatus::Success) - return result; - - if (!has_header) - return ResultStatus::ErrorNotUsed; +bool NCCHContainer::ReadEncryptionType(EncryptionType& encryption) { + if (!Load()) { + return false; + } if (!is_encrypted) { encryption = EncryptionType::None; @@ -410,37 +414,31 @@ ResultStatus NCCHContainer::ReadEncryptionType(EncryptionType& encryption) { break; default: LOG_ERROR(Service_FS, "Unknown encryption type {:X}!", ncch_header.secondary_key_slot); - return ResultStatus::ErrorNotUsed; + return false; } } - return ResultStatus::Success; + return true; } -ResultStatus NCCHContainer::ReadSeedCrypto(bool& used) { - ResultStatus result = Load(); - if (result != ResultStatus::Success) - return result; - - if (!has_header) - return ResultStatus::ErrorNotUsed; +bool NCCHContainer::ReadSeedCrypto(bool& used) { + if (!Load()) { + return false; + } used = ncch_header.seed_crypto; - return ResultStatus::Success; + return true; } -ResultStatus NCCHContainer::DecryptToFile(std::shared_ptr dest_file, - const Common::ProgressCallback& callback) { - ResultStatus result = Load(); - if (result != ResultStatus::Success) - return result; - - if (!has_header) - return ResultStatus::ErrorNotUsed; +bool NCCHContainer::DecryptToFile(std::shared_ptr dest_file, + const Common::ProgressCallback& callback) { + if (!Load()) { + return false; + } if (!*dest_file) { LOG_ERROR(Core, "File is not open"); - return ResultStatus::Error; + return false; } if (!is_encrypted) { @@ -451,8 +449,7 @@ ResultStatus NCCHContainer::DecryptToFile(std::shared_ptr dest decryptor.Reset(size); decryptor.SetCrypto(nullptr); - const bool ret = decryptor.CryptAndWriteFile(file, size, dest_file, callback); - return ret ? ResultStatus::Success : ResultStatus::Error; + return decryptor.CryptAndWriteFile(file, size, dest_file, callback); } const auto total_size = file->GetSize(); @@ -476,7 +473,7 @@ ResultStatus NCCHContainer::DecryptToFile(std::shared_ptr dest if (dest_file->WriteBytes(&modified_header, sizeof(modified_header)) != sizeof(modified_header)) { LOG_ERROR(Core, "Could not write NCCH header to file"); - return ResultStatus::Error; + return false; } written += sizeof(NCCH_Header); @@ -485,7 +482,7 @@ ResultStatus NCCHContainer::DecryptToFile(std::shared_ptr dest if (dest_file->WriteBytes(&exheader_header, sizeof(exheader_header)) != sizeof(exheader_header)) { LOG_ERROR(Core, "Could not write Exheader to file"); - return ResultStatus::Error; + return false; } written += sizeof(ExHeader_Header); } @@ -533,19 +530,19 @@ ResultStatus NCCHContainer::DecryptToFile(std::shared_ptr dest if (!Write("logo", ncch_header.logo_region_offset * 0x200, ncch_header.logo_region_size * 0x200)) { - return ResultStatus::Error; + return false; } if (!Write("plain region", ncch_header.plain_region_offset * 0x200, ncch_header.plain_region_size * 0x200)) { - return ResultStatus::Error; + return false; } // Write ExeFS header if (has_exefs) { if (dest_file->WriteBytes(&exefs_header, sizeof(exefs_header)) != sizeof(exefs_header)) { LOG_ERROR(Core, "Could not write ExeFS header to file"); - return ResultStatus::Error; + return false; } written += sizeof(ExeFs_Header); @@ -565,21 +562,21 @@ ResultStatus NCCHContainer::DecryptToFile(std::shared_ptr dest // Plus 1 for the ExeFS header if (!Write(section.name, section.offset + (ncch_header.exefs_offset + 1) * 0x200, section.size, true, key, exefs_ctr, section.offset + sizeof(exefs_header))) { - return ResultStatus::Error; + return false; } } } if (has_romfs && !Write("romfs", ncch_header.romfs_offset * 0x200, ncch_header.romfs_size * 0x200, true, secondary_key, romfs_ctr)) { - return ResultStatus::Error; + return false; } if (written < total_size) { LOG_WARNING(Core, "Data after {} ignored", written); } callback(total_size, total_size); - return ResultStatus::Success; + return true; } void NCCHContainer::AbortDecryptToFile() { diff --git a/src/core/ncch/ncch_container.h b/src/core/ncch/ncch_container.h index 371bc08..5ee97b5 100644 --- a/src/core/ncch/ncch_container.h +++ b/src/core/ncch/ncch_container.h @@ -14,7 +14,6 @@ #include "common/progress_callback.h" #include "common/swap.h" #include "core/decryptor.h" -#include "core/result_status.h" namespace Core { @@ -211,33 +210,29 @@ public: NCCHContainer(std::shared_ptr file); NCCHContainer() {} - ResultStatus OpenFile(std::shared_ptr file); + bool OpenFile(std::shared_ptr file); /** * Ensure ExeFS and exheader is loaded and ready for reading sections - * @return ResultStatus result of function */ - ResultStatus Load(); + bool Load(); /** * Reads an application ExeFS section of an NCCH file (non-compressed, primary key only) * @param name Name of section to read out of NCCH file * @param buffer Vector to read data into - * @return ResultStatus result of function */ - ResultStatus LoadSectionExeFS(const char* name, std::vector& buffer); + bool LoadSectionExeFS(const char* name, std::vector& buffer); /** * Get the Program ID of the NCCH container - * @return ResultStatus result of function */ - ResultStatus ReadProgramId(u64_le& program_id); + bool ReadProgramId(u64_le& program_id); /** * Get the Extdata ID of the NCCH container - * @return ResultStatus result of function */ - ResultStatus ReadExtdataId(u64& extdata_id); + bool ReadExtdataId(u64& extdata_id); /** * Checks whether the NCCH container contains an ExeFS @@ -253,33 +248,28 @@ public: /** * Reads the name of the codeset. - * @return ResultStatus result of function. */ - ResultStatus ReadCodesetName(std::string& name); + bool ReadCodesetName(std::string& name); /** * Reads the product code. - * @return ResultStatus result of function. */ - ResultStatus ReadProductCode(std::string& name); + bool ReadProductCode(std::string& name); /** * Gets encryption type (which key is used). - * @return ResultStatus result of function. */ - ResultStatus ReadEncryptionType(EncryptionType& encryption); + bool ReadEncryptionType(EncryptionType& encryption); /** * Gets whether seed crypto is used. - * @return ResultStatus result of function. */ - ResultStatus ReadSeedCrypto(bool& used); + bool ReadSeedCrypto(bool& used); /** * Decrypts this NCCH and write to the destination file. - * @return ResultStatus result of function. */ - ResultStatus DecryptToFile( + bool DecryptToFile( std::shared_ptr dest_file, const Common::ProgressCallback& callback = [](std::size_t, std::size_t) {}); @@ -293,7 +283,6 @@ public: ExeFs_Header exefs_header; private: - bool has_header = false; bool has_exheader = false; bool has_exefs = false; bool has_romfs = false; diff --git a/src/core/ncch/title_metadata.cpp b/src/core/ncch/title_metadata.cpp index 2fc8cd0..d47b3ce 100644 --- a/src/core/ncch/title_metadata.cpp +++ b/src/core/ncch/title_metadata.cpp @@ -17,18 +17,18 @@ namespace Core { -ResultStatus TitleMetadata::Load(const std::vector file_data, std::size_t offset) { +bool TitleMetadata::Load(const std::vector file_data, std::size_t offset) { std::size_t total_size = static_cast(file_data.size() - offset); if (total_size < sizeof(u32_be)) - return ResultStatus::Error; + return false; if (!signature.Load(file_data, offset)) { - return ResultStatus::Error; + return false; } const auto signature_size = signature.GetSize(); std::size_t body_end = signature_size + sizeof(Body); if (total_size < body_end) - return ResultStatus::Error; + return false; // Read TMD body, then load the amount of ContentChunks specified std::memcpy(&tmd_body, &file_data[offset + signature_size], sizeof(TitleMetadata::Body)); @@ -38,7 +38,7 @@ ResultStatus TitleMetadata::Load(const std::vector file_data, std::size_t of if (total_size < expected_size) { LOG_ERROR(Service_FS, "Malformed TMD, expected size 0x{:x}, got 0x{:x}!", expected_size, total_size); - return ResultStatus::ErrorInvalidFormat; + return false; } for (u16 i = 0; i < tmd_body.content_count; i++) { @@ -49,33 +49,33 @@ ResultStatus TitleMetadata::Load(const std::vector file_data, std::size_t of tmd_chunks.push_back(chunk); } - return ResultStatus::Success; + return true; } -ResultStatus TitleMetadata::Save(FileUtil::IOFile& file) { +bool TitleMetadata::Save(FileUtil::IOFile& file) { const std::size_t offset = file.Tell(); if (!file.IsOpen()) - return ResultStatus::Error; + return false; if (!signature.Save(file)) { - return ResultStatus::Error; + return false; } // Write our TMD body, then write each of our ContentChunks if (file.WriteBytes(&tmd_body, sizeof(TitleMetadata::Body)) != sizeof(TitleMetadata::Body)) - return ResultStatus::Error; + return false; for (u16 i = 0; i < tmd_body.content_count; i++) { ContentChunk chunk = tmd_chunks[i]; if (file.WriteBytes(&chunk, sizeof(ContentChunk)) != sizeof(ContentChunk)) - return ResultStatus::Error; + return false; } - return ResultStatus::Success; + return true; } -ResultStatus TitleMetadata::Save(const std::string& file_path) { +bool TitleMetadata::Save(const std::string& file_path) { FileUtil::IOFile file(file_path, "wb"); return Save(file); } diff --git a/src/core/ncch/title_metadata.h b/src/core/ncch/title_metadata.h index 98a9314..b6ac1bc 100644 --- a/src/core/ncch/title_metadata.h +++ b/src/core/ncch/title_metadata.h @@ -10,7 +10,6 @@ #include "common/common_types.h" #include "common/swap.h" #include "core/ncch/signature.h" -#include "core/result_status.h" namespace Core { @@ -79,9 +78,9 @@ public: #pragma pack(pop) - ResultStatus Load(const std::vector file_data, std::size_t offset = 0); - ResultStatus Save(FileUtil::IOFile& file); - ResultStatus Save(const std::string& file_path); + bool Load(const std::vector file_data, std::size_t offset = 0); + bool Save(FileUtil::IOFile& file); + bool Save(const std::string& file_path); void FixHashes(); bool VerifyHashes() const; diff --git a/src/core/result_status.h b/src/core/result_status.h deleted file mode 100644 index b25ff9d..0000000 --- a/src/core/result_status.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 Citra Emulator Project / 2019 threeSD Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -/// Result code for operations -enum class ResultStatus { - Success, - Error, - // Citra loader errors - ErrorInvalidFormat, - ErrorNotImplemented, - ErrorNotLoaded, - ErrorNotUsed, - ErrorAlreadyLoaded, - ErrorMemoryAllocationFailed, - ErrorEncrypted, -};