[rvthtool] verify.cpp: Print the total number of hash errors.

[librvth] RvtH::verifyWiiPartitions(): Accept a pointer to a 5-element
unsigned int array to get the total number of hash errors. This is for
both actual hash errors and hash table copy errors.
This commit is contained in:
David Korth 2022-08-16 01:00:42 -04:00
parent 5601647630
commit d92bfecd7b
3 changed files with 46 additions and 10 deletions

View File

@ -468,12 +468,14 @@ class RvtH {
* NOTE: Assuming the TMD signature is valid, which means
* the H4 hash is correct.
*
* @param bank [in] Bank number. (0-7)
* @param callback [in,opt] Progress callback.
* @param userdata [in,opt] User data for progress callback.
* @param bank [in] Bank number (0-7)
* @param errors [out] Error counts for all 5 hash tables
* @param callback [in,opt] Progress callback
* @param userdata [in,opt] User data for progress callback
* @return Error code. (If negative, POSIX error; otherwise, see RvtH_Errors.)
*/
int verifyWiiPartitions(unsigned int bank,
unsigned int error_count[5] = nullptr,
RvtH_Verify_Progress_Callback callback = nullptr,
void *userdata = nullptr);

View File

@ -110,16 +110,23 @@ static bool is_block_zero(const uint8_t *pData, size_t size)
* NOTE: Assuming the TMD signature is valid, which means
* the H4 hash is correct.
*
* @param bank [in] Bank number. (0-7)
* @param callback [in,opt] Progress callback.
* @param userdata [in,opt] User data for progress callback.
* @param bank [in] Bank number (0-7)
* @param errors [out] Error counts for all 5 hash tables
* @param callback [in,opt] Progress callback
* @param userdata [in,opt] User data for progress callback
* @return Error code. (If negative, POSIX error; otherwise, see RvtH_Errors.)
*/
int RvtH::verifyWiiPartitions(unsigned int bank,
unsigned int error_count[5],
RvtH_Verify_Progress_Callback callback,
void *userdata)
{
int ret = 0; // errno or RvtH_Errors
if (error_count) {
for (unsigned int i = 0; i < 5; i++) {
error_count[i] = 0;
}
}
// Make sure this is a Wii disc.
RvtH_BankEntry *const entry = &m_entries[bank];
@ -370,6 +377,9 @@ int RvtH::verifyWiiPartitions(unsigned int bank,
sha1_digest(&sha1, sizeof(digest), digest);
if (memcmp(pContentEntry->sha1_hash, digest, SHA1_DIGEST_SIZE) != 0) {
state.is_zero = is_block_zero((const uint8_t*)H3_tbl.get(), 512); // only check one LBA
if (error_count) {
error_count[4]++;
}
if (callback) {
state.type = RVTH_VERIFY_ERROR_REPORT;
state.hash_level = 4;
@ -455,6 +465,9 @@ int RvtH::verifyWiiPartitions(unsigned int bank,
sha1_digest(&sha1, sizeof(digest), digest);
if (memcmp(H3_entry, digest, SHA1_DIGEST_SIZE) != 0) {
state.is_zero = is_block_zero((const uint8_t*)&gdata_enc[0], sizeof(gdata_enc[0]));
if (error_count) {
error_count[3]++;
}
if (callback) {
state.type = RVTH_VERIFY_ERROR_REPORT;
state.hash_level = 3;
@ -472,6 +485,9 @@ int RvtH::verifyWiiPartitions(unsigned int bank,
sizeof(gdata[0].hashes.H2)) != 0)
{
state.is_zero = is_block_zero((const uint8_t*)&gdata_enc[sector], sizeof(gdata_enc[sector]));
if (error_count) {
error_count[2]++;
}
if (callback) {
state.type = RVTH_VERIFY_ERROR_REPORT;
state.hash_level = 2;
@ -490,6 +506,9 @@ int RvtH::verifyWiiPartitions(unsigned int bank,
sha1_digest(&sha1, sizeof(digest), digest);
if (memcmp(gdata[0].hashes.H2[sg], digest, sizeof(digest)) != 0) {
state.is_zero = is_block_zero((const uint8_t*)&gdata_enc[sector], sizeof(gdata_enc[sector]));
if (error_count) {
error_count[2]++;
}
if (callback) {
state.type = RVTH_VERIFY_ERROR_REPORT;
state.hash_level = 2;
@ -513,6 +532,9 @@ int RvtH::verifyWiiPartitions(unsigned int bank,
sizeof(gdata[0].hashes.H1)) != 0)
{
state.is_zero = is_block_zero((const uint8_t*)&gdata_enc[sector], sizeof(gdata_enc[sector]));
if (error_count) {
error_count[1]++;
}
if (callback) {
state.type = RVTH_VERIFY_ERROR_REPORT;
state.hash_level = 1;
@ -531,6 +553,9 @@ int RvtH::verifyWiiPartitions(unsigned int bank,
sha1_digest(&sha1, sizeof(digest), digest);
if (memcmp(gdata[sector].hashes.H1[sector % 8], digest, sizeof(digest)) != 0) {
state.is_zero = is_block_zero((const uint8_t*)&gdata_enc[sector], sizeof(gdata_enc[sector]));
if (error_count) {
error_count[1]++;
}
if (callback) {
state.type = RVTH_VERIFY_ERROR_REPORT;
state.hash_level = 1;
@ -551,6 +576,9 @@ int RvtH::verifyWiiPartitions(unsigned int bank,
sha1_digest(&sha1, sizeof(digest), digest);
if (memcmp(gdata[sector].hashes.H0[kb], digest, sizeof(digest)) != 0) {
state.is_zero = is_block_zero(&gdata_enc[sector].data[kb * 1024], 1024);
if (error_count) {
error_count[0]++;
}
if (callback) {
state.type = RVTH_VERIFY_ERROR_REPORT;
state.hash_level = 0;

View File

@ -13,11 +13,14 @@
#include "librvth/rvth_error.h"
#include "librvth/nhcd_structs.h"
// C includes. (C++ namespace)
// C includes (C++ namespace)
#include <cassert>
#include <cerrno>
#include <cstdlib>
// C++ includes
#include <numeric>
/**
* RVT-H verify progress callback.
* @param state [in] Current progress.
@ -161,13 +164,16 @@ int verify(const TCHAR *rvth_filename, const TCHAR *s_bank)
print_bank(rvth, bank);
putchar('\n');
unsigned int error_count[5] = {0, 0, 0, 0, 0};
_tprintf(_T("Verifying Bank %u...\n"), bank+1);
fflush(stdout);
ret = rvth->verifyWiiPartitions(bank, progress_callback);
ret = rvth->verifyWiiPartitions(bank, error_count, progress_callback);
if (ret == 0) {
_tprintf(_T("Bank %u verified with (TODO) errors.\n"), bank+1);
// Add up the errors.
unsigned int total_errs = std::accumulate(error_count, error_count + ARRAY_SIZE(error_count), 0);
_tprintf(_T("Bank %u verified with %u error%s.\n"), bank+1, total_errs, (total_errs != 1) ? "s" : "");
} else {
fprintf(stderr, "*** ERROR: rvth->verify() failed: %s\n", rvth_error(ret));
fprintf(stderr, "*** ERROR: rvth->verifyWiiPartitions() failed: %s\n", rvth_error(ret));
}
delete rvth;