Use more result codes in FS code

This commit is contained in:
Alex Barney 2019-06-28 19:41:09 -05:00
parent 46d4274686
commit 8f37b2b1c4
30 changed files with 325 additions and 140 deletions

View file

@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using static LibHac.Fs.ResultsFs;
namespace LibHac.Fs.Accessors
{
public class FileSystemAccessor
@ -129,7 +127,7 @@ namespace LibHac.Fs.Accessors
{
if (OpenFiles.Any(x => (x.OpenMode & OpenMode.Write) != 0))
{
ThrowHelper.ThrowResult(ResultFsWritableFileOpen);
ThrowHelper.ThrowResult(ResultFs.WritableFileOpen);
}
FileSystem.Commit();

View file

@ -1,7 +1,6 @@
using System.Collections.Generic;
using static LibHac.Results;
using static LibHac.Fs.ResultsFs;
namespace LibHac.Fs.Accessors
{
@ -19,7 +18,7 @@ namespace LibHac.Fs.Accessors
if (Table.ContainsKey(mountName))
{
return ResultFsMountNameAlreadyExists;
return ResultFs.MountNameAlreadyExists;
}
Table.Add(mountName, fileSystem);
@ -34,7 +33,7 @@ namespace LibHac.Fs.Accessors
{
if (!Table.TryGetValue(name, out fileSystem))
{
return ResultFsMountNameNotFound;
return ResultFs.MountNameNotFound;
}
return ResultSuccess;
@ -47,7 +46,7 @@ namespace LibHac.Fs.Accessors
{
if (!Table.TryGetValue(name, out FileSystemAccessor fsAccessor))
{
return ResultFsMountNameNotFound;
return ResultFs.MountNameNotFound;
}
Table.Remove(name);

View file

@ -28,7 +28,12 @@ namespace LibHac.Fs
if (!Header.TryDecryptHeader(Path, KekSeed, VerificationKey))
{
throw new ArgumentException("NAX0 key derivation failed.");
ThrowHelper.ThrowResult(ResultFs.AesXtsFileHeaderInvalidKeys, "NAX0 key derivation failed.");
}
if (HeaderLength + Util.AlignUp(Header.Size, 0x10) > baseFile.GetSize())
{
ThrowHelper.ThrowResult(ResultFs.AesXtsFileTooShort, "NAX0 key derivation failed.");
}
IStorage encStorage = BaseFile.AsStorage().Slice(HeaderLength, Util.AlignUp(Header.Size, 0x10));

View file

@ -1,5 +1,4 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
@ -22,6 +21,11 @@ namespace LibHac.Fs
public AesXtsFileHeader(IFile aesXtsFile)
{
if (aesXtsFile.GetSize() < 0x80)
{
ThrowHelper.ThrowResult(ResultFs.AesXtsFileHeaderTooShort);
}
var reader = new FileReader(aesXtsFile);
reader.ReadBytes(Signature);
@ -33,7 +37,7 @@ namespace LibHac.Fs
if (Magic != AesXtsFileMagic)
{
throw new InvalidDataException("Invalid NAX0 magic value");
ThrowHelper.ThrowResult(ResultFs.AesXtsFileHeaderInvalidMagic, "Invalid NAX0 magic value");
}
}

View file

@ -1,6 +1,5 @@
using System;
using System.Diagnostics;
using System.IO;
namespace LibHac.Fs
{
@ -218,7 +217,7 @@ namespace LibHac.Fs
{
if (!TryReadXtsHeader(filePath, keyPath, out AesXtsFileHeader header))
{
throw new InvalidDataException("Could not decrypt AES-XTS keys");
ThrowHelper.ThrowResult(ResultFs.AesXtsFileHeaderInvalidKeysInRenameFile, "Could not decrypt AES-XTS keys");
}
return header;

View file

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace LibHac.Fs
{
@ -38,10 +37,12 @@ namespace LibHac.Fs
public void CreateDirectory(string path)
{
path = PathTools.Normalize(path);
string parent = PathTools.GetParentDirectory(path);
if (FileExists(path))
if (IsConcatenationFile(parent))
{
throw new IOException("Cannot create directory because a file with this name already exists.");
ThrowHelper.ThrowResult(ResultFs.PathNotFound,
"Cannot create a directory inside of a concatenation file");
}
BaseFileSystem.CreateDirectory(path);
@ -61,7 +62,12 @@ namespace LibHac.Fs
// A concatenation file directory can't contain normal files
string parentDir = PathTools.GetParentDirectory(path);
if (IsConcatenationFile(parentDir)) throw new IOException("Cannot create files inside of a concatenation file");
if (IsConcatenationFile(parentDir))
{
ThrowHelper.ThrowResult(ResultFs.PathNotFound,
"Cannot create a concatenation file inside of a concatenation file");
}
BaseFileSystem.CreateDirectory(path);
SetConcatenationFileAttribute(path);
@ -85,7 +91,7 @@ namespace LibHac.Fs
if (IsConcatenationFile(path))
{
throw new DirectoryNotFoundException(path);
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
BaseFileSystem.DeleteDirectory(path);
@ -95,7 +101,7 @@ namespace LibHac.Fs
{
path = PathTools.Normalize(path);
if (IsConcatenationFile(path)) throw new DirectoryNotFoundException();
if (IsConcatenationFile(path)) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
BaseFileSystem.DeleteDirectoryRecursively(path);
}
@ -104,7 +110,7 @@ namespace LibHac.Fs
{
path = PathTools.Normalize(path);
if (IsConcatenationFile(path)) throw new DirectoryNotFoundException();
if (IsConcatenationFile(path)) ThrowHelper.ThrowResult(ResultFs.PathNotFound);
BaseFileSystem.CleanDirectoryRecursively(path);
}
@ -134,7 +140,7 @@ namespace LibHac.Fs
if (IsConcatenationFile(path))
{
throw new DirectoryNotFoundException(path);
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
IDirectory parentDir = BaseFileSystem.OpenDirectory(path, OpenDirectoryMode.All);
@ -172,7 +178,7 @@ namespace LibHac.Fs
if (IsConcatenationFile(srcPath))
{
throw new DirectoryNotFoundException();
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
BaseFileSystem.RenameDirectory(srcPath, dstPath);
@ -238,7 +244,7 @@ namespace LibHac.Fs
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId)
{
if (queryId != QueryId.MakeConcatFile) throw new NotSupportedException();
if (queryId != QueryId.MakeConcatFile) ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationInConcatFsQueryEntry);
SetConcatenationFileAttribute(path);
}

View file

@ -175,24 +175,28 @@ namespace LibHac.Fs
public long GetFreeSpaceSize(string path)
{
throw new NotSupportedException();
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public long GetTotalSpaceSize(string path)
{
throw new NotSupportedException();
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public FileTimeStampRaw GetFileTimeStampRaw(string path)
{
throw new NotSupportedException();
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public void Commit()
{
if (OpenWritableFileCount > 0)
{
throw new InvalidOperationException("All files must be closed before commiting save data.");
ThrowHelper.ThrowResult(ResultFs.WritableFileOpen,
"All files must be closed before commiting save data.");
}
SynchronizeDirectory(SyncDir, WorkingDir);
@ -204,7 +208,7 @@ namespace LibHac.Fs
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId)
{
throw new NotSupportedException();
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
}
private string GetFullPath(string path)

View file

@ -20,14 +20,14 @@ namespace LibHac.Fs
{
if (IsDisposed) throw new ObjectDisposedException(null);
if ((Mode & OpenMode.Read) == 0) throw new NotSupportedException("File does not allow reading.");
if ((Mode & OpenMode.Read) == 0) ThrowHelper.ThrowResult(ResultFs.InvalidOpenModeOperation, "File does not allow reading.");
if (span == null) throw new ArgumentNullException(nameof(span));
if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Argument must be non-negative.");
if (offset < 0) ThrowHelper.ThrowResult(ResultFs.ValueOutOfRange, "Offset must be non-negative.");
long fileSize = GetSize();
int size = span.Length;
if (offset > fileSize) throw new ArgumentOutOfRangeException(nameof(offset), "Offset must be less than the file size.");
if (offset > fileSize) ThrowHelper.ThrowResult(ResultFs.ValueOutOfRange, "Offset must be less than the file size.");
return (int)Math.Min(fileSize - offset, size);
}
@ -36,10 +36,10 @@ namespace LibHac.Fs
{
if (IsDisposed) throw new ObjectDisposedException(null);
if ((Mode & OpenMode.Write) == 0) throw new NotSupportedException("File does not allow writing.");
if ((Mode & OpenMode.Write) == 0) ThrowHelper.ThrowResult(ResultFs.InvalidOpenModeOperation, "File does not allow writing.");
if (span == null) throw new ArgumentNullException(nameof(span));
if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Argument must be non-negative.");
if (offset < 0) ThrowHelper.ThrowResult(ResultFs.ValueOutOfRange, "Offset must be non-negative.");
long fileSize = GetSize();
int size = span.Length;
@ -48,7 +48,7 @@ namespace LibHac.Fs
{
if ((Mode & OpenMode.Append) == 0)
{
throw new NotSupportedException("File does not allow appending.");
ThrowHelper.ThrowResult(ResultFs.AllowAppendRequiredForImplicitExtension);
}
SetSize(offset + size);

View file

@ -4,7 +4,6 @@ using System.Runtime.CompilerServices;
using LibHac.Fs.Accessors;
using static LibHac.Results;
using static LibHac.Fs.ResultsFs;
namespace LibHac.Fs
{
@ -192,7 +191,7 @@ namespace LibHac.Fs
if (oldFileSystem != newFileSystem)
{
ThrowHelper.ThrowResult(ResultFsDifferentDestFileSystem);
ThrowHelper.ThrowResult(ResultFs.DifferentDestFileSystem);
}
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
@ -219,7 +218,7 @@ namespace LibHac.Fs
if (oldFileSystem != newFileSystem)
{
ThrowHelper.ThrowResult(ResultFsDifferentDestFileSystem);
ThrowHelper.ThrowResult(ResultFs.DifferentDestFileSystem);
}
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
@ -531,7 +530,7 @@ namespace LibHac.Fs
mountName = default;
subPath = default;
return ResultFsInvalidMountName;
return ResultFs.InvalidMountName;
}
mountName = path.Slice(0, mountLen);

View file

@ -91,7 +91,6 @@ namespace LibHac.Fs
/// </summary>
/// <param name="srcPath">The full path of the file to rename.</param>
/// <param name="dstPath">The new full path of the file.</param>
/// <exception cref="FileNotFoundException">The specified file does not exist.</exception>
/// <exception cref="IOException">An I/O error occurred while deleting the file.</exception>
void RenameFile(string srcPath, string dstPath);
@ -114,7 +113,6 @@ namespace LibHac.Fs
/// </summary>
/// <param name="path">The full path to check.</param>
/// <returns>The <see cref="DirectoryEntryType"/> of the file.</returns>
/// <exception cref="FileNotFoundException">The specified path does not exist.</exception>
DirectoryEntryType GetEntryType(string path);
/// <summary>

View file

@ -31,6 +31,11 @@ namespace LibHac.Fs
{
RelocationEntry entry = GetRelocationEntry(offset);
if (entry.SourceIndex > Sources.Count)
{
ThrowHelper.ThrowResult(ResultFs.InvalidIndirectStorageSource);
}
long inPos = offset;
int outPos = 0;
int remaining = destination.Length;
@ -55,16 +60,18 @@ namespace LibHac.Fs
protected override void WriteImpl(ReadOnlySpan<byte> source, long offset)
{
throw new NotImplementedException();
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationInIndirectStorageWrite);
}
public override void Flush()
{
throw new NotImplementedException();
}
public override void Flush() { }
public override long GetSize() => _length;
public override void SetSize(long size)
{
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationInIndirectStorageSetSize);
}
private RelocationEntry GetRelocationEntry(long offset)
{
int index = RelocationOffsets.BinarySearch(offset);

View file

@ -43,7 +43,8 @@ namespace LibHac.Fs
if (BlockValidities[blockIndex] == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
{
throw new InvalidDataException("Hash error!");
// Todo: Differentiate between the top and lower layers
ThrowHelper.ThrowResult(ResultFs.InvalidHashInIvfc, "Hash error!");
}
bool needsHashCheck = integrityCheckLevel != IntegrityCheckLevel.None &&
@ -104,7 +105,7 @@ namespace LibHac.Fs
if (validity == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid)
{
throw new InvalidDataException("Hash error!");
ThrowHelper.ThrowResult(ResultFs.InvalidHashInIvfc, "Hash error!");
}
}
finally

View file

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace LibHac.Fs
{
@ -44,7 +43,8 @@ namespace LibHac.Fs
}
}
throw new FileNotFoundException();
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
return default;
}
public bool DirectoryExists(string path)
@ -94,7 +94,8 @@ namespace LibHac.Fs
}
}
throw new FileNotFoundException(path);
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
return DirectoryEntryType.NotFound;
}
public FileTimeStampRaw GetFileTimeStampRaw(string path)
@ -109,7 +110,8 @@ namespace LibHac.Fs
}
}
throw new FileNotFoundException(path);
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
return default;
}
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId)
@ -125,20 +127,30 @@ namespace LibHac.Fs
}
}
throw new FileNotFoundException(path);
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
public void Commit() { }
public void CreateDirectory(string path) => throw new NotSupportedException();
public void CreateFile(string path, long size, CreateFileOptions options) => throw new NotSupportedException();
public void DeleteDirectory(string path) => throw new NotSupportedException();
public void DeleteDirectoryRecursively(string path) => throw new NotSupportedException();
public void CleanDirectoryRecursively(string path) => throw new NotSupportedException();
public void DeleteFile(string path) => throw new NotSupportedException();
public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException();
public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException();
public long GetFreeSpaceSize(string path) => throw new NotSupportedException();
public long GetTotalSpaceSize(string path) => throw new NotSupportedException();
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)
{
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
return default;
}
public long GetTotalSpaceSize(string path)
{
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
return default;
}
}
}

View file

@ -179,7 +179,8 @@ namespace LibHac.Fs
return DirectoryEntryType.File;
}
throw new FileNotFoundException(path);
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
return DirectoryEntryType.NotFound;
}
public FileTimeStampRaw GetFileTimeStampRaw(string path)
@ -208,6 +209,7 @@ namespace LibHac.Fs
public void Commit() { }
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) => throw new NotSupportedException();
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperation);
}
}

View file

@ -95,5 +95,10 @@ namespace LibHac.Fs
public override void Flush() { }
public override long GetSize() => _length;
public override void SetSize(long size)
{
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationInMemoryStorageSetSize);
}
}
}

View file

@ -150,8 +150,6 @@ namespace LibHac.Fs.NcaUtils
{
const int sectorSize = 0x200;
NcaFsHeader fsHeader = Header.GetFsHeader(index);
byte[] key0 = GetContentKey(NcaKeyType.AesXts0);
byte[] key1 = GetContentKey(NcaKeyType.AesXts1);

View file

@ -28,11 +28,22 @@ namespace LibHac.Fs
public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{
throw new NotImplementedException();
ValidateWriteParams(source, offset);
BaseStorage.Write(source, offset);
if ((options & WriteOption.Flush) != 0)
{
BaseStorage.Flush();
}
}
public override void Flush()
{
if ((Mode & OpenMode.Write) != 0)
{
BaseStorage.Flush();
}
}
public override long GetSize()
@ -42,7 +53,7 @@ namespace LibHac.Fs
public override void SetSize(long size)
{
throw new NotSupportedException();
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationInPartitionFileSetSize);
}
}
}

View file

@ -40,7 +40,7 @@ namespace LibHac.Fs
if (!FileDict.TryGetValue(path, out PartitionFileEntry entry))
{
throw new FileNotFoundException();
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
return OpenFile(entry, mode);
@ -75,19 +75,35 @@ namespace LibHac.Fs
throw new FileNotFoundException(path);
}
public void CreateDirectory(string path) => throw new NotSupportedException();
public void CreateFile(string path, long size, CreateFileOptions options) => throw new NotSupportedException();
public void DeleteDirectory(string path) => throw new NotSupportedException();
public void DeleteDirectoryRecursively(string path) => throw new NotSupportedException();
public void CleanDirectoryRecursively(string path) => throw new NotSupportedException();
public void DeleteFile(string path) => throw new NotSupportedException();
public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException();
public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException();
public long GetFreeSpaceSize(string path) => throw new NotSupportedException();
public long GetTotalSpaceSize(string path) => throw new NotSupportedException();
public FileTimeStampRaw GetFileTimeStampRaw(string path) => throw new NotSupportedException();
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 long GetFreeSpaceSize(string path)
{
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public long GetTotalSpaceSize(string path)
{
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public FileTimeStampRaw GetFileTimeStampRaw(string path)
{
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public void Commit() { }
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) => throw new NotSupportedException();
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) => ThrowHelper.ThrowResult(ResultFs.NotImplemented);
}
public enum PartitionFileSystemType
@ -122,7 +138,8 @@ namespace LibHac.Fs
Type = PartitionFileSystemType.Hashed;
break;
default:
throw new InvalidDataException($"Invalid Partition FS type \"{Magic}\"");
ThrowHelper.ThrowResult(ResultFs.InvalidPartitionFileSystemMagic, $"Invalid Partition FS type \"{Magic}\"");
break;
}
int entrySize = PartitionFileEntry.GetEntrySize(Type);

