mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add AesXtsFileSystem resizing and renaming
This commit is contained in:
parent
5c1d8e0786
commit
1ee3841125
7 changed files with 96 additions and 8 deletions
|
@ -74,7 +74,9 @@ namespace LibHac.IO
|
|||
{
|
||||
Header.SetSize(size, VerificationKey);
|
||||
|
||||
throw new NotImplementedException();
|
||||
BaseFile.Write(Header.ToBytes(false), 0);
|
||||
|
||||
BaseStorage.SetSize(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace LibHac.IO
|
|||
EncryptHeader(path, kekSeed, verificationKey);
|
||||
}
|
||||
|
||||
private void EncryptHeader(string path, byte[] kekSeed, byte[] verificationKey)
|
||||
public void EncryptHeader(string path, byte[] kekSeed, byte[] verificationKey)
|
||||
{
|
||||
GenerateKek(kekSeed, path);
|
||||
EncryptKeys();
|
||||
|
@ -84,7 +84,7 @@ namespace LibHac.IO
|
|||
private void GenerateKek(byte[] kekSeed, string path)
|
||||
{
|
||||
var hash = new HMACSHA256(kekSeed);
|
||||
byte[] pathBytes = Encoding.ASCII.GetBytes(path);
|
||||
byte[] pathBytes = Encoding.UTF8.GetBytes(path);
|
||||
|
||||
byte[] checksum = hash.ComputeHash(pathBytes, 0, pathBytes.Length);
|
||||
Array.Copy(checksum, 0, Kek1, 0, 0x10);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace LibHac.IO
|
||||
{
|
||||
|
@ -95,7 +97,24 @@ namespace LibHac.IO
|
|||
|
||||
public void RenameFile(string srcPath, string dstPath)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
srcPath = PathTools.Normalize(srcPath);
|
||||
dstPath = PathTools.Normalize(dstPath);
|
||||
|
||||
AesXtsFileHeader header = ReadXtsHeader(srcPath);
|
||||
|
||||
BaseFileSystem.RenameFile(srcPath, dstPath);
|
||||
|
||||
try
|
||||
{
|
||||
WriteXtsHeader(header, dstPath);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
BaseFileSystem.RenameFile(dstPath, srcPath);
|
||||
WriteXtsHeader(header, srcPath);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string path)
|
||||
|
@ -117,5 +136,34 @@ namespace LibHac.IO
|
|||
{
|
||||
BaseFileSystem.Commit();
|
||||
}
|
||||
|
||||
private AesXtsFileHeader ReadXtsHeader(string path)
|
||||
{
|
||||
Debug.Assert(PathTools.IsNormalized(path.AsSpan()));
|
||||
|
||||
using (IFile file = BaseFileSystem.OpenFile(path, OpenMode.Read))
|
||||
{
|
||||
var header = new AesXtsFileHeader(file);
|
||||
|
||||
if (!header.TryDecryptHeader(path, KekSource, ValidationKey))
|
||||
{
|
||||
throw new InvalidDataException("Could not decrypt AES-XTS keys");
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteXtsHeader(AesXtsFileHeader header, string path)
|
||||
{
|
||||
Debug.Assert(PathTools.IsNormalized(path.AsSpan()));
|
||||
|
||||
header.EncryptHeader(path, KekSource, ValidationKey);
|
||||
|
||||
using (IFile file = BaseFileSystem.OpenFile(path, OpenMode.ReadWrite))
|
||||
{
|
||||
file.Write(header.ToBytes(false), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace LibHac.IO
|
|||
{
|
||||
private IStorage BaseStorage { get; }
|
||||
private int BlockSize { get; }
|
||||
private readonly long _length;
|
||||
private long _length;
|
||||
|
||||
private LinkedList<CacheBlock> Blocks { get; } = new LinkedList<CacheBlock>();
|
||||
private Dictionary<long, LinkedListNode<CacheBlock>> BlockDict { get; } = new Dictionary<long, LinkedListNode<CacheBlock>>();
|
||||
|
@ -99,6 +99,13 @@ namespace LibHac.IO
|
|||
|
||||
public override long GetSize() => _length;
|
||||
|
||||
public override void SetSize(long size)
|
||||
{
|
||||
BaseStorage.SetSize(size);
|
||||
|
||||
_length = BaseStorage.GetSize();
|
||||
}
|
||||
|
||||
private CacheBlock GetBlock(long blockIndex)
|
||||
{
|
||||
if (BlockDict.TryGetValue(blockIndex, out LinkedListNode<CacheBlock> node))
|
||||
|
|
|
@ -27,5 +27,10 @@ namespace LibHac.IO
|
|||
}
|
||||
|
||||
public override long GetSize() => BaseFile.GetSize();
|
||||
|
||||
public override void SetSize(long size)
|
||||
{
|
||||
BaseFile.SetSize(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace LibHac.IO
|
|||
protected IStorage BaseStorage { get; }
|
||||
|
||||
public int SectorSize { get; }
|
||||
public int SectorCount { get; }
|
||||
public int SectorCount { get; private set; }
|
||||
|
||||
private long _length;
|
||||
|
||||
|
@ -15,8 +15,8 @@ namespace LibHac.IO
|
|||
{
|
||||
BaseStorage = baseStorage;
|
||||
SectorSize = sectorSize;
|
||||
SectorCount = (int)Util.DivideByRoundUp(BaseStorage.GetSize(), sectorSize);
|
||||
_length = baseStorage.GetSize();
|
||||
SectorCount = (int)Util.DivideByRoundUp(BaseStorage.GetSize(), SectorSize);
|
||||
_length = BaseStorage.GetSize();
|
||||
|
||||
if (!leaveOpen) ToDispose.Add(BaseStorage);
|
||||
}
|
||||
|
@ -40,6 +40,14 @@ namespace LibHac.IO
|
|||
|
||||
public override long GetSize() => _length;
|
||||
|
||||
public override void SetSize(long size)
|
||||
{
|
||||
BaseStorage.SetSize(size);
|
||||
|
||||
SectorCount = (int)Util.DivideByRoundUp(BaseStorage.GetSize(), SectorSize);
|
||||
_length = BaseStorage.GetSize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the size is a multiple of the sector size
|
||||
/// </summary>
|
||||
|
|
|
@ -54,5 +54,23 @@ namespace LibHac.IO
|
|||
}
|
||||
|
||||
public override long GetSize() => _length;
|
||||
|
||||
public override void SetSize(long size)
|
||||
{
|
||||
//if (!IsResizable)
|
||||
// return 0x313802;
|
||||
|
||||
//if (Offset < 0 || size < 0)
|
||||
// return 0x2F5C02;
|
||||
|
||||
if (BaseStorage.GetSize() != Offset + _length)
|
||||
{
|
||||
throw new NotSupportedException("SubStorage cannot be resized unless it is located at the end of the base storage.");
|
||||
}
|
||||
|
||||
BaseStorage.SetSize(Offset + size);
|
||||
|
||||
_length = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue