mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add some validation to StorageBase
This commit is contained in:
parent
54950c9b68
commit
bfc343e801
9 changed files with 89 additions and 40 deletions
|
@ -55,7 +55,7 @@ namespace LibHac.Fs
|
||||||
|
|
||||||
public Result GetSize(out long size)
|
public Result GetSize(out long size)
|
||||||
{
|
{
|
||||||
size = 0;
|
size = default;
|
||||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||||
|
|
||||||
return GetSizeImpl(out size);
|
return GetSizeImpl(out size);
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace LibHac.Fs
|
||||||
FsClient = Handle.File.Parent.FsClient;
|
FsClient = Handle.File.Parent.FsClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Read(long offset, Span<byte> destination)
|
public override Result ReadImpl(long offset, Span<byte> destination)
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
|
@ -30,14 +30,13 @@ namespace LibHac.Fs
|
||||||
Result rc = UpdateSize();
|
Result rc = UpdateSize();
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
if (destination.Length < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
|
|
||||||
if (!IsRangeValid(offset, destination.Length, FileSize)) return ResultFs.ValueOutOfRange.Log();
|
if (!IsRangeValid(offset, destination.Length, FileSize)) return ResultFs.ValueOutOfRange.Log();
|
||||||
|
|
||||||
return FsClient.ReadFile(Handle, offset, destination);
|
return FsClient.ReadFile(Handle, offset, destination);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Write(long offset, ReadOnlySpan<byte> source)
|
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source)
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
|
@ -46,26 +45,25 @@ namespace LibHac.Fs
|
||||||
Result rc = UpdateSize();
|
Result rc = UpdateSize();
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
if (source.Length < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
|
|
||||||
if (!IsRangeValid(offset, source.Length, FileSize)) return ResultFs.ValueOutOfRange.Log();
|
if (!IsRangeValid(offset, source.Length, FileSize)) return ResultFs.ValueOutOfRange.Log();
|
||||||
|
|
||||||
return FsClient.WriteFile(Handle, offset, source);
|
return FsClient.WriteFile(Handle, offset, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Flush()
|
public override Result FlushImpl()
|
||||||
{
|
{
|
||||||
return FsClient.FlushFile(Handle);
|
return FsClient.FlushFile(Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result SetSize(long size)
|
public override Result SetSizeImpl(long size)
|
||||||
{
|
{
|
||||||
FileSize = InvalidSize;
|
FileSize = InvalidSize;
|
||||||
|
|
||||||
return FsClient.SetFileSize(Handle, size);
|
return FsClient.SetFileSize(Handle, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result GetSize(out long size)
|
public override Result GetSizeImpl(out long size)
|
||||||
{
|
{
|
||||||
size = default;
|
size = default;
|
||||||
|
|
||||||
|
@ -87,7 +85,7 @@ namespace LibHac.Fs
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (CloseHandle)
|
if (CloseHandle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -205,8 +205,8 @@ namespace LibHac.Fs
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
Application = 1 << 0,
|
Application = 1 << 0,
|
||||||
Internal = 1 << 1,
|
System = 1 << 1,
|
||||||
All = Application | Internal
|
All = Application | System
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
|
|
@ -135,7 +135,7 @@
|
||||||
|
|
||||||
public static Result RemapStorageMapFull => new Result(ModuleFs, 6811);
|
public static Result RemapStorageMapFull => new Result(ModuleFs, 6811);
|
||||||
|
|
||||||
public static Result Result6902 => new Result(ModuleFs, 6902);
|
public static Result SubStorageNotInitialized => new Result(ModuleFs, 6902);
|
||||||
public static Result MountNameNotFound => new Result(ModuleFs, 6905);
|
public static Result MountNameNotFound => new Result(ModuleFs, 6905);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace LibHac.Fs
|
||||||
public static Result CreateSystemSaveData(this FileSystemClient fs, SaveDataSpaceId spaceId,
|
public static Result CreateSystemSaveData(this FileSystemClient fs, SaveDataSpaceId spaceId,
|
||||||
ulong saveDataId, UserId userId, ulong ownerId, long size, long journalSize, uint flags)
|
ulong saveDataId, UserId userId, ulong ownerId, long size, long journalSize, uint flags)
|
||||||
{
|
{
|
||||||
return fs.RunOperationWithAccessLog(LocalAccessLogMode.Internal,
|
return fs.RunOperationWithAccessLog(LocalAccessLogMode.System,
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
@ -89,7 +89,7 @@ namespace LibHac.Fs
|
||||||
|
|
||||||
public static Result DeleteSaveData(this FileSystemClient fs, ulong saveDataId)
|
public static Result DeleteSaveData(this FileSystemClient fs, ulong saveDataId)
|
||||||
{
|
{
|
||||||
return fs.RunOperationWithAccessLog(LocalAccessLogMode.Internal,
|
return fs.RunOperationWithAccessLog(LocalAccessLogMode.System,
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
|
@ -1,20 +1,71 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace LibHac.Fs
|
namespace LibHac.Fs
|
||||||
{
|
{
|
||||||
public abstract class StorageBase : IStorage
|
public abstract class StorageBase : IStorage
|
||||||
{
|
{
|
||||||
public abstract Result Read(long offset, Span<byte> destination);
|
// 0 = not disposed; 1 = disposed
|
||||||
public abstract Result Write(long offset, ReadOnlySpan<byte> source);
|
private int _disposedState;
|
||||||
public abstract Result Flush();
|
private bool IsDisposed => _disposedState != 0;
|
||||||
public abstract Result SetSize(long size);
|
|
||||||
public abstract Result GetSize(out long size);
|
|
||||||
|
|
||||||
public virtual void Dispose() { }
|
public abstract Result ReadImpl(long offset, Span<byte> destination);
|
||||||
|
public abstract Result WriteImpl(long offset, ReadOnlySpan<byte> source);
|
||||||
|
public abstract Result FlushImpl();
|
||||||
|
public abstract Result GetSizeImpl(out long size);
|
||||||
|
public abstract Result SetSizeImpl(long size);
|
||||||
|
|
||||||
|
public Result Read(long offset, Span<byte> destination)
|
||||||
|
{
|
||||||
|
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||||
|
|
||||||
|
return ReadImpl(offset, destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result Write(long offset, ReadOnlySpan<byte> source)
|
||||||
|
{
|
||||||
|
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||||
|
|
||||||
|
return WriteImpl(offset, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result Flush()
|
||||||
|
{
|
||||||
|
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||||
|
|
||||||
|
return FlushImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result SetSize(long size)
|
||||||
|
{
|
||||||
|
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||||
|
|
||||||
|
return SetSizeImpl(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result GetSize(out long size)
|
||||||
|
{
|
||||||
|
size = default;
|
||||||
|
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||||
|
|
||||||
|
return GetSizeImpl(out size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Make sure Dispose is only called once
|
||||||
|
if (Interlocked.CompareExchange(ref _disposedState, 1, 0) == 0)
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing) { }
|
||||||
|
|
||||||
public static bool IsRangeValid(long offset, long size, long totalSize)
|
public static bool IsRangeValid(long offset, long size, long totalSize)
|
||||||
{
|
{
|
||||||
return size <= totalSize && offset <= totalSize - size;
|
return offset >= 0 && size >= 0 && size <= totalSize && offset <= totalSize - size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,38 +23,38 @@ namespace LibHac.Fs
|
||||||
Size = size;
|
Size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Read(long offset, Span<byte> destination)
|
public override Result ReadImpl(long offset, Span<byte> destination)
|
||||||
{
|
{
|
||||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||||
if (destination.Length == 0) return Result.Success;
|
if (destination.Length == 0) return Result.Success;
|
||||||
if (Size < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
|
|
||||||
if (!IsRangeValid(offset, destination.Length, Size)) return ResultFs.ValueOutOfRange.Log();
|
if (!IsRangeValid(offset, destination.Length, Size)) return ResultFs.ValueOutOfRange.Log();
|
||||||
|
|
||||||
return BaseStorage.Read(Offset + offset, destination);
|
return BaseStorage.Read(Offset + offset, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Write(long offset, ReadOnlySpan<byte> source)
|
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source)
|
||||||
{
|
{
|
||||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||||
if (source.Length == 0) return Result.Success;
|
if (source.Length == 0) return Result.Success;
|
||||||
if (Size < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
|
|
||||||
if (!IsRangeValid(offset, source.Length, Size)) return ResultFs.ValueOutOfRange.Log();
|
if (!IsRangeValid(offset, source.Length, Size)) return ResultFs.ValueOutOfRange.Log();
|
||||||
|
|
||||||
return BaseStorage.Write(Offset + offset, source);
|
return BaseStorage.Write(Offset + offset, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Flush()
|
public override Result FlushImpl()
|
||||||
{
|
{
|
||||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||||
|
|
||||||
return BaseStorage.Flush();
|
return BaseStorage.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result SetSize(long size)
|
public override Result SetSizeImpl(long size)
|
||||||
{
|
{
|
||||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||||
if (!IsResizable) return ResultFs.SubStorageNotResizable.Log();
|
if (!IsResizable) return ResultFs.SubStorageNotResizable.Log();
|
||||||
if (size < 0 || Offset < 0) return ResultFs.ValueOutOfRange.Log();
|
if (size < 0 || Offset < 0) return ResultFs.InvalidSize.Log();
|
||||||
|
|
||||||
Result rc = BaseStorage.GetSize(out long baseSize);
|
Result rc = BaseStorage.GetSize(out long baseSize);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
@ -72,11 +72,11 @@ namespace LibHac.Fs
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result GetSize(out long size)
|
public override Result GetSizeImpl(out long size)
|
||||||
{
|
{
|
||||||
size = default;
|
size = default;
|
||||||
|
|
||||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||||
|
|
||||||
size = Size;
|
size = Size;
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace LibHac.FsService.Creators
|
||||||
imageHash.CopyTo(ImageHash);
|
imageHash.CopyTo(ImageHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Read(long offset, Span<byte> destination)
|
public override Result ReadImpl(long offset, Span<byte> destination)
|
||||||
{
|
{
|
||||||
// In secure mode, if Handle is old and the card's device ID and
|
// In secure mode, if Handle is old and the card's device ID and
|
||||||
// header hash are still the same, Handle is updated to the new handle
|
// header hash are still the same, Handle is updated to the new handle
|
||||||
|
@ -95,22 +95,22 @@ namespace LibHac.FsService.Creators
|
||||||
return GameCard.Read(Handle, offset, destination);
|
return GameCard.Read(Handle, offset, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Write(long offset, ReadOnlySpan<byte> source)
|
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source)
|
||||||
{
|
{
|
||||||
return ResultFs.UnsupportedOperationInRoGameCardStorageWrite.Log();
|
return ResultFs.UnsupportedOperationInRoGameCardStorageWrite.Log();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Flush()
|
public override Result FlushImpl()
|
||||||
{
|
{
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result SetSize(long size)
|
public override Result SetSizeImpl(long size)
|
||||||
{
|
{
|
||||||
return ResultFs.UnsupportedOperationInRoGameCardStorageSetSize.Log();
|
return ResultFs.UnsupportedOperationInRoGameCardStorageSetSize.Log();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result GetSize(out long size)
|
public override Result GetSizeImpl(out long size)
|
||||||
{
|
{
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace LibHac.FsSystem
|
||||||
|
|
||||||
public override Result SetSize(long size)
|
public override Result SetSize(long size)
|
||||||
{
|
{
|
||||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||||
|
|
||||||
// todo: Add IsResizable member
|
// todo: Add IsResizable member
|
||||||
// if (!IsResizable) return ResultFs.SubStorageNotResizable.Log();
|
// if (!IsResizable) return ResultFs.SubStorageNotResizable.Log();
|
||||||
|
|
Loading…
Reference in a new issue