diff --git a/src/LibHac/Fs/AesXtsDirectory.cs b/src/LibHac/Fs/AesXtsDirectory.cs
index d1b14e92..67106723 100644
--- a/src/LibHac/Fs/AesXtsDirectory.cs
+++ b/src/LibHac/Fs/AesXtsDirectory.cs
@@ -56,7 +56,9 @@ namespace LibHac.Fs
{
try
{
- using (IFile file = BaseFileSystem.OpenFile(path, OpenMode.Read))
+ BaseFileSystem.OpenFile(out IFile file, path, OpenMode.Read).ThrowIfFailure();
+
+ using (file)
{
file.GetSize(out long fileSize).ThrowIfFailure();
diff --git a/src/LibHac/Fs/AesXtsFileSystem.cs b/src/LibHac/Fs/AesXtsFileSystem.cs
index 545c556f..3078bd05 100644
--- a/src/LibHac/Fs/AesXtsFileSystem.cs
+++ b/src/LibHac/Fs/AesXtsFileSystem.cs
@@ -27,14 +27,14 @@ namespace LibHac.Fs
BlockSize = blockSize;
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
- BaseFileSystem.CreateDirectory(path);
+ return BaseFileSystem.CreateDirectory(path);
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
- CreateFile(path, size, options, new byte[0x20]);
+ return CreateFile(path, size, options, new byte[0x20]);
}
///
@@ -45,83 +45,109 @@ namespace LibHac.Fs
/// Flags to control how the file is created.
/// Should usually be
/// The 256-bit key containing a 128-bit data key followed by a 128-bit tweak key.
- public void CreateFile(string path, long size, CreateFileOptions options, byte[] key)
+ public Result CreateFile(string path, long size, CreateFileOptions options, byte[] key)
{
long containerSize = AesXtsFile.HeaderLength + Util.AlignUp(size, 0x10);
BaseFileSystem.CreateFile(path, containerSize, options);
var header = new AesXtsFileHeader(key, size, path, KekSource, ValidationKey);
- using (IFile baseFile = BaseFileSystem.OpenFile(path, OpenMode.Write))
+ Result rc = BaseFileSystem.OpenFile(out IFile baseFile, path, OpenMode.Write);
+ if (rc.IsFailure()) return rc;
+
+ using (baseFile)
{
- baseFile.Write(0, header.ToBytes(false)).ThrowIfFailure();
+ rc = baseFile.Write(0, header.ToBytes(false));
+ if (rc.IsFailure()) return rc;
}
+
+ return Result.Success;
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
- BaseFileSystem.DeleteDirectory(path);
+ return BaseFileSystem.DeleteDirectory(path);
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
- BaseFileSystem.DeleteDirectoryRecursively(path);
+ return BaseFileSystem.DeleteDirectoryRecursively(path);
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
- BaseFileSystem.CleanDirectoryRecursively(path);
+ return BaseFileSystem.CleanDirectoryRecursively(path);
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
- BaseFileSystem.DeleteFile(path);
+ return BaseFileSystem.DeleteFile(path);
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
+ directory = default;
path = PathTools.Normalize(path);
- IDirectory baseDir = BaseFileSystem.OpenDirectory(path, mode);
+ Result rc = BaseFileSystem.OpenDirectory(out IDirectory baseDir, path, mode);
+ if (rc.IsFailure()) return rc;
- var dir = new AesXtsDirectory(this, baseDir, mode);
- return dir;
+ directory = new AesXtsDirectory(this, baseDir, mode);
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
+ file = default;
path = PathTools.Normalize(path);
- IFile baseFile = BaseFileSystem.OpenFile(path, mode | OpenMode.Read);
- var file = new AesXtsFile(mode, baseFile, path, KekSource, ValidationKey, BlockSize);
+ Result rc = BaseFileSystem.OpenFile(out IFile baseFile, path, mode | OpenMode.Read);
+ if (rc.IsFailure()) return rc;
- file.ToDispose.Add(baseFile);
- return file;
+ var xtsFile = new AesXtsFile(mode, baseFile, path, KekSource, ValidationKey, BlockSize);
+
+ xtsFile.ToDispose.Add(baseFile);
+
+ file = xtsFile;
+ return Result.Success;
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
- BaseFileSystem.RenameDirectory(srcPath, dstPath);
+ // todo: Return proper result codes
+
+ // Official code procedure:
+ // Make sure all file headers can be decrypted
+ // Rename directory to the new path
+ // Reencrypt file headers with new path
+ // If no errors, return
+ // Reencrypt any modified file headers with the old path
+ // Rename directory to the old path
+
+ Result rc = BaseFileSystem.RenameDirectory(oldPath, newPath);
+ if (rc.IsFailure()) return rc;
try
{
- RenameDirectoryImpl(srcPath, dstPath, false);
+ RenameDirectoryImpl(oldPath, newPath, false);
}
catch (Exception)
{
- RenameDirectoryImpl(srcPath, dstPath, true);
- BaseFileSystem.RenameDirectory(dstPath, srcPath);
+ RenameDirectoryImpl(oldPath, newPath, true);
+ BaseFileSystem.RenameDirectory(oldPath, newPath);
throw;
}
+
+ return Result.Success;
}
private void RenameDirectoryImpl(string srcDir, string dstDir, bool doRollback)
{
- IDirectory dir = OpenDirectory(dstDir, OpenDirectoryMode.All);
+ OpenDirectory(out IDirectory dir, dstDir, OpenDirectoryMode.All);
foreach (DirectoryEntry entry in dir.Read())
{
@@ -151,56 +177,60 @@ namespace LibHac.Fs
}
}
- public void RenameFile(string srcPath, string dstPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
- AesXtsFileHeader header = ReadXtsHeader(srcPath, srcPath);
+ // todo: Return proper result codes
- BaseFileSystem.RenameFile(srcPath, dstPath);
+ AesXtsFileHeader header = ReadXtsHeader(oldPath, oldPath);
+
+ BaseFileSystem.RenameFile(oldPath, newPath);
try
{
- WriteXtsHeader(header, dstPath, dstPath);
+ WriteXtsHeader(header, newPath, newPath);
}
catch (Exception)
{
- BaseFileSystem.RenameFile(dstPath, srcPath);
- WriteXtsHeader(header, srcPath, srcPath);
+ BaseFileSystem.RenameFile(newPath, oldPath);
+ WriteXtsHeader(header, oldPath, oldPath);
throw;
}
+
+ return Result.Success;
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
- return BaseFileSystem.GetEntryType(path);
+ return BaseFileSystem.GetEntryType(out entryType, path);
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- return BaseFileSystem.GetFileTimeStampRaw(path);
+ return BaseFileSystem.GetFileTimeStampRaw(out timeStamp, path);
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- return BaseFileSystem.GetFreeSpaceSize(path);
+ return BaseFileSystem.GetFreeSpaceSize(out freeSpace, path);
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- return BaseFileSystem.GetTotalSpaceSize(path);
+ return BaseFileSystem.GetTotalSpaceSize(out totalSpace, path);
}
- public void Commit()
+ public Result Commit()
{
- BaseFileSystem.Commit();
+ return BaseFileSystem.Commit();
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId)
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
{
- BaseFileSystem.QueryEntry(outBuffer, inBuffer, path, queryId);
+ return BaseFileSystem.QueryEntry(outBuffer, inBuffer, queryId, path);
}
private AesXtsFileHeader ReadXtsHeader(string filePath, string keyPath)
@@ -218,7 +248,12 @@ namespace LibHac.Fs
Debug.Assert(PathTools.IsNormalized(filePath.AsSpan()));
Debug.Assert(PathTools.IsNormalized(keyPath.AsSpan()));
- using (IFile file = BaseFileSystem.OpenFile(filePath, OpenMode.Read))
+ header = null;
+
+ Result rc = BaseFileSystem.OpenFile(out IFile file, filePath, OpenMode.Read);
+ if (rc.IsFailure()) return false;
+
+ using (file)
{
header = new AesXtsFileHeader(file);
@@ -233,7 +268,9 @@ namespace LibHac.Fs
header.EncryptHeader(keyPath, KekSource, ValidationKey);
- using (IFile file = BaseFileSystem.OpenFile(filePath, OpenMode.ReadWrite))
+ BaseFileSystem.OpenFile(out IFile file, filePath, OpenMode.ReadWrite);
+
+ using (file)
{
file.Write(0, header.ToBytes(false), WriteOption.Flush).ThrowIfFailure();
}
diff --git a/src/LibHac/Fs/ConcatenationFile.cs b/src/LibHac/Fs/ConcatenationFile.cs
index b50c7594..ad6842a8 100644
--- a/src/LibHac/Fs/ConcatenationFile.cs
+++ b/src/LibHac/Fs/ConcatenationFile.cs
@@ -130,7 +130,8 @@ namespace LibHac.Fs
public override Result SetSize(long size)
{
- GetSize(out long currentSize).ThrowIfFailure();
+ Result rc = GetSize(out long currentSize);
+ if (rc.IsFailure()) return rc;
if (currentSize == size) return Result.Success;
@@ -142,7 +143,7 @@ namespace LibHac.Fs
IFile currentLastSubFile = Sources[currentSubFileCount - 1];
long newSubFileSize = QuerySubFileSize(currentSubFileCount - 1, size, SubFileSize);
- Result rc = currentLastSubFile.SetSize(newSubFileSize);
+ rc = currentLastSubFile.SetSize(newSubFileSize);
if (rc.IsFailure()) return rc;
for (int i = currentSubFileCount; i < newSubFileCount; i++)
@@ -150,8 +151,13 @@ namespace LibHac.Fs
string newSubFilePath = ConcatenationFileSystem.GetSubFilePath(FilePath, i);
newSubFileSize = QuerySubFileSize(i, size, SubFileSize);
- BaseFileSystem.CreateFile(newSubFilePath, newSubFileSize, CreateFileOptions.None);
- Sources.Add(BaseFileSystem.OpenFile(newSubFilePath, Mode));
+ rc = BaseFileSystem.CreateFile(newSubFilePath, newSubFileSize, CreateFileOptions.None);
+ if (rc.IsFailure()) return rc;
+
+ rc = BaseFileSystem.OpenFile(out IFile newSubFile, newSubFilePath, Mode);
+ if (rc.IsFailure()) return rc;
+
+ Sources.Add(newSubFile);
}
}
else
@@ -162,12 +168,14 @@ namespace LibHac.Fs
Sources.RemoveAt(i);
string subFilePath = ConcatenationFileSystem.GetSubFilePath(FilePath, i);
- BaseFileSystem.DeleteFile(subFilePath);
+
+ rc = BaseFileSystem.DeleteFile(subFilePath);
+ if (rc.IsFailure()) return rc;
}
long newLastFileSize = QuerySubFileSize(newSubFileCount - 1, size, SubFileSize);
- Result rc = Sources[newSubFileCount - 1].SetSize(newLastFileSize);
+ rc = Sources[newSubFileCount - 1].SetSize(newLastFileSize);
if (rc.IsFailure()) return rc;
}
diff --git a/src/LibHac/Fs/ConcatenationFileSystem.cs b/src/LibHac/Fs/ConcatenationFileSystem.cs
index f9df0964..9c2a4471 100644
--- a/src/LibHac/Fs/ConcatenationFileSystem.cs
+++ b/src/LibHac/Fs/ConcatenationFileSystem.cs
@@ -68,11 +68,19 @@ namespace LibHac.Fs
#if CROSS_PLATFORM
private bool IsConcatenationFileHeuristic(string path)
{
- if (BaseFileSystem.GetEntryType(path) != DirectoryEntryType.Directory) return false;
+ // Check if the path is a directory
+ Result getTypeResult = BaseFileSystem.GetEntryType(out DirectoryEntryType pathType, path);
+ if (getTypeResult.IsFailure() || pathType != DirectoryEntryType.Directory) return false;
- if (BaseFileSystem.GetEntryType(PathTools.Combine(path, "00")) != DirectoryEntryType.File) return false;
+ // Check if the directory contains at least one subfile
+ getTypeResult = BaseFileSystem.GetEntryType(out DirectoryEntryType subFileType, PathTools.Combine(path, "00"));
+ if (getTypeResult.IsFailure() || subFileType != DirectoryEntryType.File) return false;
- if (BaseFileSystem.OpenDirectory(path, OpenDirectoryMode.Directory).GetEntryCount() > 0) return false;
+ // Make sure the directory contains no subdirectories
+ Result rc = BaseFileSystem.OpenDirectory(out IDirectory dir, path, OpenDirectoryMode.Directory);
+ if (rc.IsFailure()) return false;
+
+ if (dir.GetEntryCount() > 0) return false;
// Should be enough checks to avoid most false positives. Maybe
return true;
@@ -91,21 +99,21 @@ namespace LibHac.Fs
BaseFileSystem.SetFileAttributes(path, attributes);
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
path = PathTools.Normalize(path);
string parent = PathTools.GetParentDirectory(path);
if (IsConcatenationFile(parent))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound,
- "Cannot create a directory inside of a concatenation file");
+ // Cannot create a directory inside of a concatenation file
+ return ResultFs.PathNotFound.Log();
}
- BaseFileSystem.CreateDirectory(path);
+ return BaseFileSystem.CreateDirectory(path);
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
path = PathTools.Normalize(path);
@@ -113,8 +121,7 @@ namespace LibHac.Fs
if (!options.HasFlag(CreateFileOptions.CreateConcatenationFile))
{
- BaseFileSystem.CreateFile(path, size, newOptions);
- return;
+ return BaseFileSystem.CreateFile(path, size, newOptions);
}
// A concatenation file directory can't contain normal files
@@ -122,11 +129,13 @@ namespace LibHac.Fs
if (IsConcatenationFile(parentDir))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound,
- "Cannot create a concatenation file inside of a concatenation file");
+ // Cannot create a file inside of a concatenation file
+ return ResultFs.PathNotFound.Log();
}
- BaseFileSystem.CreateDirectory(path);
+ Result rc = BaseFileSystem.CreateDirectory(path);
+ if (rc.IsFailure()) return rc;
+
SetConcatenationFileAttribute(path);
long remaining = size;
@@ -136,82 +145,95 @@ namespace LibHac.Fs
long fileSize = Math.Min(SubFileSize, remaining);
string fileName = GetSubFilePath(path, i);
- BaseFileSystem.CreateFile(fileName, fileSize, CreateFileOptions.None);
+ Result createSubFileResult = BaseFileSystem.CreateFile(fileName, fileSize, CreateFileOptions.None);
+
+ if (createSubFileResult.IsFailure())
+ {
+ BaseFileSystem.DeleteDirectoryRecursively(path);
+ return createSubFileResult;
+ }
remaining -= fileSize;
}
+
+ return Result.Success;
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
path = PathTools.Normalize(path);
if (IsConcatenationFile(path))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- BaseFileSystem.DeleteDirectory(path);
+ return BaseFileSystem.DeleteDirectory(path);
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
path = PathTools.Normalize(path);
- if (IsConcatenationFile(path)) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ if (IsConcatenationFile(path)) return ResultFs.PathNotFound.Log();
- BaseFileSystem.DeleteDirectoryRecursively(path);
+ return BaseFileSystem.DeleteDirectoryRecursively(path);
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
path = PathTools.Normalize(path);
- if (IsConcatenationFile(path)) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ if (IsConcatenationFile(path)) return ResultFs.PathNotFound.Log();
- BaseFileSystem.CleanDirectoryRecursively(path);
+ return BaseFileSystem.CleanDirectoryRecursively(path);
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
path = PathTools.Normalize(path);
if (!IsConcatenationFile(path))
{
- BaseFileSystem.DeleteFile(path);
+ return BaseFileSystem.DeleteFile(path);
}
int count = GetSubFileCount(path);
for (int i = 0; i < count; i++)
{
- BaseFileSystem.DeleteFile(GetSubFilePath(path, i));
+ Result rc = BaseFileSystem.DeleteFile(GetSubFilePath(path, i));
+ if (rc.IsFailure()) return rc;
}
- BaseFileSystem.DeleteDirectory(path);
+ return BaseFileSystem.DeleteDirectory(path);
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
+ directory = default;
path = PathTools.Normalize(path);
if (IsConcatenationFile(path))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- IDirectory parentDir = BaseFileSystem.OpenDirectory(path, OpenDirectoryMode.All);
- var dir = new ConcatenationDirectory(this, parentDir, mode);
- return dir;
+ Result rc = BaseFileSystem.OpenDirectory(out IDirectory parentDir, path, OpenDirectoryMode.All);
+ if (rc.IsFailure()) return rc;
+
+ directory = new ConcatenationDirectory(this, parentDir, mode);
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
+ file = default;
path = PathTools.Normalize(path);
if (!IsConcatenationFile(path))
{
- return BaseFileSystem.OpenFile(path, mode);
+ return BaseFileSystem.OpenFile(out file, path, mode);
}
int fileCount = GetSubFileCount(path);
@@ -221,75 +243,85 @@ namespace LibHac.Fs
for (int i = 0; i < fileCount; i++)
{
string filePath = GetSubFilePath(path, i);
- IFile file = BaseFileSystem.OpenFile(filePath, mode);
- files.Add(file);
+
+ Result rc = BaseFileSystem.OpenFile(out IFile subFile, filePath, mode);
+ if (rc.IsFailure()) return rc;
+
+ files.Add(subFile);
}
- return new ConcatenationFile(BaseFileSystem, path, files, SubFileSize, mode);
+ file = new ConcatenationFile(BaseFileSystem, path, files, SubFileSize, mode);
+ return Result.Success;
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
- if (IsConcatenationFile(srcPath))
+ if (IsConcatenationFile(oldPath))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- BaseFileSystem.RenameDirectory(srcPath, dstPath);
+ return BaseFileSystem.RenameDirectory(oldPath, newPath);
}
- public void RenameFile(string srcPath, string dstPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
- if (IsConcatenationFile(srcPath))
+ if (IsConcatenationFile(oldPath))
{
- BaseFileSystem.RenameDirectory(srcPath, dstPath);
+ return BaseFileSystem.RenameDirectory(oldPath, newPath);
}
else
{
- BaseFileSystem.RenameFile(srcPath, dstPath);
+ return BaseFileSystem.RenameFile(oldPath, newPath);
}
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
path = PathTools.Normalize(path);
- if (IsConcatenationFile(path)) return DirectoryEntryType.File;
+ if (IsConcatenationFile(path))
+ {
+ entryType = DirectoryEntryType.File;
+ return Result.Success;
+ }
- return BaseFileSystem.GetEntryType(path);
+ return BaseFileSystem.GetEntryType(out entryType, path);
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- return BaseFileSystem.GetFreeSpaceSize(path);
+ return BaseFileSystem.GetFreeSpaceSize(out freeSpace, path);
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- return BaseFileSystem.GetTotalSpaceSize(path);
+ return BaseFileSystem.GetTotalSpaceSize(out totalSpace, path);
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- return BaseFileSystem.GetFileTimeStampRaw(path);
+ return BaseFileSystem.GetFileTimeStampRaw(out timeStamp, path);
}
- public void Commit()
+ public Result Commit()
{
- BaseFileSystem.Commit();
+ return BaseFileSystem.Commit();
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId)
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
{
- if (queryId != QueryId.MakeConcatFile) ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationInConcatFsQueryEntry);
+ if (queryId != QueryId.MakeConcatFile) return ResultFs.UnsupportedOperationInConcatFsQueryEntry.Log();
SetConcatenationFileAttribute(path);
+
+ return Result.Success;
}
private int GetSubFileCount(string dirPath)
diff --git a/src/LibHac/Fs/DirectorySaveDataFileSystem.cs b/src/LibHac/Fs/DirectorySaveDataFileSystem.cs
index 3fe9f866..9e4aca7e 100644
--- a/src/LibHac/Fs/DirectorySaveDataFileSystem.cs
+++ b/src/LibHac/Fs/DirectorySaveDataFileSystem.cs
@@ -33,162 +33,170 @@ namespace LibHac.Fs
}
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- BaseFs.CreateDirectory(fullPath);
+ return BaseFs.CreateDirectory(fullPath);
}
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- BaseFs.CreateFile(fullPath, size, options);
+ return BaseFs.CreateFile(fullPath, size, options);
}
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- BaseFs.DeleteDirectory(fullPath);
+ return BaseFs.DeleteDirectory(fullPath);
}
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- BaseFs.DeleteDirectoryRecursively(fullPath);
+ return BaseFs.DeleteDirectoryRecursively(fullPath);
}
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- BaseFs.CleanDirectoryRecursively(fullPath);
+ return BaseFs.CleanDirectoryRecursively(fullPath);
}
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- BaseFs.DeleteFile(fullPath);
+ return BaseFs.DeleteFile(fullPath);
}
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- return BaseFs.OpenDirectory(fullPath, mode);
+ return BaseFs.OpenDirectory(out directory, fullPath, mode);
}
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
+ file = default;
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- IFile baseFile = BaseFs.OpenFile(fullPath, mode);
- var file = new DirectorySaveDataFile(this, baseFile);
+ Result rc = BaseFs.OpenFile(out IFile baseFile, fullPath, mode);
+ if (rc.IsFailure()) return rc;
+
+ file = new DirectorySaveDataFile(this, baseFile);
if (mode.HasFlag(OpenMode.Write))
{
OpenWritableFileCount++;
}
- return file;
+ return Result.Success;
}
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- string fullSrcPath = GetFullPath(PathTools.Normalize(srcPath));
- string fullDstPath = GetFullPath(PathTools.Normalize(dstPath));
+ string fullOldPath = GetFullPath(PathTools.Normalize(oldPath));
+ string fullNewPath = GetFullPath(PathTools.Normalize(newPath));
lock (Locker)
{
- BaseFs.RenameDirectory(fullSrcPath, fullDstPath);
+ return BaseFs.RenameDirectory(fullOldPath, fullNewPath);
}
}
- public void RenameFile(string srcPath, string dstPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- string fullSrcPath = GetFullPath(PathTools.Normalize(srcPath));
- string fullDstPath = GetFullPath(PathTools.Normalize(dstPath));
+ string fullOldPath = GetFullPath(PathTools.Normalize(oldPath));
+ string fullNewPath = GetFullPath(PathTools.Normalize(newPath));
lock (Locker)
{
- BaseFs.RenameFile(fullSrcPath, fullDstPath);
+ return BaseFs.RenameFile(fullOldPath, fullNewPath);
}
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
string fullPath = GetFullPath(PathTools.Normalize(path));
lock (Locker)
{
- return BaseFs.GetEntryType(fullPath);
+ return BaseFs.GetEntryType(out entryType, fullPath);
}
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ freeSpace = default;
+ return ResultFs.NotImplemented.Log();
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ totalSpace = default;
+ return ResultFs.NotImplemented.Log();
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ timeStamp = default;
+ return ResultFs.NotImplemented.Log();
}
- public void Commit()
+ public Result Commit()
{
- if (OpenWritableFileCount > 0)
+ lock (Locker)
{
- ThrowHelper.ThrowResult(ResultFs.WritableFileOpen,
- "All files must be closed before commiting save data.");
+ if (OpenWritableFileCount > 0)
+ {
+ // All files must be closed before commiting save data.
+ return ResultFs.WritableFileOpen.Log();
+ }
+
+ Result rc = SynchronizeDirectory(SyncDir, WorkingDir);
+ if (rc.IsFailure()) return rc;
+
+ rc = BaseFs.DeleteDirectoryRecursively(CommittedDir);
+ if (rc.IsFailure()) return rc;
+
+ return BaseFs.RenameDirectory(SyncDir, CommittedDir);
}
-
- SynchronizeDirectory(SyncDir, WorkingDir);
-
- BaseFs.DeleteDirectoryRecursively(CommittedDir);
-
- BaseFs.RenameDirectory(SyncDir, CommittedDir);
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId)
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
+ return ResultFs.NotImplemented.Log();
}
private string GetFullPath(string path)
@@ -196,19 +204,21 @@ namespace LibHac.Fs
return PathTools.Normalize(PathTools.Combine(WorkingDir, path));
}
- private void SynchronizeDirectory(string dest, string src)
+ private Result SynchronizeDirectory(string dest, string src)
{
- if (BaseFs.DirectoryExists(dest))
- {
- BaseFs.DeleteDirectoryRecursively(dest);
- }
+ Result rc = BaseFs.DeleteDirectoryRecursively(dest);
+ if (rc.IsFailure() && rc != ResultFs.PathNotFound) return rc;
- BaseFs.CreateDirectory(dest);
+ rc = BaseFs.CreateDirectory(dest);
+ if (rc.IsFailure()) return rc;
- IDirectory sourceDir = BaseFs.OpenDirectory(src, OpenDirectoryMode.All);
- IDirectory destDir = BaseFs.OpenDirectory(dest, OpenDirectoryMode.All);
+ rc = BaseFs.OpenDirectory(out IDirectory sourceDir, src, OpenDirectoryMode.All);
+ if (rc.IsFailure()) return rc;
- sourceDir.CopyDirectory(destDir);
+ rc = BaseFs.OpenDirectory(out IDirectory destDir, dest, OpenDirectoryMode.All);
+ if (rc.IsFailure()) return rc;
+
+ return sourceDir.CopyDirectory(destDir);
}
internal void NotifyCloseWritableFile()
diff --git a/src/LibHac/Fs/FileSystemExtensions.cs b/src/LibHac/Fs/FileSystemExtensions.cs
index 22643be6..50997c48 100644
--- a/src/LibHac/Fs/FileSystemExtensions.cs
+++ b/src/LibHac/Fs/FileSystemExtensions.cs
@@ -7,10 +7,11 @@ namespace LibHac.Fs
{
public static class FileSystemExtensions
{
- public static void CopyDirectory(this IDirectory source, IDirectory dest, IProgressReport logger = null, CreateFileOptions options = CreateFileOptions.None)
+ public static Result CopyDirectory(this IDirectory source, IDirectory dest, IProgressReport logger = null, CreateFileOptions options = CreateFileOptions.None)
{
IFileSystem sourceFs = source.ParentFileSystem;
IFileSystem destFs = dest.ParentFileSystem;
+ Result rc;
foreach (DirectoryEntry entry in source.Read())
{
@@ -20,32 +21,47 @@ namespace LibHac.Fs
if (entry.Type == DirectoryEntryType.Directory)
{
destFs.EnsureDirectoryExists(subDstPath);
- IDirectory subSrcDir = sourceFs.OpenDirectory(subSrcPath, OpenDirectoryMode.All);
- IDirectory subDstDir = destFs.OpenDirectory(subDstPath, OpenDirectoryMode.All);
- subSrcDir.CopyDirectory(subDstDir, logger, options);
+ rc = sourceFs.OpenDirectory(out IDirectory subSrcDir, subSrcPath, OpenDirectoryMode.All);
+ if (rc.IsFailure()) return rc;
+
+ rc = destFs.OpenDirectory(out IDirectory subDstDir, subDstPath, OpenDirectoryMode.All);
+ if (rc.IsFailure()) return rc;
+
+ rc = subSrcDir.CopyDirectory(subDstDir, logger, options);
+ if (rc.IsFailure()) return rc;
}
if (entry.Type == DirectoryEntryType.File)
{
destFs.CreateOrOverwriteFile(subDstPath, entry.Size, options);
- using (IFile srcFile = sourceFs.OpenFile(subSrcPath, OpenMode.Read))
- using (IFile dstFile = destFs.OpenFile(subDstPath, OpenMode.Write | OpenMode.AllowAppend))
+ rc = sourceFs.OpenFile(out IFile srcFile, subSrcPath, OpenMode.Read);
+ if (rc.IsFailure()) return rc;
+
+ using (srcFile)
{
- logger?.LogMessage(subSrcPath);
- srcFile.CopyTo(dstFile, logger);
+ rc = destFs.OpenFile(out IFile dstFile, subDstPath, OpenMode.Write | OpenMode.AllowAppend);
+ if (rc.IsFailure()) return rc;
+
+ using (dstFile)
+ {
+ logger?.LogMessage(subSrcPath);
+ srcFile.CopyTo(dstFile, logger);
+ }
}
}
}
+
+ return Result.Success;
}
public static void CopyFileSystem(this IFileSystem source, IFileSystem dest, IProgressReport logger = null, CreateFileOptions options = CreateFileOptions.None)
{
- IDirectory sourceRoot = source.OpenDirectory("/", OpenDirectoryMode.All);
- IDirectory destRoot = dest.OpenDirectory("/", OpenDirectoryMode.All);
+ source.OpenDirectory(out IDirectory sourceRoot, "/", OpenDirectoryMode.All).ThrowIfFailure();
+ dest.OpenDirectory(out IDirectory destRoot, "/", OpenDirectoryMode.All).ThrowIfFailure();
- sourceRoot.CopyDirectory(destRoot, logger, options);
+ sourceRoot.CopyDirectory(destRoot, logger, options).ThrowIfFailure();
}
public static void Extract(this IFileSystem source, string destinationPath, IProgressReport logger = null)
@@ -67,7 +83,9 @@ namespace LibHac.Fs
public static IEnumerable EnumerateEntries(this IFileSystem fileSystem, string searchPattern, SearchOptions searchOptions)
{
- return fileSystem.OpenDirectory("/", OpenDirectoryMode.All).EnumerateEntries(searchPattern, searchOptions);
+ fileSystem.OpenDirectory(out IDirectory rootDir, "/", OpenDirectoryMode.All).ThrowIfFailure();
+
+ return rootDir.EnumerateEntries(searchPattern, searchOptions);
}
public static IEnumerable EnumerateEntries(this IDirectory directory)
@@ -91,7 +109,7 @@ namespace LibHac.Fs
if (entry.Type != DirectoryEntryType.Directory || !recurse) continue;
- IDirectory subDir = fs.OpenDirectory(PathTools.Combine(directory.FullPath, entry.Name), OpenDirectoryMode.All);
+ fs.OpenDirectory(out IDirectory subDir, PathTools.Combine(directory.FullPath, entry.Name), OpenDirectoryMode.All).ThrowIfFailure();
foreach (DirectoryEntry subEntry in subDir.EnumerateEntries(searchPattern, searchOptions))
{
@@ -139,7 +157,9 @@ namespace LibHac.Fs
public static int GetEntryCount(this IFileSystem fs, OpenDirectoryMode mode)
{
- return fs.OpenDirectory("/", OpenDirectoryMode.All).GetEntryCountRecursive(mode);
+ fs.OpenDirectory(out IDirectory rootDir, "/", OpenDirectoryMode.All).ThrowIfFailure();
+
+ return rootDir.GetEntryCountRecursive(mode);
}
public static int GetEntryCountRecursive(this IDirectory directory, OpenDirectoryMode mode)
@@ -171,7 +191,7 @@ namespace LibHac.Fs
public static void SetConcatenationFileAttribute(this IFileSystem fs, string path)
{
- fs.QueryEntry(Span.Empty, Span.Empty, path, QueryId.MakeConcatFile);
+ fs.QueryEntry(Span.Empty, Span.Empty, QueryId.MakeConcatFile, path);
}
public static void CleanDirectoryRecursivelyGeneric(IDirectory directory)
@@ -184,7 +204,7 @@ namespace LibHac.Fs
if (entry.Type == DirectoryEntryType.Directory)
{
- IDirectory subDir = fs.OpenDirectory(subPath, OpenDirectoryMode.All);
+ fs.OpenDirectory(out IDirectory subDir, subPath, OpenDirectoryMode.All).ThrowIfFailure();
CleanDirectoryRecursivelyGeneric(subDir);
fs.DeleteDirectory(subPath);
@@ -208,12 +228,16 @@ namespace LibHac.Fs
public static bool DirectoryExists(this IFileSystem fs, string path)
{
- return fs.GetEntryType(path) == DirectoryEntryType.Directory;
+ Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
+
+ return (rc.IsSuccess() && type == DirectoryEntryType.Directory);
}
public static bool FileExists(this IFileSystem fs, string path)
{
- return fs.GetEntryType(path) == DirectoryEntryType.File;
+ Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
+
+ return (rc.IsSuccess() && type == DirectoryEntryType.File);
}
public static void EnsureDirectoryExists(this IFileSystem fs, string path)
diff --git a/src/LibHac/Fs/IFileSystem.cs b/src/LibHac/Fs/IFileSystem.cs
index dc62fb24..0703baf9 100644
--- a/src/LibHac/Fs/IFileSystem.cs
+++ b/src/LibHac/Fs/IFileSystem.cs
@@ -11,14 +11,15 @@ namespace LibHac.Fs
/// Creates all directories and subdirectories in the specified path unless they already exist.
///
/// The full path of the directory to create.
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The parent directory of the specified path does not exist:
/// Specified path already exists as either a file or directory:
/// Insufficient free space to create the directory:
///
- void CreateDirectory(string path);
+ Result CreateDirectory(string path);
///
/// Creates or overwrites a file at the specified path.
@@ -27,162 +28,177 @@ namespace LibHac.Fs
/// The initial size of the created file.
/// Flags to control how the file is created.
/// Should usually be
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The parent directory of the specified path does not exist:
/// Specified path already exists as either a file or directory:
/// Insufficient free space to create the file:
///
- void CreateFile(string path, long size, CreateFileOptions options);
+ Result CreateFile(string path, long size, CreateFileOptions options);
///
/// Deletes the specified directory.
///
/// The full path of the directory to delete.
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The specified path does not exist or is a file:
/// The specified directory is not empty:
///
- void DeleteDirectory(string path);
+ Result DeleteDirectory(string path);
///
/// Deletes the specified directory and any subdirectories and files in the directory.
///
/// The full path of the directory to delete.
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The specified path does not exist or is a file:
///
- void DeleteDirectoryRecursively(string path);
+ Result DeleteDirectoryRecursively(string path);
///
/// Deletes any subdirectories and files in the specified directory.
///
/// The full path of the directory to clean.
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The specified path does not exist or is a file:
///
- void CleanDirectoryRecursively(string path);
+ Result CleanDirectoryRecursively(string path);
///
/// Deletes the specified file.
///
/// The full path of the file to delete.
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The specified path does not exist or is a directory:
///
- void DeleteFile(string path);
+ Result DeleteFile(string path);
///
/// Creates an instance for enumerating the specified directory.
///
+ /// If the operation returns successfully,
+ /// An instance for the specified directory.
/// The directory's full path.
/// Specifies which sub-entries should be enumerated.
- /// An instance for the specified directory.
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The specified path does not exist or is a file:
///
- IDirectory OpenDirectory(string path, OpenDirectoryMode mode);
+ Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode);
///
/// Opens an instance for the specified path.
///
+ /// If the operation returns successfully,
+ /// An instance for the specified path.
/// The full path of the file to open.
/// Specifies the access permissions of the created .
- /// An instance for the specified path.
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The specified path does not exist or is a directory:
///
- IFile OpenFile(string path, OpenMode mode);
+ Result OpenFile(out IFile file, string path, OpenMode mode);
///
/// Renames or moves a directory to a new location.
///
- /// The full path of the directory to rename.
- /// The new full path of the directory.
- /// An instance for the specified path.
+ /// The full path of the directory to rename.
+ /// The new full path of the directory.
+ /// The of the requested operation.
///
- /// If and are the same, this function does nothing and returns successfully.
- /// A will be thrown with the given under the following conditions:
+ /// If and are the same, this function does nothing and returns .
+ /// The following codes may be returned under certain conditions:
///
- /// does not exist or is a file:
- /// 's parent directory does not exist:
- /// already exists as either a file or directory:
- /// Either or is a subpath of the other:
+ /// does not exist or is a file:
+ /// 's parent directory does not exist:
+ /// already exists as either a file or directory:
+ /// Either or is a subpath of the other:
///
- void RenameDirectory(string srcPath, string dstPath);
+ Result RenameDirectory(string oldPath, string newPath);
///
/// Renames or moves a file to a new location.
///
- /// The full path of the file to rename.
- /// The new full path of the file.
+ /// The full path of the file to rename.
+ /// The new full path of the file.
+ /// The of the requested operation.
///
- /// If and are the same, this function does nothing and returns successfully.
- /// A will be thrown with the given under the following conditions:
+ /// If and are the same, this function does nothing and returns successfully.
+ /// The following codes may be returned under certain conditions:
///
- /// does not exist or is a directory:
- /// 's parent directory does not exist:
- /// already exists as either a file or directory:
+ /// does not exist or is a directory:
+ /// 's parent directory does not exist:
+ /// already exists as either a file or directory:
///
- void RenameFile(string srcPath, string dstPath);
+ Result RenameFile(string oldPath, string newPath);
///
/// Determines whether the specified path is a file or directory, or does not exist.
///
+ /// If the operation returns successfully, the of the file.
/// The full path to check.
- /// The of the file.
+ /// The of the requested operation.
///
/// This function operates slightly differently than it does in Horizon OS.
/// Instead of returning when an entry is missing,
/// the function will return .
///
- DirectoryEntryType GetEntryType(string path);
+ Result GetEntryType(out DirectoryEntryType entryType, string path);
///
/// Gets the amount of available free space on a drive, in bytes.
///
+ /// If the operation returns successfully, the amount of free space available on the drive, in bytes.
/// The path of the drive to query. Unused in almost all cases.
- /// The amount of free space available on the drive, in bytes.
- long GetFreeSpaceSize(string path);
+ /// The of the requested operation.
+ Result GetFreeSpaceSize(out long freeSpace, string path);
///
/// Gets the total size of storage space on a drive, in bytes.
///
+ /// If the operation returns successfully, the total size of the drive, in bytes.
/// The path of the drive to query. Unused in almost all cases.
- /// The total size of the drive, in bytes.
- long GetTotalSpaceSize(string path);
+ /// The of the requested operation.
+ Result GetTotalSpaceSize(out long totalSpace, string path);
///
/// Gets the creation, last accessed, and last modified timestamps of a file or directory.
///
+ /// If the operation returns successfully, the timestamps for the specified file or directory.
+ /// These value are expressed as Unix timestamps.
/// The path of the file or directory.
- /// The timestamps for the specified file or directory.
- /// This value is expressed as a Unix timestamp
+ /// The of the requested operation.
///
- /// A will be thrown with the given under the following conditions:
+ /// The following codes may be returned under certain conditions:
///
/// The specified path does not exist:
///
- FileTimeStampRaw GetFileTimeStampRaw(string path);
+ Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path);
///
/// Commits any changes to a transactional file system.
/// Does nothing if called on a non-transactional file system.
///
- void Commit();
+ /// The of the requested operation.
+ Result Commit();
///
/// Performs a query on the specified file.
@@ -193,9 +209,10 @@ namespace LibHac.Fs
/// May be unused depending on the query type.
/// The buffer for sending data to the query operation.
/// May be unused depending on the query type.
- /// The full path of the file to query.
/// The type of query to perform.
- void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId);
+ /// The full path of the file to query.
+ /// The of the requested operation.
+ Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path);
}
///
diff --git a/src/LibHac/Fs/LayeredFileSystem.cs b/src/LibHac/Fs/LayeredFileSystem.cs
index d0e23930..500dde46 100644
--- a/src/LibHac/Fs/LayeredFileSystem.cs
+++ b/src/LibHac/Fs/LayeredFileSystem.cs
@@ -12,122 +12,138 @@ namespace LibHac.Fs
Sources.AddRange(sourceFileSystems);
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
+ directory = default;
path = PathTools.Normalize(path);
var dirs = new List();
foreach (IFileSystem fs in Sources)
{
- DirectoryEntryType type = fs.GetEntryType(path);
+ Result rc = fs.GetEntryType(out DirectoryEntryType entryType, path);
+ if (rc.IsFailure()) return rc;
- if (type == DirectoryEntryType.File && dirs.Count == 0)
+ if (entryType == DirectoryEntryType.File && dirs.Count == 0)
{
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
- if (fs.GetEntryType(path) == DirectoryEntryType.Directory)
+ if (entryType == DirectoryEntryType.Directory)
{
- dirs.Add(fs.OpenDirectory(path, mode));
+ rc = fs.OpenDirectory(out IDirectory subDirectory, path, mode);
+ if (rc.IsFailure()) return rc;
+
+ dirs.Add(subDirectory);
}
}
- var dir = new LayeredFileSystemDirectory(this, dirs, path, mode);
-
- return dir;
+ directory = new LayeredFileSystemDirectory(this, dirs, path, mode);
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
+ file = default;
path = PathTools.Normalize(path);
foreach (IFileSystem fs in Sources)
{
- DirectoryEntryType type = fs.GetEntryType(path);
+ Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
+ if (rc.IsFailure()) return rc;
if (type == DirectoryEntryType.File)
{
- return fs.OpenFile(path, mode);
+ return fs.OpenFile(out file, path, mode);
}
if (type == DirectoryEntryType.Directory)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
}
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
- return default;
+ return ResultFs.PathNotFound.Log();
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
path = PathTools.Normalize(path);
foreach (IFileSystem fs in Sources)
{
- DirectoryEntryType type = fs.GetEntryType(path);
+ Result getEntryResult = fs.GetEntryType(out DirectoryEntryType type, path);
- if (type != DirectoryEntryType.NotFound) return type;
- }
-
- return DirectoryEntryType.NotFound;
- }
-
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
- {
- path = PathTools.Normalize(path);
-
- foreach (IFileSystem fs in Sources)
- {
- if (fs.GetEntryType(path) != DirectoryEntryType.NotFound)
+ if (getEntryResult.IsSuccess() && type != DirectoryEntryType.NotFound)
{
- return fs.GetFileTimeStampRaw(path);
+ entryType = type;
+ return Result.Success;
}
}
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
- return default;
+ entryType = DirectoryEntryType.NotFound;
+ return ResultFs.PathNotFound.Log();
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
path = PathTools.Normalize(path);
foreach (IFileSystem fs in Sources)
{
- if (fs.GetEntryType(path) != DirectoryEntryType.NotFound)
+ Result getEntryResult = fs.GetEntryType(out DirectoryEntryType type, path);
+
+ if (getEntryResult.IsSuccess() && type != DirectoryEntryType.NotFound)
{
- fs.QueryEntry(outBuffer, inBuffer, path, queryId);
- return;
+ return fs.GetFileTimeStampRaw(out timeStamp, path);
}
}
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ timeStamp = default;
+ return ResultFs.PathNotFound.Log();
}
- public void Commit() { }
-
- public void CreateDirectory(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- public void CreateFile(string path, long size, CreateFileOptions options) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- public void DeleteDirectory(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- public void DeleteDirectoryRecursively(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- public void CleanDirectoryRecursively(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- public void DeleteFile(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- public void RenameDirectory(string srcPath, string dstPath) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- public void RenameFile(string srcPath, string dstPath) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
-
- public long GetFreeSpaceSize(string path)
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
{
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- return default;
+ path = PathTools.Normalize(path);
+
+ foreach (IFileSystem fs in Sources)
+ {
+ Result getEntryResult = fs.GetEntryType(out DirectoryEntryType type, path);
+
+ if (getEntryResult.IsSuccess() && type != DirectoryEntryType.NotFound)
+ {
+ return fs.QueryEntry(outBuffer, inBuffer, queryId, path);
+ }
+ }
+
+ return ResultFs.PathNotFound.Log();
}
- public long GetTotalSpaceSize(string path)
+ public Result Commit()
{
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
- return default;
+ return Result.Success;
+ }
+
+ public Result CreateDirectory(string path) => ResultFs.UnsupportedOperation.Log();
+ public Result CreateFile(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperation.Log();
+ public Result DeleteDirectory(string path) => ResultFs.UnsupportedOperation.Log();
+ public Result DeleteDirectoryRecursively(string path) => ResultFs.UnsupportedOperation.Log();
+ public Result CleanDirectoryRecursively(string path) => ResultFs.UnsupportedOperation.Log();
+ public Result DeleteFile(string path) => ResultFs.UnsupportedOperation.Log();
+ public Result RenameDirectory(string oldPath, string newPath) => ResultFs.UnsupportedOperation.Log();
+ public Result RenameFile(string oldPath, string newPath) => ResultFs.UnsupportedOperation.Log();
+
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
+ {
+ freeSpace = default;
+ return ResultFs.UnsupportedOperation.Log();
+ }
+
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
+ {
+ totalSpace = default;
+ return ResultFs.UnsupportedOperation.Log();
}
}
}
diff --git a/src/LibHac/Fs/LocalFileSystem.cs b/src/LibHac/Fs/LocalFileSystem.cs
index 048e5c71..33c4b28b 100644
--- a/src/LibHac/Fs/LocalFileSystem.cs
+++ b/src/LibHac/Fs/LocalFileSystem.cs
@@ -58,7 +58,7 @@ namespace LibHac.Fs
return GetSizeInternal(info);
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@@ -66,18 +66,18 @@ namespace LibHac.Fs
if (dir.Exists)
{
- ThrowHelper.ThrowResult(ResultFs.PathAlreadyExists);
+ return ResultFs.PathAlreadyExists.Log();
}
if (dir.Parent?.Exists != true)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- CreateDirInternal(dir);
+ return CreateDirInternal(dir);
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@@ -85,121 +85,140 @@ namespace LibHac.Fs
if (file.Exists)
{
- ThrowHelper.ThrowResult(ResultFs.PathAlreadyExists);
+ return ResultFs.PathAlreadyExists.Log();
}
if (file.Directory?.Exists != true)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- using (FileStream stream = CreateFileInternal(file))
+ Result rc = CreateFileInternal(out FileStream stream, file);
+
+ using (stream)
{
- SetStreamLengthInternal(stream, size);
+ if (rc.IsFailure()) return rc;
+
+ return SetStreamLengthInternal(stream, size);
}
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
DirectoryInfo dir = GetDirInfo(localPath);
- DeleteDirectoryInternal(dir, false);
+ return DeleteDirectoryInternal(dir, false);
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
DirectoryInfo dir = GetDirInfo(localPath);
- DeleteDirectoryInternal(dir, true);
+ return DeleteDirectoryInternal(dir, true);
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
foreach (string file in Directory.EnumerateFiles(localPath))
{
- DeleteFileInternal(GetFileInfo(file));
+ Result rc = DeleteFileInternal(GetFileInfo(file));
+ if (rc.IsFailure()) return rc;
}
foreach (string dir in Directory.EnumerateDirectories(localPath))
{
- DeleteDirectoryInternal(GetDirInfo(dir), true);
+ Result rc = DeleteDirectoryInternal(GetDirInfo(dir), true);
+ if (rc.IsFailure()) return rc;
}
+
+ return Result.Success;
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
FileInfo file = GetFileInfo(localPath);
- DeleteFileInternal(file);
+ return DeleteFileInternal(file);
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
+ // Getting the local path is done in the LocalDirectory constructor
path = PathTools.Normalize(path);
+ directory = default;
- if (GetEntryType(path) == DirectoryEntryType.File)
+ Result rc = GetEntryType(out DirectoryEntryType entryType, path);
+ if (rc.IsFailure()) return rc;
+
+ if (entryType == DirectoryEntryType.File)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- return new LocalDirectory(this, path, mode);
+ directory = new LocalDirectory(this, path, mode);
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
+ file = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path));
- if (GetEntryType(path) == DirectoryEntryType.Directory)
+ Result rc = GetEntryType(out DirectoryEntryType entryType, path);
+ if (rc.IsFailure()) return rc;
+
+ if (entryType == DirectoryEntryType.Directory)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- return new LocalFile(localPath, mode);
+ file = new LocalFile(localPath, mode);
+ return Result.Success;
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
// Official FS behavior is to do nothing in this case
- if (srcPath == dstPath) return;
+ if (oldPath == newPath) return Result.Success;
// FS does the subpath check before verifying the path exists
- if (PathTools.IsSubPath(srcPath.AsSpan(), dstPath.AsSpan()))
+ if (PathTools.IsSubPath(oldPath.AsSpan(), newPath.AsSpan()))
{
ThrowHelper.ThrowResult(ResultFs.DestinationIsSubPathOfSource);
}
- DirectoryInfo srcDir = GetDirInfo(ResolveLocalPath(srcPath));
- DirectoryInfo dstDir = GetDirInfo(ResolveLocalPath(dstPath));
+ DirectoryInfo srcDir = GetDirInfo(ResolveLocalPath(oldPath));
+ DirectoryInfo dstDir = GetDirInfo(ResolveLocalPath(newPath));
- RenameDirInternal(srcDir, dstDir);
+ return RenameDirInternal(srcDir, dstDir);
}
- public void RenameFile(string srcPath, string dstPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- string srcLocalPath = ResolveLocalPath(PathTools.Normalize(srcPath));
- string dstLocalPath = ResolveLocalPath(PathTools.Normalize(dstPath));
+ string srcLocalPath = ResolveLocalPath(PathTools.Normalize(oldPath));
+ string dstLocalPath = ResolveLocalPath(PathTools.Normalize(newPath));
// Official FS behavior is to do nothing in this case
- if (srcLocalPath == dstLocalPath) return;
+ if (srcLocalPath == dstLocalPath) return Result.Success;
FileInfo srcFile = GetFileInfo(srcLocalPath);
FileInfo dstFile = GetFileInfo(dstLocalPath);
- RenameFileInternal(srcFile, dstFile);
+ return RenameFileInternal(srcFile, dstFile);
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@@ -207,48 +226,57 @@ namespace LibHac.Fs
if (dir.Exists)
{
- return DirectoryEntryType.Directory;
+ entryType = DirectoryEntryType.Directory;
+ return Result.Success;
}
FileInfo file = GetFileInfo(localPath);
if (file.Exists)
{
- return DirectoryEntryType.File;
+ entryType = DirectoryEntryType.File;
+ return Result.Success;
}
- return DirectoryEntryType.NotFound;
+ entryType = DirectoryEntryType.NotFound;
+ return ResultFs.PathNotFound.Log();
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
+ timeStamp = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path));
- if (!GetFileInfo(localPath).Exists) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
-
- FileTimeStampRaw timeStamp = default;
+ if (!GetFileInfo(localPath).Exists) return ResultFs.PathNotFound.Log();
timeStamp.Created = new DateTimeOffset(File.GetCreationTime(localPath)).ToUnixTimeSeconds();
timeStamp.Accessed = new DateTimeOffset(File.GetLastAccessTime(localPath)).ToUnixTimeSeconds();
timeStamp.Modified = new DateTimeOffset(File.GetLastWriteTime(localPath)).ToUnixTimeSeconds();
- return timeStamp;
+ return Result.Success;
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- return new DriveInfo(BasePath).AvailableFreeSpace;
+ freeSpace = new DriveInfo(BasePath).AvailableFreeSpace;
+ return Result.Success;
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- return new DriveInfo(BasePath).TotalSize;
+ totalSpace = new DriveInfo(BasePath).TotalSize;
+ return Result.Success;
}
- public void Commit() { }
+ public Result Commit()
+ {
+ return Result.Success;
+ }
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
+ {
+ return ResultFs.UnsupportedOperation.Log();
+ }
private static long GetSizeInternal(FileInfo file)
{
@@ -268,35 +296,36 @@ namespace LibHac.Fs
}
}
- private static FileStream CreateFileInternal(FileInfo file)
+ private static Result CreateFileInternal(out FileStream file, FileInfo fileInfo)
{
+ file = default;
+
try
{
- return new FileStream(file.FullName, FileMode.CreateNew, FileAccess.ReadWrite);
+ file = new FileStream(fileInfo.FullName, FileMode.CreateNew, FileAccess.ReadWrite);
}
- catch (DirectoryNotFoundException ex)
+ catch (DirectoryNotFoundException)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound, ex);
- throw;
+ return ResultFs.PathNotFound.Log();
}
catch (IOException ex) when (ex.HResult == ErrorDiskFull || ex.HResult == ErrorHandleDiskFull)
{
- ThrowHelper.ThrowResult(ResultFs.InsufficientFreeSpace, ex);
- throw;
+ return ResultFs.InsufficientFreeSpace.Log();
}
catch (IOException ex) when (ex.HResult == ErrorFileExists)
{
- ThrowHelper.ThrowResult(ResultFs.PathAlreadyExists, ex);
- throw;
+ return ResultFs.PathAlreadyExists.Log();
}
catch (Exception ex) when (ex is SecurityException || ex is UnauthorizedAccessException)
{
- // todo: Should a HorizonResultException be thrown?
+ // todo: What Result value should be returned?
throw;
}
+
+ return Result.Success;
}
- private static void SetStreamLengthInternal(Stream stream, long size)
+ private static Result SetStreamLengthInternal(Stream stream, long size)
{
try
{
@@ -304,128 +333,131 @@ namespace LibHac.Fs
}
catch (IOException ex) when (ex.HResult == ErrorDiskFull || ex.HResult == ErrorHandleDiskFull)
{
- ThrowHelper.ThrowResult(ResultFs.InsufficientFreeSpace, ex);
- throw;
+ return ResultFs.InsufficientFreeSpace.Log();
}
+
+ return Result.Success;
}
- private static void DeleteDirectoryInternal(DirectoryInfo dir, bool recursive)
+ private static Result DeleteDirectoryInternal(DirectoryInfo dir, bool recursive)
{
- if (!dir.Exists) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ if (!dir.Exists) return ResultFs.PathNotFound.Log();
try
{
dir.Delete(recursive);
}
- catch (DirectoryNotFoundException ex)
+ catch (DirectoryNotFoundException)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound, ex);
- throw;
+ return ResultFs.PathNotFound.Log();
}
catch (IOException ex) when (ex.HResult == ErrorDirNotEmpty)
{
- ThrowHelper.ThrowResult(ResultFs.DirectoryNotEmpty, ex);
- throw;
+ return ResultFs.DirectoryNotEmpty.Log();
}
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException)
{
- // todo: Should a HorizonResultException be thrown?
+ // todo: What Result value should be returned?
throw;
}
EnsureDeleted(dir);
+
+ return Result.Success;
}
- private static void DeleteFileInternal(FileInfo file)
+ private static Result DeleteFileInternal(FileInfo file)
{
- if (!file.Exists) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ if (!file.Exists) return ResultFs.PathNotFound.Log();
try
{
file.Delete();
}
- catch (DirectoryNotFoundException ex)
+ catch (DirectoryNotFoundException)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound, ex);
- throw;
+ return ResultFs.PathNotFound.Log();
}
catch (IOException ex) when (ex.HResult == ErrorDirNotEmpty)
{
- ThrowHelper.ThrowResult(ResultFs.DirectoryNotEmpty, ex);
- throw;
+ return ResultFs.DirectoryNotEmpty.Log();
}
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException)
{
- // todo: Should a HorizonResultException be thrown?
+ // todo: What Result value should be returned?
throw;
}
EnsureDeleted(file);
+
+ return Result.Success;
}
- private static void CreateDirInternal(DirectoryInfo dir)
+ private static Result CreateDirInternal(DirectoryInfo dir)
{
try
{
dir.Create();
}
- catch (DirectoryNotFoundException ex)
+ catch (DirectoryNotFoundException)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound, ex);
- throw;
+ return ResultFs.PathNotFound.Log();
}
catch (IOException ex) when (ex.HResult == ErrorDiskFull || ex.HResult == ErrorHandleDiskFull)
{
- ThrowHelper.ThrowResult(ResultFs.InsufficientFreeSpace, ex);
- throw;
+ return ResultFs.InsufficientFreeSpace.Log();
}
catch (Exception ex) when (ex is SecurityException || ex is UnauthorizedAccessException)
{
- // todo: Should a HorizonResultException be thrown?
+ // todo: What Result value should be returned?
throw;
}
+
+ return Result.Success;
}
- private static void RenameDirInternal(DirectoryInfo source, DirectoryInfo dest)
+ private static Result RenameDirInternal(DirectoryInfo source, DirectoryInfo dest)
{
- if (!source.Exists) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
- if (dest.Exists) ThrowHelper.ThrowResult(ResultFs.PathAlreadyExists);
+ if (!source.Exists) return ResultFs.PathNotFound.Log();
+ if (dest.Exists) return ResultFs.PathAlreadyExists.Log();
try
{
source.MoveTo(dest.FullName);
}
- catch (DirectoryNotFoundException ex)
+ catch (DirectoryNotFoundException)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound, ex);
- throw;
+ return ResultFs.PathNotFound.Log();
}
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException)
{
- // todo: Should a HorizonResultException be thrown?
+ // todo: What Result value should be returned?
throw;
}
+
+ return Result.Success;
}
- private static void RenameFileInternal(FileInfo source, FileInfo dest)
+ private static Result RenameFileInternal(FileInfo source, FileInfo dest)
{
- if (!source.Exists) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
- if (dest.Exists) ThrowHelper.ThrowResult(ResultFs.PathAlreadyExists);
+ if (!source.Exists) return ResultFs.PathNotFound.Log();
+ if (dest.Exists) return ResultFs.PathAlreadyExists.Log();
try
{
source.MoveTo(dest.FullName);
}
- catch (DirectoryNotFoundException ex)
+ catch (DirectoryNotFoundException)
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound, ex);
- throw;
+ return ResultFs.PathNotFound.Log();
}
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException)
{
- // todo: Should a HorizonResultException be thrown?
+ // todo: What Result value should be returned?
throw;
}
+
+ return Result.Success;
}
diff --git a/src/LibHac/Fs/PartitionFileSystem.cs b/src/LibHac/Fs/PartitionFileSystem.cs
index e8d75888..a8ba92d4 100644
--- a/src/LibHac/Fs/PartitionFileSystem.cs
+++ b/src/LibHac/Fs/PartitionFileSystem.cs
@@ -29,12 +29,13 @@ namespace LibHac.Fs
BaseStorage = storage;
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
- return new PartitionDirectory(this, path, mode);
+ directory = new PartitionDirectory(this, path, mode);
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
path = PathTools.Normalize(path).TrimStart('/');
@@ -43,7 +44,8 @@ namespace LibHac.Fs
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
- return OpenFile(entry, mode);
+ file = OpenFile(entry, mode);
+ return Result.Success;
}
public IFile OpenFile(PartitionFileEntry entry, OpenMode mode)
@@ -51,46 +53,59 @@ namespace LibHac.Fs
return new PartitionFile(BaseStorage, HeaderSize + entry.Offset, entry.Size, mode);
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
+ entryType = DirectoryEntryType.NotFound;
path = PathTools.Normalize(path);
- if (path == "/") return DirectoryEntryType.Directory;
+ if (path == "/")
+ {
+ entryType = DirectoryEntryType.Directory;
+ return Result.Success;
+ }
- if (FileDict.ContainsKey(path.TrimStart('/'))) return DirectoryEntryType.File;
+ if (FileDict.ContainsKey(path.TrimStart('/')))
+ {
+ entryType = DirectoryEntryType.File;
+ return Result.Success;
+ }
- return DirectoryEntryType.NotFound;
+ return ResultFs.PathNotFound.Log();
}
- public void CreateDirectory(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyPartitionFileSystem);
- public void CreateFile(string path, long size, CreateFileOptions options) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyPartitionFileSystem);
- public void DeleteDirectory(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyPartitionFileSystem);
- public void DeleteDirectoryRecursively(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyPartitionFileSystem);
- public void CleanDirectoryRecursively(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyPartitionFileSystem);
- public void DeleteFile(string path) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyPartitionFileSystem);
- public void RenameDirectory(string srcPath, string dstPath) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyPartitionFileSystem);
- public void RenameFile(string srcPath, string dstPath) => ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyPartitionFileSystem);
+ public Result CreateDirectory(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
+ public Result CreateFile(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
+ public Result DeleteDirectory(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
+ public Result DeleteDirectoryRecursively(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
+ public Result CleanDirectoryRecursively(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
+ public Result DeleteFile(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
+ public Result RenameDirectory(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
+ public Result RenameFile(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ freeSpace = default;
+ return ResultFs.NotImplemented.Log();
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ totalSpace = default;
+ return ResultFs.NotImplemented.Log();
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ timeStamp = default;
+ return ResultFs.NotImplemented.Log();
}
- public void Commit() { }
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId) => ThrowHelper.ThrowResult(ResultFs.NotImplemented);
+ public Result Commit()
+ {
+ return Result.Success;
+ }
+
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path) => ResultFs.NotImplemented.Log();
}
public enum PartitionFileSystemType
diff --git a/src/LibHac/Fs/PartitionFileSystemBuilder.cs b/src/LibHac/Fs/PartitionFileSystemBuilder.cs
index d997dd0f..9a41c18d 100644
--- a/src/LibHac/Fs/PartitionFileSystemBuilder.cs
+++ b/src/LibHac/Fs/PartitionFileSystemBuilder.cs
@@ -22,11 +22,13 @@ namespace LibHac.Fs
///
public PartitionFileSystemBuilder(IFileSystem input)
{
- IDirectory rootDir = input.OpenDirectory("/", OpenDirectoryMode.File);
+ input.OpenDirectory(out IDirectory rootDir, "/", OpenDirectoryMode.File).ThrowIfFailure();
- foreach (DirectoryEntry file in rootDir.Read().OrderBy(x => x.FullPath, StringComparer.Ordinal))
+ foreach (DirectoryEntry entry in rootDir.Read().OrderBy(x => x.FullPath, StringComparer.Ordinal))
{
- AddFile(file.FullPath.TrimStart('/'), input.OpenFile(file.FullPath, OpenMode.Read));
+ input.OpenFile(out IFile file, entry.FullPath, OpenMode.Read).ThrowIfFailure();
+
+ AddFile(entry.FullPath.TrimStart('/'), file);
}
}
diff --git a/src/LibHac/Fs/ReadOnlyFileSystem.cs b/src/LibHac/Fs/ReadOnlyFileSystem.cs
index 43a9d8c3..417b2526 100644
--- a/src/LibHac/Fs/ReadOnlyFileSystem.cs
+++ b/src/LibHac/Fs/ReadOnlyFileSystem.cs
@@ -11,71 +11,82 @@ namespace LibHac.Fs
BaseFs = baseFileSystem;
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
- IDirectory baseDir = BaseFs.OpenDirectory(path, mode);
- return new ReadOnlyDirectory(this, baseDir);
+ directory = default;
+
+ Result rc = BaseFs.OpenDirectory(out IDirectory baseDir, path, mode);
+ if (rc.IsFailure()) return rc;
+
+ directory = new ReadOnlyDirectory(this, baseDir);
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
- IFile baseFile = BaseFs.OpenFile(path, mode);
- return new ReadOnlyFile(baseFile);
+ file = default;
+
+ Result rc = BaseFs.OpenFile(out IFile baseFile, path, mode);
+ if (rc.IsFailure()) return rc;
+
+ file = new ReadOnlyFile(baseFile);
+ return Result.Success;
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
- return BaseFs.GetEntryType(path);
+ return BaseFs.GetEntryType(out entryType, path);
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- return 0;
+ freeSpace = 0;
+ return Result.Success;
+
+ // FS does:
+ // return ResultFs.UnsupportedOperationReadOnlyFileSystemGetSpace.Log();
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- return BaseFs.GetTotalSpaceSize(path);
+ return BaseFs.GetTotalSpaceSize(out totalSpace, path);
+
+ // FS does:
+ // return ResultFs.UnsupportedOperationReadOnlyFileSystemGetSpace.Log();
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- return BaseFs.GetFileTimeStampRaw(path);
+ return BaseFs.GetFileTimeStampRaw(out timeStamp, path);
+
+ // FS does:
+ // return ResultFs.NotImplemented.Log();
}
- public void Commit()
+ public Result Commit()
{
-
+ return Result.Success;
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId)
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
{
- BaseFs.QueryEntry(outBuffer, inBuffer, path, queryId);
+ return ResultFs.NotImplemented.Log();
}
- public void CreateDirectory(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
+ public Result CreateDirectory(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
- public void CreateFile(string path, long size, CreateFileOptions options) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
+ public Result CreateFile(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
- public void DeleteDirectory(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
+ public Result DeleteDirectory(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
- public void DeleteDirectoryRecursively(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
+ public Result DeleteDirectoryRecursively(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
- public void CleanDirectoryRecursively(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
+ public Result CleanDirectoryRecursively(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
- public void DeleteFile(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
+ public Result DeleteFile(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
- public void RenameDirectory(string srcPath, string dstPath) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
-
- public void RenameFile(string srcPath, string dstPath) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
+ public Result RenameDirectory(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
+ public Result RenameFile(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
}
}
diff --git a/src/LibHac/Fs/ResultFs.cs b/src/LibHac/Fs/ResultFs.cs
index a3733289..fcc8eb68 100644
--- a/src/LibHac/Fs/ResultFs.cs
+++ b/src/LibHac/Fs/ResultFs.cs
@@ -11,7 +11,6 @@
public static Result InsufficientFreeSpace => new Result(ModuleFs, 30);
public static Result MountNameAlreadyExists => new Result(ModuleFs, 60);
- public static Result ResultPartitionNotFound => new Result(ModuleFs, 1002);
public static Result TargetNotFound => new Result(ModuleFs, 1002);
public static Result NotImplemented => new Result(ModuleFs, 3001);
diff --git a/src/LibHac/Fs/RomFs/RomFsBuilder.cs b/src/LibHac/Fs/RomFs/RomFsBuilder.cs
index 8d067e6e..055e2c4f 100644
--- a/src/LibHac/Fs/RomFs/RomFsBuilder.cs
+++ b/src/LibHac/Fs/RomFs/RomFsBuilder.cs
@@ -32,10 +32,12 @@ namespace LibHac.Fs.RomFs
///
public RomFsBuilder(IFileSystem input)
{
- foreach (DirectoryEntry file in input.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File)
+ foreach (DirectoryEntry entry in input.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File)
.OrderBy(x => x.FullPath, StringComparer.Ordinal))
{
- AddFile(file.FullPath, input.OpenFile(file.FullPath, OpenMode.Read));
+ input.OpenFile(out IFile file, entry.FullPath, OpenMode.Read).ThrowIfFailure();
+
+ AddFile(entry.FullPath, file);
}
}
diff --git a/src/LibHac/Fs/RomFs/RomFsFileSystem.cs b/src/LibHac/Fs/RomFs/RomFsFileSystem.cs
index ee944186..0b9970a4 100644
--- a/src/LibHac/Fs/RomFs/RomFsFileSystem.cs
+++ b/src/LibHac/Fs/RomFs/RomFsFileSystem.cs
@@ -22,52 +22,63 @@ namespace LibHac.Fs.RomFs
FileTable = new HierarchicalRomFileTable(dirHashTable, dirEntryTable, fileHashTable, fileEntryTable);
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
+ entryType = DirectoryEntryType.NotFound;
path = PathTools.Normalize(path);
if (FileTable.TryOpenFile(path, out RomFileInfo _))
{
- return DirectoryEntryType.File;
+ entryType = DirectoryEntryType.File;
+ return Result.Success;
}
if (FileTable.TryOpenDirectory(path, out FindPosition _))
{
- return DirectoryEntryType.Directory;
+ entryType = DirectoryEntryType.Directory;
+ return Result.Success;
}
- return DirectoryEntryType.NotFound;
+ return ResultFs.PathNotFound.Log();
}
- public void Commit() { }
-
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result Commit()
{
+ return Result.Success;
+ }
+
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
+ {
+ directory = default;
path = PathTools.Normalize(path);
if (!FileTable.TryOpenDirectory(path, out FindPosition position))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- return new RomFsDirectory(this, path, position, mode);
+ directory = new RomFsDirectory(this, path, position, mode);
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
+ file = default;
path = PathTools.Normalize(path);
if (!FileTable.TryOpenFile(path, out RomFileInfo info))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
if (mode != OpenMode.Read)
{
- ThrowHelper.ThrowResult(ResultFs.InvalidArgument, "RomFs files must be opened read-only.");
+ // RomFs files must be opened read-only.
+ return ResultFs.InvalidArgument.Log();
}
- return new RomFsFile(BaseStorage, Header.DataOffset + info.Offset, info.Length);
+ file = new RomFsFile(BaseStorage, Header.DataOffset + info.Offset, info.Length);
+ return Result.Success;
}
public IStorage GetBaseStorage()
@@ -75,50 +86,37 @@ namespace LibHac.Fs.RomFs
return BaseStorage;
}
- public void CreateDirectory(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
+ public Result CreateDirectory(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
+ public Result CreateFile(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
+ public Result DeleteDirectory(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
+ public Result DeleteDirectoryRecursively(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
+ public Result CleanDirectoryRecursively(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
+ public Result DeleteFile(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
+ public Result RenameDirectory(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
+ public Result RenameFile(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
- public void CreateFile(string path, long size, CreateFileOptions options) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
-
- public void DeleteDirectory(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
-
- public void DeleteDirectoryRecursively(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
-
- public void CleanDirectoryRecursively(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
-
- public void DeleteFile(string path) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
-
- public void RenameDirectory(string srcPath, string dstPath) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
-
- public void RenameFile(string srcPath, string dstPath) =>
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
-
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationRomFsFileSystemGetSpace);
- return default;
+ freeSpace = default;
+ return ResultFs.UnsupportedOperationRomFsFileSystemGetSpace.Log();
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationRomFsFileSystemGetSpace);
- return default;
+ totalSpace = default;
+ return ResultFs.UnsupportedOperationRomFsFileSystemGetSpace.Log();
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ timeStamp = default;
+ return ResultFs.NotImplemented.Log();
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId) =>
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
+ {
+ return ResultFs.NotImplemented.Log();
+ }
}
public class RomfsHeader
diff --git a/src/LibHac/Fs/Save/HierarchicalSaveFileTable.cs b/src/LibHac/Fs/Save/HierarchicalSaveFileTable.cs
index 07b8ac5e..78555ee3 100644
--- a/src/LibHac/Fs/Save/HierarchicalSaveFileTable.cs
+++ b/src/LibHac/Fs/Save/HierarchicalSaveFileTable.cs
@@ -338,11 +338,11 @@ namespace LibHac.Fs.Save
FileTable.ChangeKey(ref oldKey, ref newKey);
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string srcPath, string dstPath)
{
if (srcPath == dstPath || TryOpenFile(dstPath, out _) || TryOpenDirectory(dstPath, out _))
{
- throw new IOException(Messages.DestPathAlreadyExists);
+ return ResultFs.PathAlreadyExists.Log();
}
ReadOnlySpan oldPathBytes = Util.GetUtf8Bytes(srcPath);
@@ -350,19 +350,19 @@ namespace LibHac.Fs.Save
if (!FindPathRecursive(oldPathBytes, out SaveEntryKey oldKey))
{
- throw new DirectoryNotFoundException();
+ return ResultFs.PathNotFound.Log();
}
int dirIndex = DirectoryTable.GetIndexFromKey(ref oldKey).Index;
if (!FindPathRecursive(newPathBytes, out SaveEntryKey newKey))
{
- throw new IOException(Messages.PartialPathNotFound);
+ return ResultFs.PathNotFound.Log();
}
if (PathTools.IsSubPath(oldPathBytes, newPathBytes))
{
- ThrowHelper.ThrowResult(ResultFs.DestinationIsSubPathOfSource);
+ return ResultFs.DestinationIsSubPathOfSource.Log();
}
if (oldKey.Parent != newKey.Parent)
@@ -372,6 +372,8 @@ namespace LibHac.Fs.Save
}
DirectoryTable.ChangeKey(ref oldKey, ref newKey);
+
+ return Result.Success;
}
public bool TryOpenDirectory(string path, out SaveFindPosition position)
diff --git a/src/LibHac/Fs/Save/SaveDataFileSystem.cs b/src/LibHac/Fs/Save/SaveDataFileSystem.cs
index 8191ccba..e71d1a0c 100644
--- a/src/LibHac/Fs/Save/SaveDataFileSystem.cs
+++ b/src/LibHac/Fs/Save/SaveDataFileSystem.cs
@@ -142,198 +142,114 @@ namespace LibHac.Fs.Save
IntegrityStorageType.Save, integrityCheckLevel, LeaveOpen);
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
- try
- {
- SaveDataFileSystemCore.CreateDirectory(path);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.CreateDirectory(path);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
- try
- {
- SaveDataFileSystemCore.CreateFile(path, size, options);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.CreateFile(path, size, options);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
- try
- {
- SaveDataFileSystemCore.DeleteDirectory(path);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.DeleteDirectory(path);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
- try
- {
- SaveDataFileSystemCore.DeleteDirectoryRecursively(path);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.DeleteDirectoryRecursively(path);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
- try
- {
- SaveDataFileSystemCore.CleanDirectoryRecursively(path);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.CleanDirectoryRecursively(path);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
- try
- {
- SaveDataFileSystemCore.DeleteFile(path);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.DeleteFile(path);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
- try
- {
- return SaveDataFileSystemCore.OpenDirectory(path, mode);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.OpenDirectory(out directory, path, mode);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
- try
- {
- return SaveDataFileSystemCore.OpenFile(path, mode);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.OpenFile(out file, path, mode);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- try
- {
- SaveDataFileSystemCore.RenameDirectory(srcPath, dstPath);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.RenameDirectory(oldPath, newPath);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public void RenameFile(string srcPath, string dstPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- try
- {
- SaveDataFileSystemCore.RenameFile(srcPath, dstPath);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.RenameFile(oldPath, newPath);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
- try
- {
- return SaveDataFileSystemCore.GetEntryType(path);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.GetEntryType(out entryType, path);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- try
- {
- return SaveDataFileSystemCore.GetFreeSpaceSize(path);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.GetFreeSpaceSize(out freeSpace, path);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- try
- {
- return SaveDataFileSystemCore.GetTotalSpaceSize(path);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = SaveDataFileSystemCore.GetTotalSpaceSize(out totalSpace, path);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public void Commit()
+ public Result Commit()
{
- try
- {
- Commit(Keyset);
- }
- catch (HorizonResultException ex)
- {
- ConvertResultException(ex);
- throw;
- }
+ Result result = Commit(Keyset);
+
+ return SaveResults.ConvertToExternalResult(result);
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ timeStamp = default;
+ return ResultFs.NotImplemented.Log();
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId) =>
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path) =>
+ ResultFs.NotImplemented.Log();
- public bool Commit(Keyset keyset)
+ public Result Commit(Keyset keyset)
{
CoreDataIvfcStorage.Flush();
FatIvfcStorage?.Flush();
@@ -349,7 +265,7 @@ namespace LibHac.Fs.Save
headerStream.Position = 0x108;
headerStream.Write(hash, 0, hash.Length);
- if (keyset == null || keyset.SaveMacKey.IsEmpty()) return false;
+ if (keyset == null || keyset.SaveMacKey.IsEmpty()) return ResultFs.PreconditionViolation;
var cmacData = new byte[0x200];
var cmac = new byte[0x10];
@@ -363,7 +279,7 @@ namespace LibHac.Fs.Save
headerStream.Write(cmac, 0, 0x10);
headerStream.Flush();
- return true;
+ return Result.Success;
}
public void FsTrim()
@@ -395,10 +311,5 @@ namespace LibHac.Fs.Save
return journalValidity;
}
-
- private void ConvertResultException(HorizonResultException ex)
- {
- ex.ResultValue = SaveResults.ConvertToExternalResult(ex.ResultValue);
- }
}
}
diff --git a/src/LibHac/Fs/Save/SaveDataFileSystemCore.cs b/src/LibHac/Fs/Save/SaveDataFileSystemCore.cs
index a1fe5c3c..721fe75b 100644
--- a/src/LibHac/Fs/Save/SaveDataFileSystemCore.cs
+++ b/src/LibHac/Fs/Save/SaveDataFileSystemCore.cs
@@ -27,14 +27,16 @@ namespace LibHac.Fs.Save
FileTable = new HierarchicalSaveFileTable(dirTableStorage, fileTableStorage);
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
path = PathTools.Normalize(path);
FileTable.AddDirectory(path);
+
+ return Result.Success;
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
path = PathTools.Normalize(path);
@@ -43,7 +45,7 @@ namespace LibHac.Fs.Save
var emptyFileEntry = new SaveFileInfo { StartBlock = int.MinValue, Length = size };
FileTable.AddFile(path, ref emptyFileEntry);
- return;
+ return Result.Success;
}
int blockCount = (int)Util.DivideByRoundUp(size, AllocationTable.Header.BlockSize);
@@ -51,45 +53,56 @@ namespace LibHac.Fs.Save
if (startBlock == -1)
{
- ThrowHelper.ThrowResult(ResultFs.AllocationTableInsufficientFreeBlocks,
- "Not enough available space to create file.");
+ return ResultFs.AllocationTableInsufficientFreeBlocks.Log();
}
var fileEntry = new SaveFileInfo { StartBlock = startBlock, Length = size };
FileTable.AddFile(path, ref fileEntry);
+
+ return Result.Success;
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
path = PathTools.Normalize(path);
FileTable.DeleteDirectory(path);
+
+ return Result.Success;
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
path = PathTools.Normalize(path);
- CleanDirectoryRecursively(path);
+ Result rc = CleanDirectoryRecursively(path);
+ if (rc.IsFailure()) return rc;
+
DeleteDirectory(path);
+
+ return Result.Success;
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
path = PathTools.Normalize(path);
- IDirectory dir = OpenDirectory(path, OpenDirectoryMode.All);
+ Result rc = OpenDirectory(out IDirectory dir, path, OpenDirectoryMode.All);
+ if (rc.IsFailure()) return rc;
+
FileSystemExtensions.CleanDirectoryRecursivelyGeneric(dir);
+
+ return Result.Success;
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
path = PathTools.Normalize(path);
if (!FileTable.TryOpenFile(path, out SaveFileInfo fileInfo))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
if (fileInfo.StartBlock != int.MinValue)
@@ -98,91 +111,110 @@ namespace LibHac.Fs.Save
}
FileTable.DeleteFile(path);
+
+ return Result.Success;
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
+ directory = default;
path = PathTools.Normalize(path);
if (!FileTable.TryOpenDirectory(path, out SaveFindPosition position))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- return new SaveDataDirectory(this, path, position, mode);
+ directory = new SaveDataDirectory(this, path, position, mode);
+
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
+ file = default;
path = PathTools.Normalize(path);
- if (!FileTable.TryOpenFile(path, out SaveFileInfo file))
+ if (!FileTable.TryOpenFile(path, out SaveFileInfo fileInfo))
{
- ThrowHelper.ThrowResult(ResultFs.PathNotFound);
+ return ResultFs.PathNotFound.Log();
}
- AllocationTableStorage storage = OpenFatStorage(file.StartBlock);
+ AllocationTableStorage storage = OpenFatStorage(fileInfo.StartBlock);
- return new SaveDataFile(storage, path, FileTable, file.Length, mode);
+ file = new SaveDataFile(storage, path, FileTable, fileInfo.Length, mode);
+
+ return Result.Success;
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
- FileTable.RenameDirectory(srcPath, dstPath);
+ return FileTable.RenameDirectory(oldPath, newPath);
}
- public void RenameFile(string srcPath, string dstPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
- FileTable.RenameFile(srcPath, dstPath);
+ FileTable.RenameFile(oldPath, newPath);
+
+ return Result.Success;
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
path = PathTools.Normalize(path);
if (FileTable.TryOpenFile(path, out SaveFileInfo _))
{
- return DirectoryEntryType.File;
+ entryType = DirectoryEntryType.File;
+ return Result.Success;
}
if (FileTable.TryOpenDirectory(path, out SaveFindPosition _))
{
- return DirectoryEntryType.Directory;
+ entryType = DirectoryEntryType.Directory;
+ return Result.Success;
}
- return DirectoryEntryType.NotFound;
+ entryType = DirectoryEntryType.NotFound;
+ return ResultFs.PathNotFound.Log();
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
int freeBlockCount = AllocationTable.GetFreeListLength();
- return Header.BlockSize * freeBlockCount;
+ freeSpace = Header.BlockSize * freeBlockCount;
+
+ return Result.Success;
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- return Header.BlockSize * Header.BlockCount;
+ totalSpace = Header.BlockSize * Header.BlockCount;
+
+ return Result.Success;
}
- public void Commit()
+ public Result Commit()
{
-
+ return Result.Success;
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
- return default;
+ timeStamp = default;
+ return ResultFs.NotImplemented.Log();
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId) =>
- ThrowHelper.ThrowResult(ResultFs.NotImplemented);
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
+ {
+ return ResultFs.NotImplemented.Log();
+ }
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
diff --git a/src/LibHac/Fs/SubdirectoryFileSystem.cs b/src/LibHac/Fs/SubdirectoryFileSystem.cs
index db5f0ab5..57f80d1a 100644
--- a/src/LibHac/Fs/SubdirectoryFileSystem.cs
+++ b/src/LibHac/Fs/SubdirectoryFileSystem.cs
@@ -18,118 +18,119 @@ namespace LibHac.Fs
RootPath = PathTools.Normalize(rootPath);
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
path = PathTools.Normalize(path);
- ParentFileSystem.CreateDirectory(ResolveFullPath(path));
+ return ParentFileSystem.CreateDirectory(ResolveFullPath(path));
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
path = PathTools.Normalize(path);
- ParentFileSystem.CreateFile(ResolveFullPath(path), size, options);
+ return ParentFileSystem.CreateFile(ResolveFullPath(path), size, options);
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
path = PathTools.Normalize(path);
- ParentFileSystem.DeleteDirectory(ResolveFullPath(path));
+ return ParentFileSystem.DeleteDirectory(ResolveFullPath(path));
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
path = PathTools.Normalize(path);
- ParentFileSystem.DeleteDirectoryRecursively(ResolveFullPath(path));
+ return ParentFileSystem.DeleteDirectoryRecursively(ResolveFullPath(path));
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
path = PathTools.Normalize(path);
- ParentFileSystem.CleanDirectoryRecursively(ResolveFullPath(path));
+ return ParentFileSystem.CleanDirectoryRecursively(ResolveFullPath(path));
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
path = PathTools.Normalize(path);
- ParentFileSystem.DeleteFile(ResolveFullPath(path));
+ return ParentFileSystem.DeleteFile(ResolveFullPath(path));
}
- public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
{
path = PathTools.Normalize(path);
- IDirectory baseDir = ParentFileSystem.OpenDirectory(ResolveFullPath(path), mode);
+ ParentFileSystem.OpenDirectory(out IDirectory baseDir, ResolveFullPath(path), mode);
- return new SubdirectoryFileSystemDirectory(this, baseDir, path, mode);
+ directory = new SubdirectoryFileSystemDirectory(this, baseDir, path, mode);
+ return Result.Success;
}
- public IFile OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out IFile file, string path, OpenMode mode)
{
path = PathTools.Normalize(path);
- return ParentFileSystem.OpenFile(ResolveFullPath(path), mode);
+ return ParentFileSystem.OpenFile(out file, ResolveFullPath(path), mode);
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
- ParentFileSystem.RenameDirectory(ResolveFullPath(srcPath), ResolveFullPath(dstPath));
+ return ParentFileSystem.RenameDirectory(oldPath, newPath);
}
- public void RenameFile(string srcPath, string dstPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- srcPath = PathTools.Normalize(srcPath);
- dstPath = PathTools.Normalize(dstPath);
+ oldPath = PathTools.Normalize(oldPath);
+ newPath = PathTools.Normalize(newPath);
- ParentFileSystem.RenameFile(ResolveFullPath(srcPath), ResolveFullPath(dstPath));
+ return ParentFileSystem.RenameFile(oldPath, newPath);
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType entryType, string path)
{
path = PathTools.Normalize(path);
- return ParentFileSystem.GetEntryType(ResolveFullPath(path));
+ return ParentFileSystem.GetEntryType(out entryType, ResolveFullPath(path));
}
- public void Commit()
+ public Result Commit()
{
- ParentFileSystem.Commit();
+ return ParentFileSystem.Commit();
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
path = PathTools.Normalize(path);
- return ParentFileSystem.GetFreeSpaceSize(ResolveFullPath(path));
+ return ParentFileSystem.GetFreeSpaceSize(out freeSpace, ResolveFullPath(path));
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
path = PathTools.Normalize(path);
- return ParentFileSystem.GetTotalSpaceSize(ResolveFullPath(path));
+ return ParentFileSystem.GetTotalSpaceSize(out totalSpace, ResolveFullPath(path));
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
path = PathTools.Normalize(path);
- return ParentFileSystem.GetFileTimeStampRaw(ResolveFullPath(path));
+ return ParentFileSystem.GetFileTimeStampRaw(out timeStamp, ResolveFullPath(path));
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId)
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path)
{
path = PathTools.Normalize(path);
- ParentFileSystem.QueryEntry(outBuffer, inBuffer, ResolveFullPath(path), queryId);
+ return ParentFileSystem.QueryEntry(outBuffer, inBuffer, queryId, ResolveFullPath(path));
}
}
}
diff --git a/src/LibHac/FsClient/Accessors/FileSystemAccessor.cs b/src/LibHac/FsClient/Accessors/FileSystemAccessor.cs
index 391f7381..317e7dd0 100644
--- a/src/LibHac/FsClient/Accessors/FileSystemAccessor.cs
+++ b/src/LibHac/FsClient/Accessors/FileSystemAccessor.cs
@@ -26,117 +26,125 @@ namespace LibHac.FsClient.Accessors
FsManager = fsManager;
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
- FileSystem.CreateDirectory(path);
+ return FileSystem.CreateDirectory(path);
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
- FileSystem.CreateFile(path, size, options);
+ return FileSystem.CreateFile(path, size, options);
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
- FileSystem.DeleteDirectory(path);
+ return FileSystem.DeleteDirectory(path);
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
- FileSystem.DeleteDirectoryRecursively(path);
+ return FileSystem.DeleteDirectoryRecursively(path);
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
- FileSystem.CleanDirectoryRecursively(path);
+ return FileSystem.CleanDirectoryRecursively(path);
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
- FileSystem.DeleteFile(path);
+ return FileSystem.DeleteFile(path);
}
- public DirectoryAccessor OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out DirectoryAccessor directory, string path, OpenDirectoryMode mode)
{
- IDirectory dir = FileSystem.OpenDirectory(path, mode);
+ directory = default;
- var accessor = new DirectoryAccessor(dir, this);
+ Result rc = FileSystem.OpenDirectory(out IDirectory rawDirectory, path, mode);
+ if (rc.IsFailure()) return rc;
+
+ var accessor = new DirectoryAccessor(rawDirectory, this);
lock (_locker)
{
OpenDirectories.Add(accessor);
}
- return accessor;
+ directory = accessor;
+ return Result.Success;
}
- public FileAccessor OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out FileAccessor file, string path, OpenMode mode)
{
- IFile file = FileSystem.OpenFile(path, mode);
+ file = default;
- var accessor = new FileAccessor(file, this, mode);
+ Result rc = FileSystem.OpenFile(out IFile rawFile, path, mode);
+ if (rc.IsFailure()) return rc;
+
+ var accessor = new FileAccessor(rawFile, this, mode);
lock (_locker)
{
OpenFiles.Add(accessor);
}
- return accessor;
+ file = accessor;
+ return Result.Success;
}
- public void RenameDirectory(string srcPath, string dstPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- FileSystem.RenameDirectory(srcPath, dstPath);
+ return FileSystem.RenameDirectory(oldPath, newPath);
}
- public void RenameFile(string srcPath, string dstPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- FileSystem.RenameFile(srcPath, dstPath);
+ return FileSystem.RenameFile(oldPath, newPath);
}
- public void DirectoryExists(string path)
+ public bool DirectoryExists(string path)
{
- FileSystem.DirectoryExists(path);
+ return FileSystem.DirectoryExists(path);
}
- public void FileExists(string path)
+ public bool FileExists(string path)
{
- FileSystem.FileExists(path);
+ return FileSystem.FileExists(path);
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType type, string path)
{
- return FileSystem.GetEntryType(path);
+ return FileSystem.GetEntryType(out type, path);
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- return FileSystem.GetFreeSpaceSize(path);
+ return FileSystem.GetFreeSpaceSize(out freeSpace, path);
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- return FileSystem.GetTotalSpaceSize(path);
+ return FileSystem.GetTotalSpaceSize(out totalSpace, path);
}
- public FileTimeStampRaw GetFileTimeStampRaw(string path)
+ public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
{
- return FileSystem.GetFileTimeStampRaw(path);
+ return FileSystem.GetFileTimeStampRaw(out timeStamp, path);
}
- public void Commit()
+ public Result Commit()
{
if (OpenFiles.Any(x => (x.OpenMode & OpenMode.Write) != 0))
{
- ThrowHelper.ThrowResult(ResultFs.WritableFileOpen);
+ return ResultFs.WritableFileOpen.Log();
}
- FileSystem.Commit();
+ return FileSystem.Commit();
}
- public void QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId)
+ public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, string path, QueryId queryId)
{
- FileSystem.QueryEntry(outBuffer, inBuffer, path, queryId);
+ return FileSystem.QueryEntry(outBuffer, inBuffer, queryId, path);
}
internal void NotifyCloseFile(FileAccessor file)
diff --git a/src/LibHac/FsClient/DirectoryHandle.cs b/src/LibHac/FsClient/DirectoryHandle.cs
index 9eb8cf2f..cab42040 100644
--- a/src/LibHac/FsClient/DirectoryHandle.cs
+++ b/src/LibHac/FsClient/DirectoryHandle.cs
@@ -12,7 +12,7 @@ namespace LibHac.FsClient
Directory = directory;
}
- public int GetId() => Directory.GetHashCode();
+ public int GetId() => Directory?.GetHashCode() ?? 0;
public void Dispose()
{
diff --git a/src/LibHac/FsClient/FileHandle.cs b/src/LibHac/FsClient/FileHandle.cs
index 387efe01..0c728291 100644
--- a/src/LibHac/FsClient/FileHandle.cs
+++ b/src/LibHac/FsClient/FileHandle.cs
@@ -12,7 +12,7 @@ namespace LibHac.FsClient
File = file;
}
- public int GetId() => File.GetHashCode();
+ public int GetId() => File?.GetHashCode() ?? 0;
public void Dispose()
{
diff --git a/src/LibHac/FsClient/FileSystemClient.FileSystem.cs b/src/LibHac/FsClient/FileSystemClient.FileSystem.cs
index f3676a12..ebd4ed12 100644
--- a/src/LibHac/FsClient/FileSystemClient.FileSystem.cs
+++ b/src/LibHac/FsClient/FileSystemClient.FileSystem.cs
@@ -55,12 +55,12 @@ namespace LibHac.FsClient
throw new NotImplementedException();
}
- public FileHandle OpenFile(out FileHandle handle, string path, OpenMode mode)
+ public Result OpenFile(out FileHandle handle, string path, OpenMode mode)
{
throw new NotImplementedException();
}
- public DirectoryHandle OpenDirectory(out DirectoryHandle handle, string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out DirectoryHandle handle, string path, OpenDirectoryMode mode)
{
throw new NotImplementedException();
}
diff --git a/src/LibHac/FsClient/FileSystemManager.cs b/src/LibHac/FsClient/FileSystemManager.cs
index 10ca268f..7b4688bf 100644
--- a/src/LibHac/FsClient/FileSystemManager.cs
+++ b/src/LibHac/FsClient/FileSystemManager.cs
@@ -6,6 +6,7 @@ using LibHac.FsClient.Accessors;
namespace LibHac.FsClient
{
+ // Todo: Access log for FindFileSystem
public class FileSystemManager
{
internal Horizon Os { get; }
@@ -66,213 +67,229 @@ namespace LibHac.FsClient
if (accessLog != null) AccessLog = accessLog;
}
- public void CreateDirectory(string path)
+ public Result CreateDirectory(string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- fileSystem.CreateDirectory(subPath.ToString());
+ rc = fileSystem.CreateDirectory(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{path}\"");
}
else
{
- fileSystem.CreateDirectory(subPath.ToString());
+ rc = fileSystem.CreateDirectory(subPath.ToString());
}
+
+ return rc;
}
- public void CreateFile(string path, long size)
+ public Result CreateFile(string path, long size)
{
- CreateFile(path, size, CreateFileOptions.None);
+ return CreateFile(path, size, CreateFileOptions.None);
}
- public void CreateFile(string path, long size, CreateFileOptions options)
+ public Result CreateFile(string path, long size, CreateFileOptions options)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- fileSystem.CreateFile(subPath.ToString(), size, options);
+ rc = fileSystem.CreateFile(subPath.ToString(), size, options);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{path}\", size: {size}");
}
else
{
- fileSystem.CreateFile(subPath.ToString(), size, options);
+ rc = fileSystem.CreateFile(subPath.ToString(), size, options);
}
+
+ return rc;
}
- public void DeleteDirectory(string path)
+ public Result DeleteDirectory(string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- fileSystem.DeleteDirectory(subPath.ToString());
+ rc = fileSystem.DeleteDirectory(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{path}\"");
}
else
{
- fileSystem.DeleteDirectory(subPath.ToString());
+ rc = fileSystem.DeleteDirectory(subPath.ToString());
}
+
+ return rc;
}
- public void DeleteDirectoryRecursively(string path)
+ public Result DeleteDirectoryRecursively(string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- fileSystem.DeleteDirectoryRecursively(subPath.ToString());
+ rc = fileSystem.DeleteDirectoryRecursively(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{path}\"");
}
else
{
- fileSystem.DeleteDirectoryRecursively(subPath.ToString());
+ rc = fileSystem.DeleteDirectoryRecursively(subPath.ToString());
}
+
+ return rc;
}
- public void CleanDirectoryRecursively(string path)
+ public Result CleanDirectoryRecursively(string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- fileSystem.CleanDirectoryRecursively(subPath.ToString());
+ rc = fileSystem.CleanDirectoryRecursively(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{path}\"");
}
else
{
- fileSystem.CleanDirectoryRecursively(subPath.ToString());
+ rc = fileSystem.CleanDirectoryRecursively(subPath.ToString());
}
+
+ return rc;
}
- public void DeleteFile(string path)
+ public Result DeleteFile(string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- fileSystem.DeleteFile(subPath.ToString());
+ rc = fileSystem.DeleteFile(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{path}\"");
}
else
{
- fileSystem.DeleteFile(subPath.ToString());
+ rc = fileSystem.DeleteFile(subPath.ToString());
}
+
+ return rc;
}
- public void RenameDirectory(string oldPath, string newPath)
+ public Result RenameDirectory(string oldPath, string newPath)
{
- FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan oldSubPath)
- .ThrowIfFailure();
+ Result rc = FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan oldSubPath);
+ if (rc.IsFailure()) return rc;
- FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan newSubPath)
- .ThrowIfFailure();
+ rc = FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan newSubPath);
+ if (rc.IsFailure()) return rc;
if (oldFileSystem != newFileSystem)
{
- ThrowHelper.ThrowResult(ResultFs.DifferentDestFileSystem);
+ return ResultFs.DifferentDestFileSystem.Log();
}
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString());
+ rc = oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{oldPath}\", new_path: \"{newPath}\"");
}
else
{
- oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString());
+ rc = oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString());
}
+
+ return rc;
}
- public void RenameFile(string oldPath, string newPath)
+ public Result RenameFile(string oldPath, string newPath)
{
- FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan oldSubPath)
- .ThrowIfFailure();
+ Result rc = FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan oldSubPath);
+ if (rc.IsFailure()) return rc;
- FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan newSubPath)
- .ThrowIfFailure();
+ rc = FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan newSubPath);
+ if (rc.IsFailure()) return rc;
if (oldFileSystem != newFileSystem)
{
- ThrowHelper.ThrowResult(ResultFs.DifferentDestFileSystem);
+ return ResultFs.DifferentDestFileSystem.Log();
}
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString());
+ rc = oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{oldPath}\", new_path: \"{newPath}\"");
}
else
{
- oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString());
+ rc = oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString());
}
+
+ return rc;
}
- public DirectoryEntryType GetEntryType(string path)
+ public Result GetEntryType(out DirectoryEntryType type, string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ type = default;
- DirectoryEntryType type;
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- type = fileSystem.GetEntryType(subPath.ToString());
+ rc = fileSystem.GetEntryType(out type, subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", path: \"{path}\"");
}
else
{
- type = fileSystem.GetEntryType(subPath.ToString());
+ rc = fileSystem.GetEntryType(out type, subPath.ToString());
}
- return type;
+ return rc;
}
- public FileHandle OpenFile(string path, OpenMode mode)
+ public Result OpenFile(out FileHandle handle, string path, OpenMode mode)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ handle = default;
- FileHandle handle;
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- FileAccessor file = fileSystem.OpenFile(subPath.ToString(), mode);
+ rc = fileSystem.OpenFile(out FileAccessor file, subPath.ToString(), mode);
handle = new FileHandle(file);
TimeSpan endTime = Time.GetCurrent();
@@ -280,24 +297,24 @@ namespace LibHac.FsClient
}
else
{
- FileAccessor file = fileSystem.OpenFile(subPath.ToString(), mode);
+ rc = fileSystem.OpenFile(out FileAccessor file, subPath.ToString(), mode);
handle = new FileHandle(file);
}
- return handle;
+ return rc;
}
- public DirectoryHandle OpenDirectory(string path, OpenDirectoryMode mode)
+ public Result OpenDirectory(out DirectoryHandle handle, string path, OpenDirectoryMode mode)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ handle = default;
- DirectoryHandle handle;
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- DirectoryAccessor dir = fileSystem.OpenDirectory(subPath.ToString(), mode);
+ rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath.ToString(), mode);
handle = new DirectoryHandle(dir);
TimeSpan endTime = Time.GetCurrent();
@@ -305,94 +322,105 @@ namespace LibHac.FsClient
}
else
{
- DirectoryAccessor dir = fileSystem.OpenDirectory(subPath.ToString(), mode);
+ rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath.ToString(), mode);
handle = new DirectoryHandle(dir);
}
- return handle;
+ return rc;
}
- public long GetFreeSpaceSize(string path)
+ public Result GetFreeSpaceSize(out long freeSpace, string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ freeSpace = default;
- return fileSystem.GetFreeSpaceSize(subPath.ToString());
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
+
+ return fileSystem.GetFreeSpaceSize(out freeSpace, subPath.ToString());
}
- public long GetTotalSpaceSize(string path)
+ public Result GetTotalSpaceSize(out long totalSpace, string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ totalSpace = default;
- return fileSystem.GetTotalSpaceSize(subPath.ToString());
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
+
+ return fileSystem.GetTotalSpaceSize(out totalSpace, subPath.ToString());
}
- public FileTimeStampRaw GetFileTimeStamp(string path)
+ public Result GetFileTimeStamp(out FileTimeStampRaw timeStamp, string path)
{
- FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath)
- .ThrowIfFailure();
+ timeStamp = default;
- return fileSystem.GetFileTimeStampRaw(subPath.ToString());
+ Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath);
+ if (rc.IsFailure()) return rc;
+
+ return fileSystem.GetFileTimeStampRaw(out timeStamp, subPath.ToString());
}
- public void Commit(string mountName)
+ public Result Commit(string mountName)
{
- MountTable.Find(mountName, out FileSystemAccessor fileSystem).ThrowIfFailure();
+ Result rc = MountTable.Find(mountName, out FileSystemAccessor fileSystem);
+ if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
- fileSystem.Commit();
+ rc = fileSystem.Commit();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, $", name: \"{mountName}\"");
}
else
{
- fileSystem.Commit();
+ rc = fileSystem.Commit();
}
+
+ return rc;
}
// ==========================
// Operations on file handles
// ==========================
- public int ReadFile(FileHandle handle, Span destination, long offset)
+ public Result ReadFile(out long bytesRead, FileHandle handle, Span destination, long offset)
{
- return ReadFile(handle, destination, offset, ReadOption.None);
+ return ReadFile(out bytesRead, handle, destination, offset, ReadOption.None);
}
- public int ReadFile(FileHandle handle, Span destination, long offset, ReadOption option)
+ public Result ReadFile(out long bytesRead, FileHandle handle, Span destination, long offset, ReadOption option)
{
- long bytesRead;
+ Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
- handle.File.Read(out bytesRead, offset, destination, option).ThrowIfFailure();
+ rc = handle.File.Read(out bytesRead, offset, destination, option);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, handle, $", offset: {offset}, size: {destination.Length}");
}
else
{
- handle.File.Read(out bytesRead, offset, destination, option).ThrowIfFailure();
+ rc = handle.File.Read(out bytesRead, offset, destination, option);
}
- return (int)bytesRead;
+ return rc;
}
- public void WriteFile(FileHandle handle, ReadOnlySpan source, long offset)
+ public Result WriteFile(FileHandle handle, ReadOnlySpan source, long offset)
{
- WriteFile(handle, source, offset, WriteOption.None);
+ return WriteFile(handle, source, offset, WriteOption.None);
}
- public void WriteFile(FileHandle handle, ReadOnlySpan source, long offset, WriteOption option)
+ public Result WriteFile(FileHandle handle, ReadOnlySpan source, long offset, WriteOption option)
{
+ Result rc;
+
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
- handle.File.Write(offset, source, option);
+ rc = handle.File.Write(offset, source, option);
TimeSpan endTime = Time.GetCurrent();
string optionString = (option & WriteOption.Flush) == 0 ? "" : $", write_option: {option}";
@@ -401,47 +429,55 @@ namespace LibHac.FsClient
}
else
{
- handle.File.Write(offset, source, option);
+ rc = handle.File.Write(offset, source, option);
}
+
+ return rc;
}
- public void FlushFile(FileHandle handle)
+ public Result FlushFile(FileHandle handle)
{
+ Result rc;
+
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
- handle.File.Flush();
+ rc = handle.File.Flush();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, handle, string.Empty);
}
else
{
- handle.File.Flush();
+ rc = handle.File.Flush();
}
+
+ return rc;
}
- public long GetFileSize(FileHandle handle)
+ public Result GetFileSize(out long fileSize, FileHandle handle)
{
- handle.File.GetSize(out long fileSize).ThrowIfFailure();
-
- return fileSize;
+ return handle.File.GetSize(out fileSize);
}
- public void SetFileSize(FileHandle handle, long size)
+ public Result SetFileSize(FileHandle handle, long size)
{
+ Result rc;
+
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
- handle.File.SetSize(size);
+ rc = handle.File.SetSize(size);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(startTime, endTime, handle, $", size: {size}");
}
else
{
- handle.File.SetSize(size);
+ rc = handle.File.SetSize(size);
}
+
+ return rc;
}
public OpenMode GetFileOpenMode(FileHandle handle)
@@ -468,9 +504,11 @@ namespace LibHac.FsClient
// ==========================
// Operations on directory handles
// ==========================
- public int GetDirectoryEntryCount(DirectoryHandle handle)
+ public Result GetDirectoryEntryCount(out long count, DirectoryHandle handle)
{
- return handle.Directory.GetEntryCount();
+ count = handle.Directory.GetEntryCount();
+
+ return Result.Success;
}
public IEnumerable ReadDirectory(DirectoryHandle handle)
diff --git a/src/LibHac/FsClient/FileSystemManagerUtils.cs b/src/LibHac/FsClient/FileSystemManagerUtils.cs
index bce4b6e4..60d3244c 100644
--- a/src/LibHac/FsClient/FileSystemManagerUtils.cs
+++ b/src/LibHac/FsClient/FileSystemManagerUtils.cs
@@ -7,10 +7,13 @@ namespace LibHac.FsClient
{
public static class FileSystemManagerUtils
{
- public static void CopyDirectory(this FileSystemManager fs, string sourcePath, string destPath,
+ public static Result CopyDirectory(this FileSystemManager fs, string sourcePath, string destPath,
CreateFileOptions options = CreateFileOptions.None, IProgressReport logger = null)
{
- using (DirectoryHandle sourceHandle = fs.OpenDirectory(sourcePath, OpenDirectoryMode.All))
+ Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath, OpenDirectoryMode.All);
+ if (rc.IsFailure()) return rc;
+
+ using (sourceHandle)
{
foreach (DirectoryEntry entry in fs.ReadDirectory(sourceHandle))
{
@@ -21,7 +24,8 @@ namespace LibHac.FsClient
{
fs.EnsureDirectoryExists(subDstPath);
- fs.CopyDirectory(subSrcPath, subDstPath, options, logger);
+ rc = fs.CopyDirectory(subSrcPath, subDstPath, options, logger);
+ if (rc.IsFailure()) return rc;
}
if (entry.Type == DirectoryEntryType.File)
@@ -29,46 +33,65 @@ namespace LibHac.FsClient
logger?.LogMessage(subSrcPath);
fs.CreateOrOverwriteFile(subDstPath, entry.Size, options);
- fs.CopyFile(subSrcPath, subDstPath, logger);
+ rc = fs.CopyFile(subSrcPath, subDstPath, logger);
+ if (rc.IsFailure()) return rc;
}
}
}
+
+ return Result.Success;
}
- public static void CopyFile(this FileSystemManager fs, string sourcePath, string destPath, IProgressReport logger = null)
+ public static Result CopyFile(this FileSystemManager fs, string sourcePath, string destPath, IProgressReport logger = null)
{
- using (FileHandle sourceHandle = fs.OpenFile(sourcePath, OpenMode.Read))
- using (FileHandle destHandle = fs.OpenFile(destPath, OpenMode.Write | OpenMode.AllowAppend))
+ Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath, OpenMode.Read);
+ if (rc.IsFailure()) return rc;
+
+ using (sourceHandle)
{
- const int maxBufferSize = 0x10000;
+ rc = fs.OpenFile(out FileHandle destHandle, destPath, OpenMode.Write | OpenMode.AllowAppend);
+ if (rc.IsFailure()) return rc;
- long fileSize = fs.GetFileSize(sourceHandle);
- int bufferSize = (int)Math.Min(maxBufferSize, fileSize);
-
- logger?.SetTotal(fileSize);
-
- byte[] buffer = ArrayPool.Shared.Rent(bufferSize);
- try
+ using (destHandle)
{
- for (long offset = 0; offset < fileSize; offset += bufferSize)
+ const int maxBufferSize = 0x10000;
+
+ rc = fs.GetFileSize(out long fileSize, sourceHandle);
+ if (rc.IsFailure()) return rc;
+
+ int bufferSize = (int)Math.Min(maxBufferSize, fileSize);
+
+ logger?.SetTotal(fileSize);
+
+ byte[] buffer = ArrayPool.Shared.Rent(bufferSize);
+ try
{
- int toRead = (int)Math.Min(fileSize - offset, bufferSize);
- Span buf = buffer.AsSpan(0, toRead);
+ for (long offset = 0; offset < fileSize; offset += bufferSize)
+ {
+ int toRead = (int)Math.Min(fileSize - offset, bufferSize);
+ Span buf = buffer.AsSpan(0, toRead);
- fs.ReadFile(sourceHandle, buf, offset);
- fs.WriteFile(destHandle, buf, offset);
+ rc = fs.ReadFile(out long _, sourceHandle, buf, offset);
+ if (rc.IsFailure()) return rc;
- logger?.ReportAdd(toRead);
+ rc = fs.WriteFile(destHandle, buf, offset);
+ if (rc.IsFailure()) return rc;
+
+ logger?.ReportAdd(toRead);
+ }
+ }
+ finally
+ {
+ ArrayPool.Shared.Return(buffer);
+ logger?.SetTotal(0);
}
- }
- finally
- {
- ArrayPool.Shared.Return(buffer);
- logger?.SetTotal(0);
- }
- fs.FlushFile(destHandle);
+ rc = fs.FlushFile(destHandle);
+ if (rc.IsFailure()) return rc;
+ }
}
+
+ return Result.Success;
}
public static IEnumerable EnumerateEntries(this FileSystemManager fs, string path)
@@ -86,7 +109,9 @@ namespace LibHac.FsClient
bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive);
bool recurse = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories);
- using (DirectoryHandle sourceHandle = fs.OpenDirectory(path, OpenDirectoryMode.All))
+ fs.OpenDirectory(out DirectoryHandle sourceHandle, path, OpenDirectoryMode.All).ThrowIfFailure();
+
+ using (sourceHandle)
{
foreach (DirectoryEntry entry in fs.ReadDirectory(sourceHandle))
{
@@ -112,12 +137,16 @@ namespace LibHac.FsClient
public static bool DirectoryExists(this FileSystemManager fs, string path)
{
- return fs.GetEntryType(path) == DirectoryEntryType.Directory;
+ Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
+
+ return (rc.IsSuccess() && type == DirectoryEntryType.Directory);
}
public static bool FileExists(this FileSystemManager fs, string path)
{
- return fs.GetEntryType(path) == DirectoryEntryType.File;
+ Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
+
+ return (rc.IsSuccess() && type == DirectoryEntryType.File);
}
public static void EnsureDirectoryExists(this FileSystemManager fs, string path)
diff --git a/src/LibHac/FsService/Creators/IHostFileSystemCreator.cs b/src/LibHac/FsService/Creators/IHostFileSystemCreator.cs
index f00dde73..d7c50ff5 100644
--- a/src/LibHac/FsService/Creators/IHostFileSystemCreator.cs
+++ b/src/LibHac/FsService/Creators/IHostFileSystemCreator.cs
@@ -5,6 +5,6 @@ namespace LibHac.FsService.Creators
public interface IHostFileSystemCreator
{
Result Create(out IFileSystem fileSystem, bool someBool);
- Result Create(out IFileSystem fileSystem, string path, bool someBool);
+ Result Create(out IFileSystem fileSystem, string path, bool openCaseSensitive);
}
}
\ No newline at end of file
diff --git a/src/LibHac/FsService/Creators/ITargetManagerFileSystemCreator.cs b/src/LibHac/FsService/Creators/ITargetManagerFileSystemCreator.cs
index 7de7c485..e0858de4 100644
--- a/src/LibHac/FsService/Creators/ITargetManagerFileSystemCreator.cs
+++ b/src/LibHac/FsService/Creators/ITargetManagerFileSystemCreator.cs
@@ -4,7 +4,7 @@ namespace LibHac.FsService.Creators
{
public interface ITargetManagerFileSystemCreator
{
- Result Create(out IFileSystem fileSystem, bool someBool);
+ Result Create(out IFileSystem fileSystem, bool openCaseSensitive);
Result GetCaseSensitivePath(out bool isSuccess, ref string path);
}
}
\ No newline at end of file
diff --git a/src/LibHac/FsService/Creators/SubDirectoryFileSystemCreator.cs b/src/LibHac/FsService/Creators/SubDirectoryFileSystemCreator.cs
index 5f19cdc4..ad2ecf8b 100644
--- a/src/LibHac/FsService/Creators/SubDirectoryFileSystemCreator.cs
+++ b/src/LibHac/FsService/Creators/SubDirectoryFileSystemCreator.cs
@@ -6,16 +6,10 @@ namespace LibHac.FsService.Creators
{
public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, string path)
{
- try
- {
- baseFileSystem.OpenDirectory(path, OpenDirectoryMode.Directory);
- }
- catch (HorizonResultException ex)
- {
- subDirFileSystem = default;
+ subDirFileSystem = default;
- return ex.ResultValue;
- }
+ Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);
+ if (rc.IsFailure()) return rc;
subDirFileSystem = new SubdirectoryFileSystem(baseFileSystem, path);
diff --git a/src/LibHac/FsService/Util.cs b/src/LibHac/FsService/Util.cs
index 0a0b8a62..8ac791bd 100644
--- a/src/LibHac/FsService/Util.cs
+++ b/src/LibHac/FsService/Util.cs
@@ -11,11 +11,13 @@ namespace LibHac.FsService
if (!createPathIfMissing)
{
- if (path == null) return ResultFs.NullArgument;
+ if (path == null) return ResultFs.NullArgument.Log();
- if (baseFileSystem.GetEntryType(path) != DirectoryEntryType.Directory)
+ Result rc = baseFileSystem.GetEntryType(out DirectoryEntryType entryType, path);
+
+ if (rc.IsFailure() || entryType != DirectoryEntryType.Directory)
{
- return ResultFs.PathNotFound;
+ return ResultFs.PathNotFound.Log();
}
}
@@ -28,16 +30,10 @@ namespace LibHac.FsService
{
subFileSystem = default;
- if (path == null) return ResultFs.NullArgument;
+ if (path == null) return ResultFs.NullArgument.Log();
- try
- {
- baseFileSystem.OpenDirectory(path, OpenDirectoryMode.Directory);
- }
- catch (HorizonResultException ex)
- {
- return ex.ResultValue;
- }
+ Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);
+ if (rc.IsFailure()) return rc;
subFileSystem = new SubdirectoryFileSystem(baseFileSystem, path);
diff --git a/src/LibHac/SwitchFs.cs b/src/LibHac/SwitchFs.cs
index 98b42155..2f91685c 100644
--- a/src/LibHac/SwitchFs.cs
+++ b/src/LibHac/SwitchFs.cs
@@ -67,9 +67,10 @@ namespace LibHac
private void OpenAllNcas()
{
+ ContentFs.OpenDirectory(out IDirectory rootDir, "/", OpenDirectoryMode.All).ThrowIfFailure();
+
// Todo: give warning if directories named "*.nca" are found or manually fix the archive bit
- IEnumerable files = ContentFs.OpenDirectory("/", OpenDirectoryMode.All)
- .EnumerateEntries("*.nca", SearchOptions.RecurseSubdirectories)
+ IEnumerable files = rootDir.EnumerateEntries("*.nca", SearchOptions.RecurseSubdirectories)
.Where(x => x.Type == DirectoryEntryType.File);
foreach (DirectoryEntry fileEntry in files)
@@ -77,9 +78,9 @@ namespace LibHac
SwitchFsNca nca = null;
try
{
- IStorage storage = ContentFs.OpenFile(fileEntry.FullPath, OpenMode.Read).AsStorage();
+ ContentFs.OpenFile(out IFile ncaFile, fileEntry.FullPath, OpenMode.Read).ThrowIfFailure();
- nca = new SwitchFsNca(new Nca(Keyset, storage));
+ nca = new SwitchFsNca(new Nca(Keyset, ncaFile.AsStorage()));
nca.NcaId = GetNcaFilename(fileEntry.Name, nca);
string extension = nca.Nca.Header.ContentType == NcaContentType.Meta ? ".cnmt.nca" : ".nca";
@@ -115,7 +116,8 @@ namespace LibHac
try
{
- IFile file = SaveFs.OpenFile(fileEntry.FullPath, OpenMode.Read);
+ SaveFs.OpenFile(out IFile file, fileEntry.FullPath, OpenMode.Read).ThrowIfFailure();
+
save = new SaveDataFileSystem(Keyset, file.AsStorage(), IntegrityCheckLevel.None, true);
}
catch (Exception ex)
@@ -141,7 +143,7 @@ namespace LibHac
IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
string cnmtPath = fs.EnumerateEntries("*.cnmt").Single().FullPath;
- IFile file = fs.OpenFile(cnmtPath, OpenMode.Read);
+ fs.OpenFile(out IFile file, cnmtPath, OpenMode.Read).ThrowIfFailure();
var metadata = new Cnmt(file.AsStream());
title.Id = metadata.TitleId;
@@ -185,7 +187,7 @@ namespace LibHac
foreach (Title title in Titles.Values.Where(x => x.ControlNca != null))
{
IFileSystem romfs = title.ControlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
- IFile control = romfs.OpenFile("control.nacp", OpenMode.Read);
+ romfs.OpenFile(out IFile control, "control.nacp", OpenMode.Read).ThrowIfFailure();
title.Control = new Nacp(control.AsStream());
diff --git a/src/LibHac/Xci.cs b/src/LibHac/Xci.cs
index 3587f12f..9fe8c7f1 100644
--- a/src/LibHac/Xci.cs
+++ b/src/LibHac/Xci.cs
@@ -28,8 +28,8 @@ namespace LibHac
XciPartition root = GetRootPartition();
if (type == XciPartitionType.Root) return root;
- IStorage partitionStorage = root.OpenFile(type.GetFileName(), OpenMode.Read).AsStorage();
- return new XciPartition(partitionStorage);
+ root.OpenFile(out IFile partitionFile, type.GetFileName(), OpenMode.Read).ThrowIfFailure();
+ return new XciPartition(partitionFile.AsStorage());
}
private XciPartition GetRootPartition()
diff --git a/src/hactoolnet/FsUtils.cs b/src/hactoolnet/FsUtils.cs
index 0f41f501..0e3d2c1b 100644
--- a/src/hactoolnet/FsUtils.cs
+++ b/src/hactoolnet/FsUtils.cs
@@ -26,7 +26,9 @@ namespace hactoolnet
private static void CopyDirectoryWithProgressInternal(FileSystemManager fs, string sourcePath, string destPath,
CreateFileOptions options, IProgressReport logger)
{
- using (DirectoryHandle sourceHandle = fs.OpenDirectory(sourcePath, OpenDirectoryMode.All))
+ fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath, OpenDirectoryMode.All).ThrowIfFailure();
+
+ using (sourceHandle)
{
foreach (DirectoryEntry entry in fs.ReadDirectory(sourceHandle))
{
@@ -63,37 +65,53 @@ namespace hactoolnet
return size;
}
- public static void CopyFileWithProgress(FileSystemManager fs, string sourcePath, string destPath, IProgressReport logger = null)
+ public static Result CopyFileWithProgress(FileSystemManager fs, string sourcePath, string destPath, IProgressReport logger = null)
{
- using (FileHandle sourceHandle = fs.OpenFile(sourcePath, OpenMode.Read))
- using (FileHandle destHandle = fs.OpenFile(destPath, OpenMode.Write | OpenMode.AllowAppend))
+ Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath, OpenMode.Read);
+ if (rc.IsFailure()) return rc;
+
+ using (sourceHandle)
{
- const int maxBufferSize = 1024 * 1024;
+ rc = fs.OpenFile(out FileHandle destHandle, destPath, OpenMode.Write | OpenMode.AllowAppend);
+ if (rc.IsFailure()) return rc;
- long fileSize = fs.GetFileSize(sourceHandle);
- int bufferSize = (int)Math.Min(maxBufferSize, fileSize);
-
- byte[] buffer = ArrayPool.Shared.Rent(bufferSize);
- try
+ using (destHandle)
{
- for (long offset = 0; offset < fileSize; offset += bufferSize)
+ const int maxBufferSize = 1024 * 1024;
+
+ rc = fs.GetFileSize(out long fileSize, sourceHandle);
+ if (rc.IsFailure()) return rc;
+
+ int bufferSize = (int)Math.Min(maxBufferSize, fileSize);
+
+ byte[] buffer = ArrayPool.Shared.Rent(bufferSize);
+ try
{
- int toRead = (int)Math.Min(fileSize - offset, bufferSize);
- Span buf = buffer.AsSpan(0, toRead);
+ for (long offset = 0; offset < fileSize; offset += bufferSize)
+ {
+ int toRead = (int)Math.Min(fileSize - offset, bufferSize);
+ Span buf = buffer.AsSpan(0, toRead);
- fs.ReadFile(sourceHandle, buf, offset);
- fs.WriteFile(destHandle, buf, offset);
+ rc = fs.ReadFile(out long _, sourceHandle, buf, offset);
+ if (rc.IsFailure()) return rc;
- logger?.ReportAdd(toRead);
+ rc = fs.WriteFile(destHandle, buf, offset);
+ if (rc.IsFailure()) return rc;
+
+ logger?.ReportAdd(toRead);
+ }
+ }
+ finally
+ {
+ ArrayPool.Shared.Return(buffer);
}
- }
- finally
- {
- ArrayPool.Shared.Return(buffer);
- }
- fs.FlushFile(destHandle);
+ rc = fs.FlushFile(destHandle);
+ if (rc.IsFailure()) return rc;
+ }
}
+
+ return Result.Success;
}
}
}
diff --git a/src/hactoolnet/ProcessDelta.cs b/src/hactoolnet/ProcessDelta.cs
index d8c1c4b7..b03dde02 100644
--- a/src/hactoolnet/ProcessDelta.cs
+++ b/src/hactoolnet/ProcessDelta.cs
@@ -33,7 +33,9 @@ namespace hactoolnet
throw new FileNotFoundException("Specified NCA does not contain a delta fragment");
}
- deltaStorage = fs.OpenFile(FragmentFileName, OpenMode.Read).AsStorage();
+ fs.OpenFile(out IFile deltaFragmentFile, FragmentFileName, OpenMode.Read).ThrowIfFailure();
+
+ deltaStorage = deltaFragmentFile.AsStorage();
}
catch (InvalidDataException) { } // Ignore non-NCA3 files
}
diff --git a/src/hactoolnet/ProcessNca.cs b/src/hactoolnet/ProcessNca.cs
index da1caf58..5b301917 100644
--- a/src/hactoolnet/ProcessNca.cs
+++ b/src/hactoolnet/ProcessNca.cs
@@ -210,8 +210,8 @@ namespace hactoolnet
IFileSystem pfs = nca.OpenFileSystem(NcaSectionType.Code, IntegrityCheckLevel.ErrorOnInvalid);
if (!pfs.FileExists("main.npdm")) return Validity.Unchecked;
- IFile npdmStorage = pfs.OpenFile("main.npdm", OpenMode.Read);
- var npdm = new NpdmBinary(npdmStorage.AsStream());
+ pfs.OpenFile(out IFile npdmFile, "main.npdm", OpenMode.Read).ThrowIfFailure();
+ var npdm = new NpdmBinary(npdmFile.AsStream());
return nca.Header.VerifySignature2(npdm.AciD.Rsa2048Modulus);
}
diff --git a/src/hactoolnet/ProcessSave.cs b/src/hactoolnet/ProcessSave.cs
index 6be16758..e95f8340 100644
--- a/src/hactoolnet/ProcessSave.cs
+++ b/src/hactoolnet/ProcessSave.cs
@@ -62,7 +62,9 @@ namespace hactoolnet
using (IFile inFile = new LocalFile(ctx.Options.ReplaceFileSource, OpenMode.Read))
{
- using (IFile outFile = save.OpenFile(destFilename, OpenMode.ReadWrite))
+ save.OpenFile(out IFile outFile, destFilename, OpenMode.ReadWrite).ThrowIfFailure();
+
+ using (outFile)
{
inFile.GetSize(out long inFileSize).ThrowIfFailure();
outFile.GetSize(out long outFileSize).ThrowIfFailure();
@@ -100,7 +102,7 @@ namespace hactoolnet
{
if (signNeeded)
{
- save.Commit(ctx.Keyset);
+ save.Commit(ctx.Keyset).ThrowIfFailure();
signNeeded = false;
}
}
@@ -114,7 +116,7 @@ namespace hactoolnet
if (signNeeded)
{
- if (save.Commit(ctx.Keyset))
+ if (save.Commit(ctx.Keyset).IsSuccess())
{
ctx.Logger.LogMessage("Successfully signed save file");
}
@@ -310,7 +312,7 @@ namespace hactoolnet
var sb = new StringBuilder();
sb.AppendLine();
- long freeSpace = save.GetFreeSpaceSize("");
+ save.GetFreeSpaceSize(out long freeSpace, "").ThrowIfFailure();
sb.AppendLine("Savefile:");
PrintItem(sb, colLen, $"CMAC Signature{save.Header.SignatureValidity.GetValidityString()}:", save.Header.Cmac);