diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index bd4b3d7c7..6f27f990b 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -237,7 +237,7 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { Key128 rights_id; std::memcpy(rights_id.data(), &field2, sizeof(u64)); std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64)); - WriteKeyToFile(true, fmt::format("{}", Common::HexArrayToString(rights_id)), key); + WriteKeyToFile(true, Common::HexArrayToString(rights_id), key); } const auto iter2 = std::find_if( s128_file_id.begin(), s128_file_id.end(), diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index d0f1afac0..e07ac8503 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -12,6 +12,7 @@ #include "core/file_sys/content_archive.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/partition_filesystem.h" +#include "core/file_sys/submission_package.h" #include "core/file_sys/vfs_offset.h" #include "core/loader/loader.h" diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index b73f1d900..4d07d3d05 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -11,7 +11,6 @@ #include "common/swap.h" #include "core/file_sys/vfs.h" #include "core/loader/loader.h" -#include "submission_package.h" namespace Loader { enum class ResultStatus : u16; @@ -21,6 +20,7 @@ namespace FileSys { class NCA; enum class NCAContentType : u8; +class NSP; enum class GamecardSize : u8 { S_1GB = 0xFA, diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index 660771cf8..ce05a5845 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -72,21 +72,21 @@ NSP::NSP(VirtualFile file_) ncas_title[ContentRecordType::Meta] = nca; for (const auto& rec : cnmt.GetContentRecords()) { - const auto next_file = pfs->GetFile( - fmt::format("{}.nca", Common::HexArrayToString(rec.nca_id, false))); + const auto id_string = Common::HexArrayToString(rec.nca_id, false); + const auto next_file = pfs->GetFile(fmt::format("{}.nca", id_string)); if (next_file == nullptr) { LOG_WARNING(Service_FS, "NCA with ID {}.nca is listed in content metadata, but cannot " "be found in PFS. NSP appears to be corrupted.", - Common::HexArrayToString(rec.nca_id, false)); + id_string); continue; } - const auto next_nca = std::make_shared(next_file); + auto next_nca = std::make_shared(next_file); if (next_nca->GetType() == NCAContentType::Program) program_status[cnmt.GetTitleID()] = next_nca->GetStatus(); if (next_nca->GetStatus() == Loader::ResultStatus::Success) - ncas_title[rec.type] = next_nca; + ncas_title[rec.type] = std::move(next_nca); } break; @@ -95,14 +95,17 @@ NSP::NSP(VirtualFile file_) } } +NSP::~NSP() = default; + Loader::ResultStatus NSP::GetStatus() const { return status; } Loader::ResultStatus NSP::GetProgramStatus(u64 title_id) const { - if (program_status.find(title_id) != program_status.end()) - return program_status.at(title_id); - return Loader::ResultStatus::ErrorNSPMissingProgramNCA; + const auto iter = program_status.find(title_id); + if (iter == program_status.end()) + return Loader::ResultStatus::ErrorNSPMissingProgramNCA; + return iter->second; } u64 NSP::GetFirstTitleID() const { @@ -112,16 +115,19 @@ u64 NSP::GetFirstTitleID() const { } u64 NSP::GetProgramTitleID() const { - auto out = GetFirstTitleID(); - for (const auto other_tid : GetTitleIDs()) { - if ((out & 0x800) != 0) - out = other_tid; - } - return out; + const auto out = GetFirstTitleID(); + if ((out & 0x800) == 0) + return out; + + const auto ids = GetTitleIDs(); + const auto iter = + std::find_if(ids.begin(), ids.end(), [](u64 tid) { return (tid & 0x800) == 0; }); + return iter == ids.end() ? out : *iter; } std::vector NSP::GetTitleIDs() const { std::vector out; + out.reserve(ncas.size()); for (const auto& kv : ncas) out.push_back(kv.first); return out; @@ -156,7 +162,7 @@ std::multimap> NSP::GetNCAsByTitleID() const { std::multimap> out; for (const auto& map : ncas) { for (const auto& inner_map : map.second) - out.insert({map.first, inner_map.second}); + out.emplace(map.first, inner_map.second); } return out; } @@ -168,13 +174,16 @@ std::map>> NSP::GetNCAs() std::shared_ptr NSP::GetNCA(u64 title_id, ContentRecordType type) const { if (extracted) LOG_WARNING(Service_FS, "called on an NSP that is of type extracted."); - if (ncas.find(title_id) != ncas.end()) { - const auto& inner_map = ncas.at(title_id); - if (inner_map.find(type) != inner_map.end()) - return inner_map.at(type); - } - return nullptr; + const auto title_id_iter = ncas.find(title_id); + if (title_id_iter == ncas.end()) + return nullptr; + + const auto type_iter = title_id_iter->second.find(type); + if (type_iter == title_id_iter->second.end()) + return nullptr; + + return type_iter->second; } VirtualFile NSP::GetNCAFile(u64 title_id, ContentRecordType type) const { @@ -197,9 +206,9 @@ std::vector NSP::GetTitlekey() const { continue; } - Core::Crypto::Key128 key{}; - ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET); - out.push_back(key); + out.emplace_back(); + ticket_file->Read(out.back().data(), out.back().size(), + Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET); } return out; } diff --git a/src/core/file_sys/submission_package.h b/src/core/file_sys/submission_package.h index 7b520df57..482a8b71f 100644 --- a/src/core/file_sys/submission_package.h +++ b/src/core/file_sys/submission_package.h @@ -10,6 +10,7 @@ #include "common/common_types.h" #include "common/swap.h" #include "core/file_sys/content_archive.h" +#include "core/file_sys/romfs_factory.h" #include "core/file_sys/vfs.h" #include "core/loader/loader.h" #include "romfs_factory.h" @@ -19,6 +20,7 @@ namespace FileSys { class NSP : public ReadOnlyVfsDirectory { public: explicit NSP(VirtualFile file); + ~NSP(); Loader::ResultStatus GetStatus() const; Loader::ResultStatus GetProgramStatus(u64 title_id) const; diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 75d9fc1bc..b59d40052 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -21,22 +21,27 @@ namespace Loader { AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file) : AppLoader(file), nsp(std::make_unique(file)), title_id(nsp->GetProgramTitleID()) { + if (nsp->GetStatus() != ResultStatus::Success) return; if (nsp->IsExtractedType()) return; + const auto control_nca = nsp->GetNCA(nsp->GetFirstTitleID(), FileSys::ContentRecordType::Control); if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) return; + const auto romfs = FileSys::ExtractRomFS(control_nca->GetRomFS()); if (romfs == nullptr) return; + for (const auto& language : FileSys::LANGUAGE_NAMES) { icon_file = romfs->GetFile("icon_" + std::string(language) + ".dat"); if (icon_file != nullptr) break; } + const auto nacp_raw = romfs->GetFile("control.nacp"); if (nacp_raw == nullptr) return; @@ -51,15 +56,17 @@ FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& file) { if (nsp.GetStatus() == ResultStatus::Success) { // Extracted Type case if (nsp.IsExtractedType() && nsp.GetExeFS() != nullptr && - FileSys::IsDirectoryExeFS(nsp.GetExeFS()) && nsp.GetRomFS() != nullptr) + FileSys::IsDirectoryExeFS(nsp.GetExeFS()) && nsp.GetRomFS() != nullptr) { return FileType::NSP; + } // Non-Ectracted Type case if (!nsp.IsExtractedType() && nsp.GetNCA(nsp.GetFirstTitleID(), FileSys::ContentRecordType::Program) != nullptr && AppLoader_NCA::IdentifyType(nsp.GetNCAFile( - nsp.GetFirstTitleID(), FileSys::ContentRecordType::Program)) == FileType::NCA) + nsp.GetFirstTitleID(), FileSys::ContentRecordType::Program)) == FileType::NCA) { return FileType::NSP; + } } return FileType::Error; diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index 785feaf37..7ef810499 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -22,7 +22,7 @@ class AppLoader_NCA; class AppLoader_NSP final : public AppLoader { public: explicit AppLoader_NSP(FileSys::VirtualFile file); - ~AppLoader_NSP(); + ~AppLoader_NSP() override; /** * Returns the type of the file