mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-06-23 04:52:12 -05:00
We had some code in VolumeVerifier to catch the error message that Redump.org used to show when trying to access the Wii datfile without logging in. This restriction was removed from Redump.org around the start of 2022, and the code has been unnecessary ever since.
209 lines
4.7 KiB
C++
209 lines
4.7 KiB
C++
// Copyright 2019 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <future>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <mbedtls/md5.h>
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/Crypto/SHA1.h"
|
|
#include "Core/IOS/ES/Formats.h"
|
|
#include "DiscIO/DiscScrubber.h"
|
|
#include "DiscIO/Volume.h"
|
|
|
|
// To be used as follows:
|
|
//
|
|
// VolumeVerifier verifier(volume, redump_verification, hashes_to_calculate);
|
|
// verifier.Start();
|
|
// while (verifier.GetBytesProcessed() != verifier.GetTotalBytes())
|
|
// verifier.Process();
|
|
// verifier.Finish();
|
|
// auto result = verifier.GetResult();
|
|
//
|
|
// Start, Process and Finish may take some time to run.
|
|
//
|
|
// GetResult() can be called before the processing is finished, but the result will be incomplete.
|
|
|
|
namespace DiscIO
|
|
{
|
|
template <typename T>
|
|
struct Hashes
|
|
{
|
|
T crc32;
|
|
T md5;
|
|
T sha1;
|
|
};
|
|
|
|
class RedumpVerifier final
|
|
{
|
|
public:
|
|
enum class Status
|
|
{
|
|
Unknown,
|
|
GoodDump,
|
|
BadDump,
|
|
Error,
|
|
};
|
|
|
|
struct Result
|
|
{
|
|
Status status = Status::Unknown;
|
|
std::string message;
|
|
};
|
|
|
|
void Start(const Volume& volume);
|
|
Result Finish(const Hashes<std::vector<u8>>& hashes);
|
|
|
|
private:
|
|
enum class DownloadStatus
|
|
{
|
|
NotAttempted,
|
|
Success,
|
|
Fail,
|
|
FailButOldCacheAvailable,
|
|
};
|
|
|
|
struct DownloadState
|
|
{
|
|
std::mutex mutex;
|
|
DownloadStatus status = DownloadStatus::NotAttempted;
|
|
};
|
|
|
|
struct PotentialMatch
|
|
{
|
|
u64 size = 0;
|
|
Hashes<std::vector<u8>> hashes;
|
|
};
|
|
|
|
static DownloadStatus DownloadDatfile(const std::string& system, DownloadStatus old_status);
|
|
static std::vector<u8> ReadDatfile(const std::string& system);
|
|
std::vector<PotentialMatch> ScanDatfile(std::span<const u8> data, const std::string& system);
|
|
|
|
std::string m_game_id;
|
|
u16 m_revision = 0;
|
|
u8 m_disc_number = 0;
|
|
u64 m_size = 0;
|
|
|
|
std::future<std::vector<PotentialMatch>> m_future;
|
|
Result m_result;
|
|
|
|
static DownloadState m_gc_download_state;
|
|
static DownloadState m_wii_download_state;
|
|
};
|
|
|
|
class VolumeVerifier final
|
|
{
|
|
public:
|
|
enum class Severity
|
|
{
|
|
None, // Only used internally
|
|
Low,
|
|
Medium,
|
|
High,
|
|
};
|
|
|
|
struct Problem
|
|
{
|
|
Severity severity;
|
|
std::string text;
|
|
};
|
|
|
|
struct Result
|
|
{
|
|
Hashes<std::vector<u8>> hashes;
|
|
std::string summary_text;
|
|
std::vector<Problem> problems;
|
|
RedumpVerifier::Result redump;
|
|
};
|
|
|
|
VolumeVerifier(const Volume& volume, bool redump_verification, Hashes<bool> hashes_to_calculate);
|
|
~VolumeVerifier();
|
|
|
|
static Hashes<bool> GetDefaultHashesToCalculate();
|
|
void Start();
|
|
void Process();
|
|
u64 GetBytesProcessed() const;
|
|
u64 GetTotalBytes() const;
|
|
void Finish();
|
|
const Result& GetResult() const;
|
|
|
|
private:
|
|
struct GroupToVerify
|
|
{
|
|
Partition partition;
|
|
u64 offset;
|
|
size_t block_index_start;
|
|
size_t block_index_end;
|
|
};
|
|
|
|
std::vector<Partition> CheckPartitions();
|
|
bool CheckPartition(const Partition& partition); // Returns false if partition should be ignored
|
|
std::string GetPartitionName(std::optional<u32> type) const;
|
|
bool IsDebugSigned() const;
|
|
bool ShouldHaveChannelPartition() const;
|
|
bool ShouldHaveInstallPartition() const;
|
|
bool ShouldHaveMasterpiecePartitions() const;
|
|
bool ShouldBeDualLayer() const;
|
|
void CheckVolumeSize();
|
|
void CheckMisc();
|
|
void CheckSuperPaperMario();
|
|
void SetUpHashing();
|
|
void WaitForAsyncOperations() const;
|
|
bool ReadChunkAndWaitForAsyncOperations(u64 bytes_to_read);
|
|
|
|
void AddProblem(Severity severity, std::string text);
|
|
|
|
const Volume& m_volume;
|
|
Result m_result;
|
|
bool m_is_tgc = false;
|
|
bool m_is_datel = false;
|
|
bool m_is_triforce = false;
|
|
bool m_is_not_retail = false;
|
|
|
|
bool m_redump_verification;
|
|
RedumpVerifier m_redump_verifier;
|
|
|
|
bool m_read_errors_occurred = false;
|
|
|
|
Hashes<bool> m_hashes_to_calculate{};
|
|
bool m_calculating_any_hash = false;
|
|
u32 m_crc32_context = 0;
|
|
mbedtls_md5_context m_md5_context{};
|
|
std::unique_ptr<Common::SHA1::Context> m_sha1_context;
|
|
|
|
u64 m_excess_bytes = 0;
|
|
std::vector<u8> m_data;
|
|
std::future<void> m_crc32_future;
|
|
std::future<void> m_md5_future;
|
|
std::future<void> m_sha1_future;
|
|
std::future<void> m_content_future;
|
|
std::future<void> m_group_future;
|
|
|
|
DiscScrubber m_scrubber;
|
|
IOS::ES::TicketReader m_ticket;
|
|
std::vector<u64> m_content_offsets;
|
|
u16 m_content_index = 0;
|
|
std::vector<GroupToVerify> m_groups;
|
|
size_t m_group_index = 0; // Index in m_groups, not index in a specific partition
|
|
std::map<Partition, size_t> m_block_errors;
|
|
std::map<Partition, size_t> 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;
|
|
u64 m_max_progress = 0;
|
|
DataSizeType m_data_size_type;
|
|
};
|
|
|
|
} // namespace DiscIO
|