View file

@ -3,7 +3,6 @@ using System.Diagnostics;
using System.Runtime.CompilerServices;
using static LibHac.Results;
using static LibHac.Fs.ResultsFs;
#if !NETFRAMEWORK
using System.IO.Enumeration;
@ -382,7 +381,7 @@ namespace LibHac.Fs
}
mountName = default;
return ResultFsInvalidMountName;
return ResultFs.InvalidMountName;
}
public static bool MatchesPattern(string searchPattern, string name, bool ignoreCase)

View file

@ -22,7 +22,11 @@ namespace LibHac.Fs
}
public override void Flush() { }
public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options) => throw new NotSupportedException();
public override void SetSize(long size) => throw new NotSupportedException();
public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFile);
public override void SetSize(long size) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFile);
}
}

View file

@ -63,13 +63,29 @@ namespace LibHac.Fs
BaseFs.QueryEntry(outBuffer, inBuffer, path, queryId);
}
public void CreateDirectory(string path) => throw new NotSupportedException();
public void CreateFile(string path, long size, CreateFileOptions options) => throw new NotSupportedException();
public void DeleteDirectory(string path) => throw new NotSupportedException();
public void DeleteDirectoryRecursively(string path) => throw new NotSupportedException();
public void CleanDirectoryRecursively(string path) => throw new NotSupportedException();
public void DeleteFile(string path) => throw new NotSupportedException();
public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException();
public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException();
public void CreateDirectory(string path) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
public void CreateFile(string path, long size, CreateFileOptions options) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
public void DeleteDirectory(string path) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
public void DeleteDirectoryRecursively(string path) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
public void CleanDirectoryRecursively(string path) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
public void DeleteFile(string path) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
public void RenameDirectory(string srcPath, string dstPath) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
public void RenameFile(string srcPath, string dstPath) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyReadOnlyFileSystem);
}
}

71
src/LibHac/Fs/ResultFs.cs Normal file
View file

@ -0,0 +1,71 @@
namespace LibHac.Fs
{
public class ResultFs
{
public const int ModuleFs = 2;
public static Result PathNotFound => new Result(ModuleFs, 1);
public static Result MountNameAlreadyExists => new Result(ModuleFs, 60);
public static Result NotImplemented => new Result(ModuleFs, 3001);
public static Result ValueOutOfRange => new Result(ModuleFs, 3005);
public static Result AesXtsFileFileStorageAllocationError => new Result(ModuleFs, 3312);
public static Result AesXtsFileXtsStorageAllocationError => new Result(ModuleFs, 3313);
public static Result AesXtsFileAlignmentStorageAllocationError => new Result(ModuleFs, 3314);
public static Result AesXtsFileStorageFileAllocationError => new Result(ModuleFs, 3315);
public static Result AesXtsFileSubStorageAllocationError => new Result(ModuleFs, 3383);
public static Result InvalidIndirectStorageSource => new Result(ModuleFs, 4023);
public static Result InvalidSaveDataHeader => new Result(ModuleFs, 4315);
public static Result InvalidHashInIvfc => new Result(ModuleFs, 4604);
public static Result IvfcHashIsEmpty => new Result(ModuleFs, 4612);
public static Result InvalidHashInIvfcTopLayer => new Result(ModuleFs, 4613);
public static Result InvalidPartitionFileSystemMagic => new Result(ModuleFs, 4644);
public static Result InvalidHashedPartitionFileSystemMagic => new Result(ModuleFs, 4645);
public static Result AesXtsFileHeaderTooShort => new Result(ModuleFs, 4742);
public static Result AesXtsFileHeaderInvalidKeys => new Result(ModuleFs, 4743);
public static Result AesXtsFileHeaderInvalidMagic => new Result(ModuleFs, 4744);
public static Result AesXtsFileTooShort => new Result(ModuleFs, 4745);
public static Result AesXtsFileHeaderTooShortInSetSize => new Result(ModuleFs, 4746);
public static Result AesXtsFileHeaderInvalidKeysInRenameFile => new Result(ModuleFs, 4747);
public static Result AesXtsFileHeaderInvalidKeysInSetSize => new Result(ModuleFs, 4748);
public static Result InvalidInput => new Result(ModuleFs, 6001);
public static Result DifferentDestFileSystem => new Result(ModuleFs, 6034);
public static Result InvalidOffset => new Result(ModuleFs, 6061);
public static Result InvalidSize => new Result(ModuleFs, 6062);
public static Result NullArgument => new Result(ModuleFs, 6063);
public static Result InvalidMountName => new Result(ModuleFs, 6065);
public static Result InvalidOpenModeOperation => new Result(ModuleFs, 6200);
public static Result AllowAppendRequiredForImplicitExtension => new Result(ModuleFs, 6201);
public static Result UnsupportedOperation => new Result(ModuleFs, 6300);
public static Result UnsupportedOperationInMemoryStorageSetSize => new Result(ModuleFs, 6316);
public static Result UnsupportedOperationInHierarchicalIvfcStorageSetSize => new Result(ModuleFs, 6304);
public static Result UnsupportedOperationInIndirectStorageWrite => new Result(ModuleFs, 6324);
public static Result UnsupportedOperationInIndirectStorageSetSize => new Result(ModuleFs, 6325);
public static Result UnsupportedOperationInConcatFsQueryEntry => new Result(ModuleFs, 6359);
public static Result UnsupportedOperationModifyRomFsFileSystem => new Result(ModuleFs, 6364);
public static Result UnsupportedOperationRomFsFileSystemGetSpace => new Result(ModuleFs, 6366);
public static Result UnsupportedOperationModifyRomFsFile => new Result(ModuleFs, 6367);
public static Result UnsupportedOperationModifyReadOnlyFileSystem => new Result(ModuleFs, 6369);
public static Result UnsupportedOperationReadOnlyFileSystemGetSpace => new Result(ModuleFs, 6371);
public static Result UnsupportedOperationModifyReadOnlyFile => new Result(ModuleFs, 6372);
public static Result UnsupportedOperationModifyPartitionFileSystem => new Result(ModuleFs, 6374);
public static Result UnsupportedOperationInPartitionFileSetSize => new Result(ModuleFs, 6376);
public static Result WriteStateUnflushed => new Result(ModuleFs, 6454);
public static Result WritableFileOpen => new Result(ModuleFs, 6457);
public static Result AllocationTableInsufficientFreeBlocks => new Result(ModuleFs, 6707);
public static Result MountNameNotFound => new Result(ModuleFs, 6905);
}
}

