diff --git a/Source/Core/Core/IOS/ES/Formats.cpp b/Source/Core/Core/IOS/ES/Formats.cpp index c28651bae7..e055f72564 100644 --- a/Source/Core/Core/IOS/ES/Formats.cpp +++ b/Source/Core/Core/IOS/ES/Formats.cpp @@ -322,7 +322,7 @@ u16 TMDReader::GetNumContents() const bool TMDReader::GetContent(u16 index, Content* content) const { - if (index >= GetNumContents()) + if (!IsValid() || index >= GetNumContents()) { return false; } diff --git a/Source/Core/DiscIO/VolumeVerifier.cpp b/Source/Core/DiscIO/VolumeVerifier.cpp index 9ffeb63757..29bd38c665 100644 --- a/Source/Core/DiscIO/VolumeVerifier.cpp +++ b/Source/Core/DiscIO/VolumeVerifier.cpp @@ -646,44 +646,65 @@ bool VolumeVerifier::CheckPartition(const Partition& partition) if (type == PARTITION_UPDATE) { const IOS::ES::TMDReader& tmd = m_volume.GetTMD(m_volume.GetGamePartition()); - - // IOS9 is the only IOS which can be assumed to exist in a working state on any Wii - // regardless of what updates have been installed. At least Mario Party 8 - // (RM8E01, revision 2) uses IOS9 without having it in its update partition. - const u64 ios_ver = tmd.GetIOSId() & 0xFF; - bool has_correct_ios = tmd.IsValid() && ios_ver == 9; - - if (!has_correct_ios && tmd.IsValid()) + if (tmd.IsValid()) { - std::unique_ptr file_info = filesystem->FindFileInfo("_sys"); - if (file_info) + const u64 ios_ver = tmd.GetIOSId() & 0xFF; + bool has_correct_ios = false; + + if (ios_ver == 9) { - const std::string ios_ver_str = std::to_string(ios_ver); - const std::string correct_ios = - IsDebugSigned() ? ("firmware.64." + ios_ver_str + ".") : ("ios" + ios_ver_str + "-"); - for (const FileInfo& f : *file_info) + // IOS9 is the only IOS which can be assumed to exist in a working state on any Wii + // regardless of what updates have been installed. At least Mario Party 8 + // (RM8E01, revision 2) uses IOS9 without having it in its update partition. + has_correct_ios = true; + } + else + { + std::unique_ptr file_info = filesystem->FindFileInfo("_sys"); + if (file_info) { - std::string file_name = f.GetName(); - Common::ToLower(&file_name); - if (file_name.starts_with(correct_ios)) + const std::string ios_ver_str = std::to_string(ios_ver); + const std::string correct_ios = + IsDebugSigned() ? ("firmware.64." + ios_ver_str + ".") : ("ios" + ios_ver_str + "-"); + for (const FileInfo& f : *file_info) { - has_correct_ios = true; - break; + std::string file_name = f.GetName(); + Common::ToLower(&file_name); + if (file_name.starts_with(correct_ios)) + { + has_correct_ios = true; + break; + } } } } - } - if (!has_correct_ios) - { - // This is reached for hacked dumps where the update partition has been replaced with - // a very old update partition so that no updates will be installed. - AddProblem( - Severity::Low, - Common::GetStringT("The update partition does not contain the IOS used by this title.")); + if (!has_correct_ios) + { + // This is reached for hacked dumps where the update partition has been replaced with + // a very old update partition so that no updates will be installed. + AddProblem(Severity::Low, + Common::GetStringT( + "The update partition does not contain the IOS used by this title.")); + } } } + const IOS::ES::TicketReader& ticket = m_volume.GetTicket(partition); + if (!ticket.IsValid()) + { + AddProblem(severity, + // i18n: "Ticket" here is a kind of digital authorization to use a certain title + // (e.g. a game) + Common::FmtFormatT("The {0} partition does not have a valid ticket.", name)); + } + + const IOS::ES::TMDReader& tmd = m_volume.GetTMD(partition); + if (!tmd.IsValid()) + { + AddProblem(severity, Common::FmtFormatT("The {0} partition does not have a valid TMD.", name)); + } + return true; } @@ -981,18 +1002,28 @@ void VolumeVerifier::CheckMisc() auto& es = ios.GetESCore(); const std::vector& cert_chain = m_volume.GetCertificateChain(PARTITION_NONE); - if (IOS::HLE::IPC_SUCCESS != - es.VerifyContainer(IOS::HLE::ESCore::VerifyContainerType::Ticket, - IOS::HLE::ESCore::VerifyMode::DoNotUpdateCertStore, m_ticket, - cert_chain)) + if (!m_ticket.IsValid()) + { + // i18n: "Ticket" here is a kind of digital authorization to use a certain title (e.g. a game) + AddProblem(Severity::High, Common::GetStringT("The ticket is invalid.")); + } + else if (IOS::HLE::IPC_SUCCESS != + es.VerifyContainer(IOS::HLE::ESCore::VerifyContainerType::Ticket, + IOS::HLE::ESCore::VerifyMode::DoNotUpdateCertStore, m_ticket, + cert_chain)) { // i18n: "Ticket" here is a kind of digital authorization to use a certain title (e.g. a game) AddProblem(Severity::Low, Common::GetStringT("The ticket is not correctly signed.")); } - if (IOS::HLE::IPC_SUCCESS != - es.VerifyContainer(IOS::HLE::ESCore::VerifyContainerType::TMD, - IOS::HLE::ESCore::VerifyMode::DoNotUpdateCertStore, tmd, cert_chain)) + if (!tmd.IsValid()) + { + AddProblem(Severity::High, Common::GetStringT("The TMD is invalid.")); + } + else if (IOS::HLE::IPC_SUCCESS != + es.VerifyContainer(IOS::HLE::ESCore::VerifyContainerType::TMD, + IOS::HLE::ESCore::VerifyMode::DoNotUpdateCertStore, tmd, + cert_chain)) { AddProblem( Severity::Medium,