diff --git a/src/LibHac/FsSrv/Impl/IResultConvertFileSystem.cs b/src/LibHac/FsSrv/Impl/IResultConvertFileSystem.cs
index 989eca42..2f361d21 100644
--- a/src/LibHac/FsSrv/Impl/IResultConvertFileSystem.cs
+++ b/src/LibHac/FsSrv/Impl/IResultConvertFileSystem.cs
@@ -6,6 +6,11 @@ using LibHac.Fs.Fsa;
namespace LibHac.FsSrv.Impl;
// ReSharper disable once InconsistentNaming
+///
+/// Wraps an , converting its returned s to different
+/// s based on the function.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public abstract class IResultConvertFile : IFile
{
protected UniqueRef BaseFile;
@@ -56,6 +61,11 @@ public abstract class IResultConvertFile : IFile
}
// ReSharper disable once InconsistentNaming
+///
+/// Wraps an , converting its returned s to different
+/// s based on the function.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public abstract class IResultConvertDirectory : IDirectory
{
protected UniqueRef BaseDirectory;
@@ -85,6 +95,11 @@ public abstract class IResultConvertDirectory : IDirectory
}
// ReSharper disable once InconsistentNaming
+///
+/// Wraps an , converting its returned s to different
+/// s based on the function.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public abstract class IResultConvertFileSystem : IFileSystem
{
protected SharedRef BaseFileSystem;
@@ -145,6 +160,8 @@ public abstract class IResultConvertFileSystem : IFileSystem
return ConvertResult(BaseFileSystem.Get.GetEntryType(out entryType, path));
}
+ // Note: The original code uses templates to determine which type of IFile/IDirectory to return. To make things
+ // easier in C# these two functions have been made abstract functions.
protected abstract override Result DoOpenFile(ref UniqueRef outFile, in Path path, OpenMode mode);
protected abstract override Result DoOpenDirectory(ref UniqueRef outDirectory, in Path path,
@@ -192,4 +209,4 @@ public abstract class IResultConvertFileSystem : IFileSystem
}
protected abstract Result ConvertResult(Result result);
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSrv/Impl/SaveDataExtraDataAccessorCacheManager.cs b/src/LibHac/FsSrv/Impl/SaveDataExtraDataAccessorCacheManager.cs
index aa378dfe..1d3ce965 100644
--- a/src/LibHac/FsSrv/Impl/SaveDataExtraDataAccessorCacheManager.cs
+++ b/src/LibHac/FsSrv/Impl/SaveDataExtraDataAccessorCacheManager.cs
@@ -10,8 +10,13 @@ namespace LibHac.FsSrv.Impl;
///
/// Holds the s for opened save data file systems.
///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public class SaveDataExtraDataAccessorCacheManager : ISaveDataExtraDataAccessorCacheObserver
{
+ ///
+ /// Holds a single cached extra data accessor identified by its save data ID and save data space ID.
+ ///
+ /// Based on FS 13.1.0 (nnSdk 13.4.0)
[NonCopyable]
private struct Cache : IDisposable
{
@@ -19,8 +24,7 @@ public class SaveDataExtraDataAccessorCacheManager : ISaveDataExtraDataAccessorC
private readonly SaveDataSpaceId _spaceId;
private readonly ulong _saveDataId;
- public Cache(in SharedRef accessor, SaveDataSpaceId spaceId,
- ulong saveDataId)
+ public Cache(in SharedRef accessor, SaveDataSpaceId spaceId, ulong saveDataId)
{
_accessor = new WeakRef(in accessor);
_spaceId = spaceId;
@@ -49,7 +53,7 @@ public class SaveDataExtraDataAccessorCacheManager : ISaveDataExtraDataAccessorC
public SaveDataExtraDataAccessorCacheManager()
{
_accessorList = new LinkedList();
- _mutex.Initialize();
+ _mutex = new SdkRecursiveMutexType();
}
public void Dispose()
@@ -138,4 +142,4 @@ public class SaveDataExtraDataAccessorCacheManager : ISaveDataExtraDataAccessorC
{
return new UniqueLockRef(ref _mutex);
}
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSrv/Impl/SaveDataResultConvertFileSystem.cs b/src/LibHac/FsSrv/Impl/SaveDataResultConvertFileSystem.cs
index 9a6204d0..d49eab27 100644
--- a/src/LibHac/FsSrv/Impl/SaveDataResultConvertFileSystem.cs
+++ b/src/LibHac/FsSrv/Impl/SaveDataResultConvertFileSystem.cs
@@ -6,6 +6,10 @@ using LibHac.FsSystem;
namespace LibHac.FsSrv.Impl;
+///
+/// Contains functions for converting internal save data s to external s.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public static class SaveDataResultConvert
{
private static Result ConvertCorruptedResult(Result result)
@@ -13,19 +17,19 @@ public static class SaveDataResultConvert
if (ResultFs.IntegrityVerificationStorageCorrupted.Includes(result))
{
if (ResultFs.IncorrectIntegrityVerificationMagicCode.Includes(result))
- return ResultFs.IncorrectSaveDataIntegrityVerificationMagicCode.Value;
+ return ResultFs.IncorrectSaveDataIntegrityVerificationMagicCode.LogConverted(result);
if (ResultFs.InvalidZeroHash.Includes(result))
- return ResultFs.InvalidSaveDataZeroHash.Value;
+ return ResultFs.InvalidSaveDataZeroHash.LogConverted(result);
if (ResultFs.NonRealDataVerificationFailed.Includes(result))
- return ResultFs.SaveDataNonRealDataVerificationFailed.Value;
+ return ResultFs.SaveDataNonRealDataVerificationFailed.LogConverted(result);
if (ResultFs.ClearedRealDataVerificationFailed.Includes(result))
- return ResultFs.ClearedSaveDataRealDataVerificationFailed.Value;
+ return ResultFs.ClearedSaveDataRealDataVerificationFailed.LogConverted(result);
if (ResultFs.UnclearedRealDataVerificationFailed.Includes(result))
- return ResultFs.UnclearedSaveDataRealDataVerificationFailed.Value;
+ return ResultFs.UnclearedSaveDataRealDataVerificationFailed.LogConverted(result);
Assert.SdkAssert(false);
}
@@ -33,16 +37,16 @@ public static class SaveDataResultConvert
if (ResultFs.HostFileSystemCorrupted.Includes(result))
{
if (ResultFs.HostEntryCorrupted.Includes(result))
- return ResultFs.SaveDataHostEntryCorrupted.Value;
+ return ResultFs.SaveDataHostEntryCorrupted.LogConverted(result);
if (ResultFs.HostFileDataCorrupted.Includes(result))
- return ResultFs.SaveDataHostFileDataCorrupted.Value;
+ return ResultFs.SaveDataHostFileDataCorrupted.LogConverted(result);
if (ResultFs.HostFileCorrupted.Includes(result))
- return ResultFs.SaveDataHostFileCorrupted.Value;
+ return ResultFs.SaveDataHostFileCorrupted.LogConverted(result);
if (ResultFs.InvalidHostHandle.Includes(result))
- return ResultFs.InvalidSaveDataHostHandle.Value;
+ return ResultFs.InvalidSaveDataHostHandle.LogConverted(result);
Assert.SdkAssert(false);
}
@@ -50,25 +54,25 @@ public static class SaveDataResultConvert
if (ResultFs.DatabaseCorrupted.Includes(result))
{
if (ResultFs.InvalidAllocationTableBlock.Includes(result))
- return ResultFs.InvalidSaveDataAllocationTableBlock.Value;
+ return ResultFs.InvalidSaveDataAllocationTableBlock.LogConverted(result);
if (ResultFs.InvalidKeyValueListElementIndex.Includes(result))
- return ResultFs.InvalidSaveDataKeyValueListElementIndex.Value;
+ return ResultFs.InvalidSaveDataKeyValueListElementIndex.LogConverted(result);
if (ResultFs.InvalidAllocationTableChainEntry.Includes(result))
- return ResultFs.InvalidSaveDataAllocationTableChainEntry.Value;
+ return ResultFs.InvalidSaveDataAllocationTableChainEntry.LogConverted(result);
if (ResultFs.InvalidAllocationTableOffset.Includes(result))
- return ResultFs.InvalidSaveDataAllocationTableOffset.Value;
+ return ResultFs.InvalidSaveDataAllocationTableOffset.LogConverted(result);
if (ResultFs.InvalidAllocationTableBlockCount.Includes(result))
- return ResultFs.InvalidSaveDataAllocationTableBlockCount.Value;
+ return ResultFs.InvalidSaveDataAllocationTableBlockCount.LogConverted(result);
if (ResultFs.InvalidKeyValueListEntryIndex.Includes(result))
- return ResultFs.InvalidSaveDataKeyValueListEntryIndex.Value;
+ return ResultFs.InvalidSaveDataKeyValueListEntryIndex.LogConverted(result);
if (ResultFs.InvalidBitmapIndex.Includes(result))
- return ResultFs.InvalidSaveDataBitmapIndex.Value;
+ return ResultFs.InvalidSaveDataBitmapIndex.LogConverted(result);
Assert.SdkAssert(false);
}
@@ -76,7 +80,7 @@ public static class SaveDataResultConvert
if (ResultFs.ZeroBitmapFileCorrupted.Includes(result))
{
if (ResultFs.IncompleteBlockInZeroBitmapHashStorageFile.Includes(result))
- return ResultFs.IncompleteBlockInZeroBitmapHashStorageFileSaveData.Value;
+ return ResultFs.IncompleteBlockInZeroBitmapHashStorageFileSaveData.LogConverted(result);
Assert.SdkAssert(false);
}
@@ -84,13 +88,13 @@ public static class SaveDataResultConvert
return result;
}
- public static Result ConvertSaveFsDriverPublicResult(Result result)
+ public static Result ConvertSaveFsDriverPrivateResult(Result result)
{
if (result.IsSuccess())
return result;
if (ResultFs.UnsupportedVersion.Includes(result))
- return ResultFs.UnsupportedSaveDataVersion.Value;
+ return ResultFs.UnsupportedSaveDataVersion.LogConverted(result);
if (ResultFs.IntegrityVerificationStorageCorrupted.Includes(result) ||
ResultFs.BuiltInStorageCorrupted.Includes(result) ||
@@ -105,21 +109,21 @@ public static class SaveDataResultConvert
return result;
if (ResultFs.NotFound.Includes(result))
- return ResultFs.PathNotFound.Value;
+ return ResultFs.PathNotFound.LogConverted(result);
if (ResultFs.AllocationTableFull.Includes(result))
- return ResultFs.UsableSpaceNotEnough.Value;
+ return ResultFs.UsableSpaceNotEnough.LogConverted(result);
if (ResultFs.AlreadyExists.Includes(result))
- return ResultFs.PathAlreadyExists.Value;
+ return ResultFs.PathAlreadyExists.LogConverted(result);
if (ResultFs.InvalidOffset.Includes(result))
- return ResultFs.OutOfRange.Value;
+ return ResultFs.OutOfRange.LogConverted(result);
if (ResultFs.IncompatiblePath.Includes(result) ||
ResultFs.FileNotFound.Includes(result))
{
- return ResultFs.PathNotFound.Value;
+ return ResultFs.PathNotFound.LogConverted(result);
}
return result;
@@ -130,6 +134,7 @@ public static class SaveDataResultConvert
/// Wraps an , converting its returned s
/// to save-data-specific s.
///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public class SaveDataResultConvertFile : IResultConvertFile
{
public SaveDataResultConvertFile(ref UniqueRef baseFile) : base(ref baseFile)
@@ -138,7 +143,7 @@ public class SaveDataResultConvertFile : IResultConvertFile
protected override Result ConvertResult(Result result)
{
- return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(result);
+ return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(result);
}
}
@@ -146,6 +151,7 @@ public class SaveDataResultConvertFile : IResultConvertFile
/// Wraps an , converting its returned s
/// to save-data-specific s.
///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public class SaveDataResultConvertDirectory : IResultConvertDirectory
{
public SaveDataResultConvertDirectory(ref UniqueRef baseDirectory) : base(ref baseDirectory)
@@ -154,7 +160,7 @@ public class SaveDataResultConvertDirectory : IResultConvertDirectory
protected override Result ConvertResult(Result result)
{
- return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(result);
+ return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(result);
}
}
@@ -162,6 +168,7 @@ public class SaveDataResultConvertDirectory : IResultConvertDirectory
/// Wraps an , converting its returned s
/// to save-data-specific s.
///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public class SaveDataResultConvertFileSystem : IResultConvertFileSystem
{
public SaveDataResultConvertFileSystem(ref SharedRef baseFileSystem)
@@ -192,7 +199,7 @@ public class SaveDataResultConvertFileSystem : IResultConvertFileSystem
protected override Result ConvertResult(Result result)
{
- return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(result);
+ return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(result);
}
}
@@ -200,6 +207,7 @@ public class SaveDataResultConvertFileSystem : IResultConvertFileSystem
/// Wraps an , converting its returned s
/// to save-data-specific s.
///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public class SaveDataExtraDataResultConvertAccessor : ISaveDataExtraDataAccessor
{
private SharedRef _accessor;
@@ -217,19 +225,19 @@ public class SaveDataExtraDataResultConvertAccessor : ISaveDataExtraDataAccessor
public Result WriteExtraData(in SaveDataExtraData extraData)
{
Result rc = _accessor.Get.WriteExtraData(in extraData);
- return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(rc);
+ return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(rc);
}
public Result CommitExtraData(bool updateTimeStamp)
{
Result rc = _accessor.Get.CommitExtraData(updateTimeStamp);
- return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(rc);
+ return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(rc);
}
public Result ReadExtraData(out SaveDataExtraData extraData)
{
Result rc = _accessor.Get.ReadExtraData(out extraData);
- return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(rc);
+ return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(rc);
}
public void RegisterCacheObserver(ISaveDataExtraDataAccessorCacheObserver observer, SaveDataSpaceId spaceId,
@@ -237,4 +245,4 @@ public class SaveDataExtraDataResultConvertAccessor : ISaveDataExtraDataAccessor
{
_accessor.Get.RegisterCacheObserver(observer, spaceId, saveDataId);
}
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSrv/Impl/StorageInterfaceAdapter.cs b/src/LibHac/FsSrv/Impl/StorageInterfaceAdapter.cs
index 79b6f4ff..ef40a0cf 100644
--- a/src/LibHac/FsSrv/Impl/StorageInterfaceAdapter.cs
+++ b/src/LibHac/FsSrv/Impl/StorageInterfaceAdapter.cs
@@ -8,6 +8,10 @@ using IStorageSf = LibHac.FsSrv.Sf.IStorage;
namespace LibHac.FsSrv.Impl;
+///
+/// Wraps an to allow interfacing with it via the interface over IPC.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public class StorageInterfaceAdapter : IStorageSf
{
private SharedRef _baseStorage;
@@ -32,6 +36,9 @@ public class StorageInterfaceAdapter : IStorageSf
if (destination.Size < 0)
return ResultFs.InvalidSize.Log();
+ if (destination.Size < size)
+ return ResultFs.InvalidSize.Log();
+
Result rc = Result.Success;
for (int tryNum = 0; tryNum < maxTryCount; tryNum++)
@@ -54,6 +61,9 @@ public class StorageInterfaceAdapter : IStorageSf
if (source.Size < 0)
return ResultFs.InvalidSize.Log();
+ if (source.Size < size)
+ return ResultFs.InvalidSize.Log();
+
using var scopedPriorityChanger = new ScopedThreadPriorityChangerByAccessPriority(
ScopedThreadPriorityChangerByAccessPriority.AccessMode.Write);
@@ -99,4 +109,4 @@ public class StorageInterfaceAdapter : IStorageSf
return Result.Success;
}
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSystem/ISaveDataCommitTimeStampGetter.cs b/src/LibHac/FsSystem/ISaveDataCommitTimeStampGetter.cs
index cb10a64c..54f9cad6 100644
--- a/src/LibHac/FsSystem/ISaveDataCommitTimeStampGetter.cs
+++ b/src/LibHac/FsSystem/ISaveDataCommitTimeStampGetter.cs
@@ -1,6 +1,10 @@
namespace LibHac.FsSystem;
+///
+/// Gets Unix timestamps used to update a save data's commit time.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public interface ISaveDataCommitTimeStampGetter
{
Result Get(out long timeStamp);
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSystem/ISaveDataExtraDataAccessor.cs b/src/LibHac/FsSystem/ISaveDataExtraDataAccessor.cs
index 801404dd..3fdc1341 100644
--- a/src/LibHac/FsSystem/ISaveDataExtraDataAccessor.cs
+++ b/src/LibHac/FsSystem/ISaveDataExtraDataAccessor.cs
@@ -3,10 +3,14 @@ using LibHac.Fs;
namespace LibHac.FsSystem;
+///
+/// Provides read/write access to a save data file system's extra data.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public interface ISaveDataExtraDataAccessor : IDisposable
{
Result WriteExtraData(in SaveDataExtraData extraData);
Result CommitExtraData(bool updateTimeStamp);
Result ReadExtraData(out SaveDataExtraData extraData);
void RegisterCacheObserver(ISaveDataExtraDataAccessorCacheObserver observer, SaveDataSpaceId spaceId, ulong saveDataId);
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSystem/ISaveDataExtraDataAccessorCacheObserver.cs b/src/LibHac/FsSystem/ISaveDataExtraDataAccessorCacheObserver.cs
index 23d0f073..cb3c74d7 100644
--- a/src/LibHac/FsSystem/ISaveDataExtraDataAccessorCacheObserver.cs
+++ b/src/LibHac/FsSystem/ISaveDataExtraDataAccessorCacheObserver.cs
@@ -1,9 +1,16 @@
using System;
using LibHac.Fs;
+using LibHac.FsSrv.Impl;
namespace LibHac.FsSystem;
+///
+/// Used when adding an to the
+/// . When an extra data accessor is disposed, the accessor will
+/// use this interface to notify the cache manager that it should be removed from the extra data cache.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public interface ISaveDataExtraDataAccessorCacheObserver : IDisposable
{
void Unregister(SaveDataSpaceId spaceId, ulong saveDataId);
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSystem/ISaveDataFileSystemCacheManager.cs b/src/LibHac/FsSystem/ISaveDataFileSystemCacheManager.cs
index 087b1f3f..5f053e83 100644
--- a/src/LibHac/FsSystem/ISaveDataFileSystemCacheManager.cs
+++ b/src/LibHac/FsSystem/ISaveDataFileSystemCacheManager.cs
@@ -4,10 +4,14 @@ using LibHac.Fs;
namespace LibHac.FsSystem;
+///
+/// Provides a mechanism for caching save data file systems.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public interface ISaveDataFileSystemCacheManager : IDisposable
{
bool GetCache(ref SharedRef outFileSystem, SaveDataSpaceId spaceId, ulong saveDataId);
void Register(ref SharedRef fileSystem);
void Register(ref SharedRef fileSystem);
void Unregister(SaveDataSpaceId spaceId, ulong saveDataId);
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSystem/SaveDataFileSystemCacheManager.cs b/src/LibHac/FsSystem/SaveDataFileSystemCacheManager.cs
index 81f866a3..1c19a119 100644
--- a/src/LibHac/FsSystem/SaveDataFileSystemCacheManager.cs
+++ b/src/LibHac/FsSystem/SaveDataFileSystemCacheManager.cs
@@ -5,8 +5,17 @@ using LibHac.Os;
namespace LibHac.FsSystem;
+///
+/// Manages a list of cached save data file systems. Each file system is registered and retrieved
+/// based on its save data ID and save data space ID.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
{
+ ///
+ /// Holds a single cached file system identified by its save data ID and save data space ID.
+ ///
+ /// Based on FS 13.1.0 (nnSdk 13.4.0)
[NonCopyable]
private struct Cache
{
@@ -26,9 +35,9 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
return _fileSystem.HasValue && _spaceId == spaceId && _saveDataId == saveDataId;
}
- public void Move(ref SharedRef outFileSystem)
+ public SharedRef Move()
{
- outFileSystem.SetByMove(ref _fileSystem);
+ return SharedRef.CreateMove(ref _fileSystem);
}
public void Register(ref SharedRef fileSystem)
@@ -52,7 +61,7 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
public SaveDataFileSystemCacheManager()
{
- _mutex.Initialize();
+ _mutex = new SdkRecursiveMutexType();
}
public void Dispose()
@@ -77,11 +86,12 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
Assert.SdkAssert(_cachedFileSystems is null);
_maxCachedFileSystemCount = maxCacheCount;
- if (maxCacheCount <= 0)
- return Result.Success;
+ if (maxCacheCount > 0)
+ {
+ // Note: The original checks for overflow here
+ _cachedFileSystems = new Cache[maxCacheCount];
+ }
- // Note: The original checks for overflow here
- _cachedFileSystems = new Cache[maxCacheCount];
return Result.Success;
}
@@ -96,7 +106,9 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
{
if (_cachedFileSystems[i].IsCached(spaceId, saveDataId))
{
- _cachedFileSystems[i].Move(ref outFileSystem);
+ using SharedRef cachedFs = _cachedFileSystems[i].Move();
+ outFileSystem.SetByMove(ref cachedFs.Ref());
+
return true;
}
}
@@ -156,4 +168,4 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
{
return new UniqueLockRef(ref _mutex);
}
-}
+}
\ No newline at end of file
diff --git a/src/LibHac/FsSystem/SaveDataFileSystemCacheRegisterBase.cs b/src/LibHac/FsSystem/SaveDataFileSystemCacheRegisterBase.cs
index f8d6254b..459ada71 100644
--- a/src/LibHac/FsSystem/SaveDataFileSystemCacheRegisterBase.cs
+++ b/src/LibHac/FsSystem/SaveDataFileSystemCacheRegisterBase.cs
@@ -1,5 +1,5 @@
using System;
-using InlineIL;
+using System.Runtime.CompilerServices;
using LibHac.Common;
using LibHac.Diag;
using LibHac.Fs;
@@ -14,6 +14,7 @@ namespace LibHac.FsSystem;
///
/// The type of the base file system. Must be one of ,
/// or .
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
public class SaveDataFileSystemCacheRegisterBase : IFileSystem where T : IFileSystem
{
private SharedRef _baseFileSystem;
@@ -36,11 +37,11 @@ public class SaveDataFileSystemCacheRegisterBase : IFileSystem where T : IFil
{
if (typeof(T) == typeof(SaveDataFileSystemHolder))
{
- _cacheManager.Register(ref GetBaseFileSystemNormal());
+ _cacheManager.Register(ref Unsafe.As, SharedRef>(ref _baseFileSystem));
}
else if (typeof(T) == typeof(ApplicationTemporaryFileSystem))
{
- _cacheManager.Register(ref GetBaseFileSystemTemp());
+ _cacheManager.Register(ref Unsafe.As, SharedRef>(ref _baseFileSystem));
}
else
{
@@ -48,23 +49,6 @@ public class SaveDataFileSystemCacheRegisterBase : IFileSystem where T : IFil
}
}
- // Hack around not being able to use Unsafe.As on ref structs
- private ref SharedRef GetBaseFileSystemNormal()
- {
- IL.Emit.Ldarg_0();
- IL.Emit.Ldflda(new FieldRef(typeof(SaveDataFileSystemCacheRegisterBase), nameof(_baseFileSystem)));
- IL.Emit.Ret();
- throw IL.Unreachable();
- }
-
- private ref SharedRef GetBaseFileSystemTemp()
- {
- IL.Emit.Ldarg_0();
- IL.Emit.Ldflda(new FieldRef(typeof(SaveDataFileSystemCacheRegisterBase), nameof(_baseFileSystem)));
- IL.Emit.Ret();
- throw IL.Unreachable();
- }
-
protected override Result DoOpenFile(ref UniqueRef outFile, in Path path, OpenMode mode)
{
return _baseFileSystem.Get.OpenFile(ref outFile, path, mode);
diff --git a/src/LibHac/FsSystem/SaveDataFileSystemHolder.cs b/src/LibHac/FsSystem/SaveDataFileSystemHolder.cs
index 3080f154..5b5d35ff 100644
--- a/src/LibHac/FsSystem/SaveDataFileSystemHolder.cs
+++ b/src/LibHac/FsSystem/SaveDataFileSystemHolder.cs
@@ -6,6 +6,13 @@ using LibHac.Fs.Fsa;
namespace LibHac.FsSystem;
+///
+/// Holds a file system for adding to the save data file system cache.
+///
+/// Nintendo uses concrete types in instead of an interface.
+/// This class allows to be cached in a way that changes the original
+/// design as little as possible.
+///
public class SaveDataFileSystemHolder : ForwardingFileSystem
{
public SaveDataFileSystemHolder(ref SharedRef baseFileSystem) : base(ref baseFileSystem)
@@ -49,4 +56,4 @@ public class SaveDataFileSystemHolder : ForwardingFileSystem
throw new NotImplementedException();
}
-}
+}
\ No newline at end of file