View file

@ -1,16 +0,0 @@
namespace LibHac.Fs
{
public class ResultsFs
{
public const int ModuleFs = 2;
public static Result ResultFsPathNotFound => new Result(ModuleFs, 1);
public static Result ResultFsMountNameAlreadyExists => new Result(ModuleFs, 60);
public static Result ResultFsDifferentDestFileSystem => new Result(ModuleFs, 6034);
public static Result ResultFsNullArgument => new Result(ModuleFs, 6063);
public static Result ResultFsInvalidMountName => new Result(ModuleFs, 6065);
public static Result ResultFsWriteStateUnflushed => new Result(ModuleFs, 6454);
public static Result ResultFsWritableFileOpen => new Result(ModuleFs, 6457);
public static Result ResultFsMountNameNotFound => new Result(ModuleFs, 6905);
}
}

View file

@ -28,7 +28,7 @@ namespace LibHac.Fs.RomFs
public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{
throw new NotImplementedException();
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFile);
}
public override void Flush()
@ -42,7 +42,7 @@ namespace LibHac.Fs.RomFs
public override void SetSize(long size)
{
throw new NotSupportedException();
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFile);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.IO;
namespace LibHac.Fs.RomFs
{
@ -30,7 +29,8 @@ namespace LibHac.Fs.RomFs
if (FileExists(path)) return DirectoryEntryType.File;
if (DirectoryExists(path)) return DirectoryEntryType.Directory;
throw new FileNotFoundException(path);
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
return DirectoryEntryType.NotFound;
}
public void Commit() { }
@ -41,7 +41,7 @@ namespace LibHac.Fs.RomFs
if (!FileTable.TryOpenDirectory(path, out FindPosition position))
{
throw new DirectoryNotFoundException();
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
return new RomFsDirectory(this, path, position, mode);
@ -53,12 +53,12 @@ namespace LibHac.Fs.RomFs
if (!FileTable.TryOpenFile(path, out RomFileInfo info))
{
throw new FileNotFoundException();
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
if (mode != OpenMode.Read)
{
throw new ArgumentOutOfRangeException(nameof(mode), "RomFs files must be opened read-only.");
ThrowHelper.ThrowResult(ResultFs.InvalidInput, "RomFs files must be opened read-only.");
}
return new RomFsFile(BaseStorage, Header.DataOffset + info.Offset, info.Length);
@ -83,18 +83,50 @@ namespace LibHac.Fs.RomFs
return BaseStorage;
}
public void CreateDirectory(string path) => throw new NotSupportedException();
public void CreateFile(string path, long size, CreateFileOptions options) => throw new NotSupportedException();
public void DeleteDirectory(string path) => throw new NotSupportedException();
public void DeleteDirectoryRecursively(string path) => throw new NotSupportedException();
public void CleanDirectoryRecursively(string path) => throw new NotSupportedException();
public void DeleteFile(string path) => throw new NotSupportedException();
public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException();
public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException();
public long GetFreeSpaceSize(string path) => throw new NotSupportedException();
public long GetTotalSpaceSize(string path) => throw new NotSupportedException();
public FileTimeStampRaw GetFileTimeStampRaw(string path) => throw new NotSupportedException();
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) => throw new NotSupportedException();
public void CreateDirectory(string path) =>
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationModifyRomFsFileSystem);
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)
{
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationRomFsFileSystemGetSpace);
return default;
}
public long GetTotalSpaceSize(string path)
{
ThrowHelper.ThrowResult(ResultFs.UnsupportedOperationRomFsFileSystemGetSpace);
return default;
}
public FileTimeStampRaw GetFileTimeStampRaw(string path)
{
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) =>
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
}
public class RomfsHeader

View file

@ -46,7 +46,7 @@ namespace LibHac.Fs.Save
}
else
{
throw new InvalidDataException("Savedata header is not valid.");
ThrowHelper.ThrowResult(ResultFs.InvalidSaveDataHeader, "Savedata header is not valid.");
}
Header = IsFirstHeaderInUse ? headerA : headerB;
@ -215,8 +215,14 @@ namespace LibHac.Fs.Save
Commit(Keyset);
}
public FileTimeStampRaw GetFileTimeStampRaw(string path) => throw new NotSupportedException();
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) => throw new NotSupportedException();
public FileTimeStampRaw GetFileTimeStampRaw(string path)
{
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) =>
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
public bool Commit(Keyset keyset)
{

View file

@ -51,7 +51,8 @@ namespace LibHac.Fs.Save
if (startBlock == -1)
{
throw new IOException("Not enough available space to create file.");
ThrowHelper.ThrowResult(ResultFs.AllocationTableInsufficientFreeBlocks,
"Not enough available space to create file.");
}
var fileEntry = new SaveFileInfo { StartBlock = startBlock, Length = size };
@ -88,7 +89,7 @@ namespace LibHac.Fs.Save
if (!FileTable.TryOpenFile(path, out SaveFileInfo fileInfo))
{
throw new FileNotFoundException();
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
if (fileInfo.StartBlock != int.MinValue)
@ -105,7 +106,7 @@ namespace LibHac.Fs.Save
if (!FileTable.TryOpenDirectory(path, out SaveFindPosition position))
{
throw new DirectoryNotFoundException();
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
return new SaveDataDirectory(this, path, position, mode);
@ -117,7 +118,7 @@ namespace LibHac.Fs.Save
if (!FileTable.TryOpenFile(path, out SaveFileInfo file))
{
throw new FileNotFoundException();
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
}
AllocationTableStorage storage = OpenFatStorage(file.StartBlock);
@ -162,7 +163,8 @@ namespace LibHac.Fs.Save
if (FileExists(path)) return DirectoryEntryType.File;
if (DirectoryExists(path)) return DirectoryEntryType.Directory;
throw new FileNotFoundException(path);
ThrowHelper.ThrowResult(ResultFs.PathNotFound);
return DirectoryEntryType.NotFound;
}
public long GetFreeSpaceSize(string path)
@ -181,8 +183,14 @@ namespace LibHac.Fs.Save
}
public FileTimeStampRaw GetFileTimeStampRaw(string path) => throw new NotSupportedException();
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) => throw new NotSupportedException();
public FileTimeStampRaw GetFileTimeStampRaw(string path)
{
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
return default;
}
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId) =>
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();

View file

@ -28,7 +28,7 @@ namespace LibHac.Fs
public virtual void SetSize(long size)
{
throw new NotSupportedException();
ThrowHelper.ThrowResult(ResultFs.NotImplemented);
}
protected virtual void Dispose(bool disposing)

View file

@ -53,6 +53,7 @@ namespace LibHac.Fs
return storage.AsReadOnly(true);
}
// Todo: Move out of SubStorage
public static IStorage AsReadOnly(this IStorage storage, bool leaveOpen)
{
return new SubStorage(storage, 0, storage.GetSize(), leaveOpen, FileAccess.Read);

View file

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using LibHac.Fs;
using LibHac.Fs.NcaUtils;
using LibHac.Fs.Save;