diff --git a/Source/Core/DiscIO/VolumeVerifier.cpp b/Source/Core/DiscIO/VolumeVerifier.cpp index 4d1bdc9a40..af875e42f8 100644 --- a/Source/Core/DiscIO/VolumeVerifier.cpp +++ b/Source/Core/DiscIO/VolumeVerifier.cpp @@ -383,24 +383,8 @@ void VolumeVerifier::CheckDiscSize() if (!IsDisc(m_volume.GetVolumeType())) return; - const u64 biggest_offset = GetBiggestUsedOffset(); - if (biggest_offset > m_volume.GetSize()) - { - const bool second_layer_missing = - biggest_offset > SL_DVD_SIZE && m_volume.GetSize() >= SL_DVD_SIZE; - std::string text = - second_layer_missing ? - Common::GetStringT( - "This disc image is too small and lacks some data. The problem is most likely that " - "this is a dual-layer disc that has been dumped as a single-layer disc.") : - Common::GetStringT( - "This disc image is too small and lacks some data. If your dumping program saved " - "the disc image as several parts, you need to merge them into one file."); - AddProblem(Severity::High, std::move(text)); - return; - } - - if (ShouldBeDualLayer() && biggest_offset <= SL_DVD_R_SIZE) + m_biggest_referenced_offset = GetBiggestReferencedOffset(); + if (ShouldBeDualLayer() && m_biggest_referenced_offset <= SL_DVD_R_SIZE) { AddProblem(Severity::Medium, Common::GetStringT( @@ -458,7 +442,7 @@ void VolumeVerifier::CheckDiscSize() } } -u64 VolumeVerifier::GetBiggestUsedOffset() const +u64 VolumeVerifier::GetBiggestReferencedOffset() const { std::vector partitions = m_volume.GetPartitions(); if (partitions.empty()) @@ -497,20 +481,20 @@ u64 VolumeVerifier::GetBiggestUsedOffset() const if (fs) { const u64 offset = - m_volume.PartitionOffsetToRawOffset(GetBiggestUsedOffset(fs->GetRoot()), partition); + m_volume.PartitionOffsetToRawOffset(GetBiggestReferencedOffset(fs->GetRoot()), partition); biggest_offset = std::max(biggest_offset, offset); } } return biggest_offset; } -u64 VolumeVerifier::GetBiggestUsedOffset(const FileInfo& file_info) const +u64 VolumeVerifier::GetBiggestReferencedOffset(const FileInfo& file_info) const { if (file_info.IsDirectory()) { u64 biggest_offset = 0; for (const FileInfo& f : file_info) - biggest_offset = std::max(biggest_offset, GetBiggestUsedOffset(f)); + biggest_offset = std::max(biggest_offset, GetBiggestReferencedOffset(f)); return biggest_offset; } else @@ -821,9 +805,14 @@ void VolumeVerifier::Process() m_blocks[block_index].partition); } - if (!success) + const u64 offset = m_blocks[block_index].offset; + if (success) + { + m_biggest_verified_offset = + std::max(m_biggest_verified_offset, offset + VolumeWii::BLOCK_TOTAL_SIZE); + } + else { - const u64 offset = m_blocks[block_index].offset; if (m_scrubber.CanBlockBeScrubbed(offset)) { WARN_LOG(DISCIO, "Integrity check failed for unused block at 0x%" PRIx64, offset); @@ -894,6 +883,27 @@ void VolumeVerifier::Finish() } } + if (IsDisc(m_volume.GetVolumeType()) && + (m_volume.IsSizeAccurate() || m_volume.SupportsIntegrityCheck())) + { + u64 volume_size = m_volume.IsSizeAccurate() ? m_volume.GetSize() : m_biggest_verified_offset; + if (m_biggest_referenced_offset > volume_size) + { + const bool second_layer_missing = + m_biggest_referenced_offset > SL_DVD_SIZE && m_volume.GetSize() >= SL_DVD_SIZE; + std::string text = + second_layer_missing ? + Common::GetStringT("This disc image is too small and lacks some data. The problem is " + "most likely that this is a dual-layer disc that has been dumped " + "as a single-layer disc.") : + Common::GetStringT("This disc image is too small and lacks some data. If your " + "dumping program saved the disc image as several parts, you need " + "to merge them into one file."); + AddProblem(Severity::High, std::move(text)); + return; + } + } + for (auto [partition, blocks] : m_block_errors) { if (blocks > 0) diff --git a/Source/Core/DiscIO/VolumeVerifier.h b/Source/Core/DiscIO/VolumeVerifier.h index 713836de5b..b6bec4ac13 100644 --- a/Source/Core/DiscIO/VolumeVerifier.h +++ b/Source/Core/DiscIO/VolumeVerifier.h @@ -96,8 +96,8 @@ private: bool ShouldHaveMasterpiecePartitions() const; bool ShouldBeDualLayer() const; void CheckDiscSize(); - u64 GetBiggestUsedOffset() const; - u64 GetBiggestUsedOffset(const FileInfo& file_info) const; + u64 GetBiggestReferencedOffset() const; + u64 GetBiggestReferencedOffset(const FileInfo& file_info) const; void CheckMisc(); void SetUpHashing(); void WaitForAsyncOperations() const; @@ -134,6 +134,9 @@ private: std::map m_block_errors; std::map m_unused_block_errors; + u64 m_biggest_referenced_offset = 0; + u64 m_biggest_verified_offset = 0; + bool m_started = false; bool m_done = false; u64 m_progress = 0;