mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Implement RenameDirectory for AesXtsFileSystem
This commit is contained in:
parent
6e6c060e25
commit
dc2bd08823
1 changed files with 72 additions and 18 deletions
|
@ -92,7 +92,54 @@ namespace LibHac.IO
|
||||||
|
|
||||||
public void RenameDirectory(string srcPath, string dstPath)
|
public void RenameDirectory(string srcPath, string dstPath)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
srcPath = PathTools.Normalize(srcPath);
|
||||||
|
dstPath = PathTools.Normalize(dstPath);
|
||||||
|
|
||||||
|
BaseFileSystem.RenameDirectory(srcPath, dstPath);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RenameDirectoryImpl(srcPath, dstPath, false);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
RenameDirectoryImpl(srcPath, dstPath, true);
|
||||||
|
BaseFileSystem.RenameDirectory(dstPath, srcPath);
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenameDirectoryImpl(string srcDir, string dstDir, bool doRollback)
|
||||||
|
{
|
||||||
|
IDirectory dir = OpenDirectory(dstDir, OpenDirectoryMode.All);
|
||||||
|
|
||||||
|
foreach (DirectoryEntry entry in dir.Read())
|
||||||
|
{
|
||||||
|
string subSrcPath = $"{srcDir}/{entry.Name}";
|
||||||
|
string subDstPath = $"{dstDir}/{entry.Name}";
|
||||||
|
|
||||||
|
if (entry.Type == DirectoryEntryType.Directory)
|
||||||
|
{
|
||||||
|
RenameDirectoryImpl(subSrcPath, subDstPath, doRollback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.Type == DirectoryEntryType.File)
|
||||||
|
{
|
||||||
|
if (doRollback)
|
||||||
|
{
|
||||||
|
if (TryReadXtsHeader(subDstPath, subDstPath, out AesXtsFileHeader header))
|
||||||
|
{
|
||||||
|
WriteXtsHeader(header, subDstPath, subSrcPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AesXtsFileHeader header = ReadXtsHeader(subDstPath, subSrcPath);
|
||||||
|
WriteXtsHeader(header, subDstPath, subDstPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RenameFile(string srcPath, string dstPath)
|
public void RenameFile(string srcPath, string dstPath)
|
||||||
|
@ -100,18 +147,18 @@ namespace LibHac.IO
|
||||||
srcPath = PathTools.Normalize(srcPath);
|
srcPath = PathTools.Normalize(srcPath);
|
||||||
dstPath = PathTools.Normalize(dstPath);
|
dstPath = PathTools.Normalize(dstPath);
|
||||||
|
|
||||||
AesXtsFileHeader header = ReadXtsHeader(srcPath);
|
AesXtsFileHeader header = ReadXtsHeader(srcPath, srcPath);
|
||||||
|
|
||||||
BaseFileSystem.RenameFile(srcPath, dstPath);
|
BaseFileSystem.RenameFile(srcPath, dstPath);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteXtsHeader(header, dstPath);
|
WriteXtsHeader(header, dstPath, dstPath);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
BaseFileSystem.RenameFile(dstPath, srcPath);
|
BaseFileSystem.RenameFile(dstPath, srcPath);
|
||||||
WriteXtsHeader(header, srcPath);
|
WriteXtsHeader(header, srcPath, srcPath);
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -137,30 +184,37 @@ namespace LibHac.IO
|
||||||
BaseFileSystem.Commit();
|
BaseFileSystem.Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private AesXtsFileHeader ReadXtsHeader(string path)
|
private AesXtsFileHeader ReadXtsHeader(string filePath, string keyPath)
|
||||||
{
|
{
|
||||||
Debug.Assert(PathTools.IsNormalized(path.AsSpan()));
|
if (!TryReadXtsHeader(filePath, keyPath, out AesXtsFileHeader header))
|
||||||
|
|
||||||
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");
|
throw new InvalidDataException("Could not decrypt AES-XTS keys");
|
||||||
}
|
}
|
||||||
|
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool TryReadXtsHeader(string filePath, string keyPath, out AesXtsFileHeader header)
|
||||||
|
{
|
||||||
|
Debug.Assert(PathTools.IsNormalized(filePath.AsSpan()));
|
||||||
|
Debug.Assert(PathTools.IsNormalized(keyPath.AsSpan()));
|
||||||
|
|
||||||
|
using (IFile file = BaseFileSystem.OpenFile(filePath, OpenMode.Read))
|
||||||
|
{
|
||||||
|
header = new AesXtsFileHeader(file);
|
||||||
|
|
||||||
|
return header.TryDecryptHeader(keyPath, KekSource, ValidationKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteXtsHeader(AesXtsFileHeader header, string path)
|
private void WriteXtsHeader(AesXtsFileHeader header, string filePath, string keyPath)
|
||||||
{
|
{
|
||||||
Debug.Assert(PathTools.IsNormalized(path.AsSpan()));
|
Debug.Assert(PathTools.IsNormalized(filePath.AsSpan()));
|
||||||
|
Debug.Assert(PathTools.IsNormalized(keyPath.AsSpan()));
|
||||||
|
|
||||||
header.EncryptHeader(path, KekSource, ValidationKey);
|
header.EncryptHeader(keyPath, KekSource, ValidationKey);
|
||||||
|
|
||||||
using (IFile file = BaseFileSystem.OpenFile(path, OpenMode.ReadWrite))
|
using (IFile file = BaseFileSystem.OpenFile(filePath, OpenMode.ReadWrite))
|
||||||
{
|
{
|
||||||
file.Write(header.ToBytes(false), 0);
|
file.Write(header.ToBytes(false), 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue