IVFS writing

This commit is contained in:
Alex Barney 2018-10-16 15:01:16 -05:00
parent 0eaefba071
commit c0393449f1
3 changed files with 37 additions and 21 deletions

View file

@ -90,7 +90,7 @@ namespace LibHac
bytesToHash = bytesRead; bytesToHash = bytesRead;
} }
} }
if (BlockValidities[blockNum] == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid) if (BlockValidities[blockNum] == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
{ {
throw new InvalidDataException("Hash error!"); throw new InvalidDataException("Hash error!");
@ -100,23 +100,7 @@ namespace LibHac
if (BlockValidities[blockNum] != Validity.Unchecked) return bytesRead; if (BlockValidities[blockNum] != Validity.Unchecked) return bytesRead;
_hash.Initialize(); byte[] hash = DoHash(buffer, offset, bytesToHash);
if (Type == IntegrityStreamType.Save)
{
_hash.TransformBlock(Salt, 0, Salt.Length, null, 0);
}
_hash.TransformBlock(buffer, offset, bytesToHash, null, 0);
_hash.TransformFinalBlock(buffer, 0, 0);
byte[] hash = _hash.Hash;
if (Type == IntegrityStreamType.Save)
{
// This bit is set on all save hashes
hash[0x1F] |= 0x80;
}
Validity validity = Util.ArraysEqual(_hashBuffer, hash) ? Validity.Valid : Validity.Invalid; Validity validity = Util.ArraysEqual(_hashBuffer, hash) ? Validity.Valid : Validity.Invalid;
BlockValidities[blockNum] = validity; BlockValidities[blockNum] = validity;
@ -131,7 +115,37 @@ namespace LibHac
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count)
{ {
throw new NotImplementedException(); long blockNum = CurrentSector;
int toWrite = (int)Math.Min(count, Length - Position);
byte[] hash = DoHash(buffer, offset, toWrite);
base.Write(buffer, offset, count);
HashStream.Position = blockNum * DigestSize;
HashStream.Write(hash, 0, DigestSize);
}
private byte[] DoHash(byte[] buffer, int offset, int count)
{
_hash.Initialize();
if (Type == IntegrityStreamType.Save)
{
_hash.TransformBlock(Salt, 0, Salt.Length, null, 0);
}
_hash.TransformBlock(buffer, offset, count, null, 0);
_hash.TransformFinalBlock(buffer, 0, 0);
byte[] hash = _hash.Hash;
if (Type == IntegrityStreamType.Save)
{
// This bit is set on all save hashes
hash[0x1F] |= 0x80;
}
return hash;
} }
public override bool CanRead => true; public override bool CanRead => true;

View file

@ -44,7 +44,7 @@ namespace LibHac.Streams
if (_readBytes == 0 || !_bufferDirty) return; if (_readBytes == 0 || !_bufferDirty) return;
_baseStream.Position = _currentSector * _bufferSize; _baseStream.Position = _currentSector * _bufferSize;
_baseStream.Write(_buffer, 0, _readBytes); _baseStream.Write(_buffer, 0, _bufferSize);
_readBytes = 0; _readBytes = 0;
_bufferDirty = false; _bufferDirty = false;

View file

@ -112,7 +112,9 @@ namespace LibHac.Streams
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count)
{ {
ValidateSize(count); ValidateSize(count);
_baseStream.Write(buffer, offset, count); int toWrite = (int)Math.Min(count, Length - Position);
_baseStream.Write(buffer, offset, toWrite);
CurrentSector += count / SectorSize; CurrentSector += count / SectorSize;
} }