mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-08 04:15:08 -04:00
Do hash-based verification of disc images
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#include "iso_validate.hpp"
|
||||
|
||||
#include <nod.h>
|
||||
|
||||
#include "SDL3/SDL_iostream.h"
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -147,7 +147,7 @@ ValidationError verify_disc(NodHandle* disc, VerificationStatus& status) {
|
||||
const auto hashState = XXH3_createState();
|
||||
XXH3_128bits_reset(hashState);
|
||||
|
||||
while (!status.shouldCancel) {
|
||||
while (true) {
|
||||
size_t bytesAvail;
|
||||
const auto buf = nod_buf_read(disc, &bytesAvail);
|
||||
if (!bytesAvail)
|
||||
@@ -159,13 +159,9 @@ ValidationError verify_disc(NodHandle* disc, VerificationStatus& status) {
|
||||
nod_buf_consume(disc, bytesAvail);
|
||||
}
|
||||
|
||||
if (status.shouldCancel) {
|
||||
return ValidationError::Cancelled;
|
||||
}
|
||||
|
||||
const auto hash = XXH3_128bits_digest(hashState);
|
||||
if (!XXH128_isEqual(hash, status.knownDisc->hash)) {
|
||||
return ValidationError::DiscHashMismatch;
|
||||
return ValidationError::HashMismatch;
|
||||
}
|
||||
|
||||
return ValidationError::Success;
|
||||
@@ -214,6 +210,11 @@ ValidationError validate(const char* path, VerificationStatus& status) {
|
||||
return verify_disc(disc.handle, status);
|
||||
}
|
||||
|
||||
ValidationError validate(const char* path) {
|
||||
VerificationStatus status{};
|
||||
return validate(path, status);
|
||||
}
|
||||
|
||||
bool isPal(const char* path) {
|
||||
NodHandleWrapper disc;
|
||||
|
||||
|
||||
@@ -7,14 +7,13 @@ namespace dusk::iso {
|
||||
struct KnownDisc;
|
||||
|
||||
enum class ValidationError : u8 {
|
||||
Success = 0,
|
||||
Unknown = 0,
|
||||
IOError,
|
||||
InvalidImage,
|
||||
WrongGame,
|
||||
WrongVersion,
|
||||
Cancelled,
|
||||
DiscHashMismatch,
|
||||
Unknown
|
||||
HashMismatch,
|
||||
Success
|
||||
};
|
||||
|
||||
struct VerificationStatus {
|
||||
@@ -25,6 +24,7 @@ namespace dusk::iso {
|
||||
};
|
||||
|
||||
ValidationError validate(const char* path, VerificationStatus& status);
|
||||
ValidationError validate(const char* path);
|
||||
bool isPal(const char* path);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ constexpr std::array<SDL_DialogFileFilter, 2> kDiscFileFilters{{
|
||||
|
||||
static std::string get_error_msg(iso::ValidationError error) {
|
||||
switch (error) {
|
||||
default:
|
||||
return "The selected disc image could not be validated.";
|
||||
case iso::ValidationError::IOError:
|
||||
return "Unable to read the selected file.";
|
||||
case iso::ValidationError::InvalidImage:
|
||||
@@ -64,22 +66,19 @@ static std::string get_error_msg(iso::ValidationError error) {
|
||||
return "The selected game is not supported by Dusk.";
|
||||
case iso::ValidationError::WrongVersion:
|
||||
return "Dusk currently supports GameCube USA and PAL disc images only.";
|
||||
case iso::ValidationError::HashMismatch:
|
||||
return "The selected disc image did not pass hash verification, it may be corrupt or modified.";
|
||||
case iso::ValidationError::Success:
|
||||
return "The selected disc image is valid.";
|
||||
default:
|
||||
return "The selected disc image could not be validated.";
|
||||
}
|
||||
}
|
||||
|
||||
void file_dialog_callback(void*, const char* path, const char* error) {
|
||||
auto& state = prelaunch_state();
|
||||
if (error != nullptr) {
|
||||
return;
|
||||
}
|
||||
if (path == nullptr) {
|
||||
if (path == nullptr || error != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& state = prelaunch_state();
|
||||
const auto validation = iso::validate(path);
|
||||
if (validation != iso::ValidationError::Success) {
|
||||
state.errorString = escape(get_error_msg(validation));
|
||||
|
||||
Reference in New Issue
Block a user