mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Tweak how IVFC validation is done
This commit is contained in:
parent
da5eec1b3d
commit
f8e7c00ef4
2 changed files with 48 additions and 28 deletions
|
@ -39,31 +39,33 @@ namespace LibHac
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the hashes of any unchecked blocks and returns the <see cref="Validity"/> of the hash level.
|
||||
/// Checks the hashes of any unchecked blocks and returns the <see cref="Validity"/> of the data.
|
||||
/// </summary>
|
||||
/// <param name="level">The level of hierarchical hashes to check.</param>
|
||||
/// <param name="returnOnError">If <see langword="true"/>, return as soon as an invalid block is found.</param>
|
||||
/// <param name="logger">An optional <see cref="IProgressReport"/> for reporting progress.</param>
|
||||
/// <returns>The <see cref="Validity"/> of the data of the specified hash level.</returns>
|
||||
public Validity ValidateLevel(int level, bool returnOnError, IProgressReport logger = null)
|
||||
public Validity Validate(bool returnOnError, IProgressReport logger = null)
|
||||
{
|
||||
Validity[] validities = LevelValidities[level];
|
||||
IntegrityVerificationStream levelStream = IntegrityStreams[level];
|
||||
Validity[] validities = LevelValidities[LevelValidities.Length - 1];
|
||||
IntegrityVerificationStream stream = IntegrityStreams[IntegrityStreams.Length - 1];
|
||||
|
||||
// The original position of the stream must be restored when we're done validating
|
||||
long initialPosition = levelStream.Position;
|
||||
// Restore the original position of the stream when we're done validating
|
||||
long initialPosition = stream.Position;
|
||||
|
||||
var buffer = new byte[levelStream.SectorSize];
|
||||
long blockSize = stream.SectorSize;
|
||||
int blockCount = (int)Util.DivideByRoundUp(Length, blockSize);
|
||||
|
||||
var buffer = new byte[blockSize];
|
||||
var result = Validity.Valid;
|
||||
|
||||
logger?.SetTotal(levelStream.SectorCount);
|
||||
logger?.SetTotal(blockCount);
|
||||
|
||||
for (int i = 0; i < levelStream.SectorCount; i++)
|
||||
for (int i = 0; i < blockCount; i++)
|
||||
{
|
||||
if (validities[i] == Validity.Unchecked)
|
||||
{
|
||||
levelStream.Position = (long)levelStream.SectorSize * i;
|
||||
levelStream.Read(buffer, 0, buffer.Length, IntegrityCheckLevel.IgnoreOnInvalid);
|
||||
stream.Position = blockSize * i;
|
||||
stream.Read(buffer, 0, buffer.Length, IntegrityCheckLevel.IgnoreOnInvalid);
|
||||
}
|
||||
|
||||
if (validities[i] == Validity.Invalid)
|
||||
|
@ -76,7 +78,7 @@ namespace LibHac
|
|||
}
|
||||
|
||||
logger?.SetTotal(0);
|
||||
levelStream.Position = initialPosition;
|
||||
stream.Position = initialPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -489,25 +489,43 @@ namespace LibHac
|
|||
if (stream == null) return Validity.Unchecked;
|
||||
|
||||
if (!quiet) logger?.LogMessage($"Verifying section {index}...");
|
||||
Validity validity = stream.Validate(true, logger);
|
||||
|
||||
for (int i = 0; i < stream.Levels.Length - 1; i++)
|
||||
if (hashType == NcaHashType.Ivfc)
|
||||
{
|
||||
if (!quiet) logger?.LogMessage($" Verifying Hash Level {i}...");
|
||||
Validity levelValidity = stream.ValidateLevel(i, true, logger);
|
||||
|
||||
if (hashType == NcaHashType.Ivfc)
|
||||
{
|
||||
sect.Header.IvfcInfo.LevelHeaders[i].HashValidity = levelValidity;
|
||||
}
|
||||
else if (hashType == NcaHashType.Sha256 && i == stream.Levels.Length - 2)
|
||||
{
|
||||
sect.Header.Sha256Info.HashValidity = levelValidity;
|
||||
}
|
||||
|
||||
if (levelValidity == Validity.Invalid) return Validity.Invalid;
|
||||
SetIvfcLevelValidities(stream, sect.Header.IvfcInfo);
|
||||
}
|
||||
else if (hashType == NcaHashType.Sha256)
|
||||
{
|
||||
sect.Header.Sha256Info.HashValidity = validity;
|
||||
}
|
||||
|
||||
return Validity.Valid;
|
||||
return validity;
|
||||
}
|
||||
|
||||
private static void SetIvfcLevelValidities(HierarchicalIntegrityVerificationStream stream, IvfcHeader header)
|
||||
{
|
||||
for (int i = 0; i < stream.Levels.Length - 1; i++)
|
||||
{
|
||||
Validity[] level = stream.LevelValidities[i];
|
||||
var levelValidity = Validity.Valid;
|
||||
|
||||
foreach (Validity block in level)
|
||||
{
|
||||
if (block == Validity.Invalid)
|
||||
{
|
||||
levelValidity = Validity.Invalid;
|
||||
break;
|
||||
}
|
||||
|
||||
if (block == Validity.Unchecked && levelValidity != Validity.Invalid)
|
||||
{
|
||||
levelValidity = Validity.Unchecked;
|
||||
}
|
||||
}
|
||||
|
||||
header.LevelHeaders[i].HashValidity = levelValidity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue