mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Update SaveDataFileSystemService for 14.0.0
- Creating save data file systems now uses a new SaveDataCreationInfo2 struct. - Ensure all implemented functions in the class are accurate to 14.0.0
This commit is contained in:
parent
3725c21928
commit
7b44441ff2
14 changed files with 1256 additions and 589 deletions
|
@ -43,4 +43,7 @@ public static class Log
|
||||||
|
|
||||||
diag.LogImpl(in metaData, message);
|
diag.LogImpl(in metaData, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>"<c>$</c>"</summary>
|
||||||
|
public static ReadOnlySpan<byte> EmptyModuleName => new[] { (byte)'$' }; // "$"
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,9 +94,17 @@ public ref struct Path
|
||||||
[DebuggerDisplay("{" + nameof(ToString) + "(),nq}")]
|
[DebuggerDisplay("{" + nameof(ToString) + "(),nq}")]
|
||||||
public struct Stored : IDisposable
|
public struct Stored : IDisposable
|
||||||
{
|
{
|
||||||
|
private static readonly byte[] EmptyBuffer = { 0 };
|
||||||
|
|
||||||
private byte[] _buffer;
|
private byte[] _buffer;
|
||||||
private int _length;
|
private int _length;
|
||||||
|
|
||||||
|
public Stored()
|
||||||
|
{
|
||||||
|
_buffer = EmptyBuffer;
|
||||||
|
_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
byte[] buffer = Shared.Move(ref _buffer);
|
byte[] buffer = Shared.Move(ref _buffer);
|
||||||
|
@ -160,7 +168,8 @@ public ref struct Path
|
||||||
byte[] oldBuffer = _buffer;
|
byte[] oldBuffer = _buffer;
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
|
|
||||||
if (oldBuffer is not null)
|
// Check if the buffer is longer than 1 so we don't try to return EmptyBuffer to the pool.
|
||||||
|
if (oldBuffer?.Length > 1)
|
||||||
ArrayPool<byte>.Shared.Return(oldBuffer);
|
ArrayPool<byte>.Shared.Return(oldBuffer);
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
|
@ -16,8 +16,7 @@ public enum SaveDataSpaceId : byte
|
||||||
Temporary = 3,
|
Temporary = 3,
|
||||||
SdUser = 4,
|
SdUser = 4,
|
||||||
ProperSystem = 100,
|
ProperSystem = 100,
|
||||||
SafeMode = 101,
|
SafeMode = 101
|
||||||
BisAuto = 127
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SaveDataType : byte
|
public enum SaveDataType : byte
|
||||||
|
@ -99,6 +98,7 @@ public struct SaveDataExtraData
|
||||||
public ulong OwnerId;
|
public ulong OwnerId;
|
||||||
public long TimeStamp;
|
public long TimeStamp;
|
||||||
public SaveDataFlags Flags;
|
public SaveDataFlags Flags;
|
||||||
|
public SaveDataFormatType FormatType;
|
||||||
public long DataSize;
|
public long DataSize;
|
||||||
public long JournalSize;
|
public long JournalSize;
|
||||||
public long CommitId;
|
public long CommitId;
|
||||||
|
@ -371,7 +371,7 @@ internal static class SaveDataTypesValidity
|
||||||
{
|
{
|
||||||
public static bool IsValid(in SaveDataAttribute attribute)
|
public static bool IsValid(in SaveDataAttribute attribute)
|
||||||
{
|
{
|
||||||
return IsValid(in attribute.Type)&& IsValid(in attribute.Rank);
|
return IsValid(in attribute.Type) && IsValid(in attribute.Rank);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValid(in SaveDataCreationInfo creationInfo)
|
public static bool IsValid(in SaveDataCreationInfo creationInfo)
|
||||||
|
|
|
@ -4,8 +4,9 @@ namespace LibHac.Fs.Impl;
|
||||||
|
|
||||||
internal readonly struct SaveDataMetaPolicy
|
internal readonly struct SaveDataMetaPolicy
|
||||||
{
|
{
|
||||||
|
internal const int ThumbnailFileSize = 0x40060;
|
||||||
|
|
||||||
private readonly SaveDataType _type;
|
private readonly SaveDataType _type;
|
||||||
private const int ThumbnailFileSize = 0x40060;
|
|
||||||
|
|
||||||
public SaveDataMetaPolicy(SaveDataType saveType)
|
public SaveDataMetaPolicy(SaveDataType saveType)
|
||||||
{
|
{
|
||||||
|
@ -39,4 +40,4 @@ internal readonly struct SaveDataMetaPolicy
|
||||||
GenerateMetaInfo(out SaveDataMetaInfo metaInfo);
|
GenerateMetaInfo(out SaveDataMetaInfo metaInfo);
|
||||||
return metaInfo.Type;
|
return metaInfo.Type;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -352,6 +352,14 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader
|
||||||
return saveFsService.CreateSaveDataFileSystemBySystemSaveDataId(in attribute, in creationInfo);
|
return saveFsService.CreateSaveDataFileSystemBySystemSaveDataId(in attribute, in creationInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result CreateSaveDataFileSystemWithCreationInfo2(in SaveDataCreationInfo2 creationInfo)
|
||||||
|
{
|
||||||
|
Result rc = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
return saveFsService.CreateSaveDataFileSystemWithCreationInfo2(in creationInfo);
|
||||||
|
}
|
||||||
|
|
||||||
public Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize,
|
public Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize,
|
||||||
long journalSize)
|
long journalSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -136,7 +136,7 @@ public static class FileSystemServerInitializer
|
||||||
saveFsServiceConfig.BufferManager = bufferManager;
|
saveFsServiceConfig.BufferManager = bufferManager;
|
||||||
saveFsServiceConfig.GenerateRandomData = config.RandomGenerator;
|
saveFsServiceConfig.GenerateRandomData = config.RandomGenerator;
|
||||||
saveFsServiceConfig.IsPseudoSaveData = () => true;
|
saveFsServiceConfig.IsPseudoSaveData = () => true;
|
||||||
saveFsServiceConfig.MaxSaveFsCacheCount = 1;
|
saveFsServiceConfig.SaveDataFileSystemCacheCount = 1;
|
||||||
saveFsServiceConfig.SaveIndexerManager = saveDataIndexerManager;
|
saveFsServiceConfig.SaveIndexerManager = saveDataIndexerManager;
|
||||||
saveFsServiceConfig.FsServer = server;
|
saveFsServiceConfig.FsServer = server;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace LibHac.FsSrv;
|
||||||
|
|
||||||
public interface ISaveDataIndexerManager
|
public interface ISaveDataIndexerManager
|
||||||
{
|
{
|
||||||
Result OpenSaveDataIndexerAccessor(ref UniqueRef<SaveDataIndexerAccessor> outAccessor, out bool neededInit, SaveDataSpaceId spaceId);
|
Result OpenSaveDataIndexerAccessor(ref UniqueRef<SaveDataIndexerAccessor> outAccessor, out bool isInitialOpen, SaveDataSpaceId spaceId);
|
||||||
void ResetIndexer(SaveDataSpaceId spaceId);
|
void ResetIndexer(SaveDataSpaceId spaceId);
|
||||||
void InvalidateIndexer(SaveDataSpaceId spaceId);
|
void InvalidateIndexer(SaveDataSpaceId spaceId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
|
using LibHac.Os;
|
||||||
using LibHac.Util;
|
using LibHac.Util;
|
||||||
using IFileSf = LibHac.FsSrv.Sf.IFile;
|
|
||||||
|
|
||||||
namespace LibHac.FsSrv.Impl;
|
namespace LibHac.FsSrv.Impl;
|
||||||
|
|
||||||
public interface ISaveDataTransferCoreInterface : IDisposable
|
public interface ISaveDataTransferCoreInterface : IDisposable
|
||||||
{
|
{
|
||||||
Result GetFreeSpaceSizeForSaveData(out long freeSpaceSize, SaveDataSpaceId spaceId);
|
Result GetFreeSpaceSizeForSaveData(out long outFreeSpaceSize, SaveDataSpaceId spaceId);
|
||||||
Result QuerySaveDataTotalSize(out long totalSize, long dataSize, long journalSize);
|
Result QuerySaveDataTotalSize(out long outTotalSize, long dataSize, long journalSize);
|
||||||
Result CheckSaveDataFile(long saveDataId, SaveDataSpaceId spaceId);
|
Result CheckSaveDataFile(long saveDataId, SaveDataSpaceId spaceId);
|
||||||
Result CreateSaveDataFileSystemCore(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo, in Optional<HashSalt> hashSalt, bool leaveUnfinalized);
|
Result CreateSaveDataFileSystemCore(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo, in Optional<HashSalt> hashSalt, bool leaveUnfinalized);
|
||||||
Result GetSaveDataInfo(out SaveDataInfo saveInfo, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
Result GetSaveDataInfo(out SaveDataInfo saveInfo, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||||
|
@ -18,13 +18,15 @@ public interface ISaveDataTransferCoreInterface : IDisposable
|
||||||
Result WriteSaveDataFileSystemExtraDataCore(SaveDataSpaceId spaceId, ulong saveDataId, in SaveDataExtraData extraData, SaveDataType type, bool updateTimeStamp);
|
Result WriteSaveDataFileSystemExtraDataCore(SaveDataSpaceId spaceId, ulong saveDataId, in SaveDataExtraData extraData, SaveDataType type, bool updateTimeStamp);
|
||||||
Result FinalizeSaveDataCreation(ulong saveDataId, SaveDataSpaceId spaceId);
|
Result FinalizeSaveDataCreation(ulong saveDataId, SaveDataSpaceId spaceId);
|
||||||
Result CancelSaveDataCreation(ulong saveDataId, SaveDataSpaceId spaceId);
|
Result CancelSaveDataCreation(ulong saveDataId, SaveDataSpaceId spaceId);
|
||||||
Result OpenSaveDataFile(ref SharedRef<IFileSf> file, SaveDataSpaceId spaceId, in SaveDataAttribute attribute, SaveDataMetaType metaType);
|
Result OpenSaveDataFile(ref SharedRef<IFile> oufFile, SaveDataSpaceId spaceId, ulong saveDataId, OpenMode mode);
|
||||||
Result OpenSaveDataMetaFileRaw(ref SharedRef<IFile> file, SaveDataSpaceId spaceId, ulong saveDataId, SaveDataMetaType metaType, OpenMode mode);
|
Result OpenSaveDataMetaFileRaw(ref SharedRef<IFile> outFile, SaveDataSpaceId spaceId, ulong saveDataId, SaveDataMetaType metaType, OpenMode mode);
|
||||||
Result OpenSaveDataInternalStorageFileSystemCore(ref SharedRef<IFileSystem> fileSystem, SaveDataSpaceId spaceId, ulong saveDataId, bool useSecondMacKey);
|
Result OpenSaveDataInternalStorageFileSystemCore(ref SharedRef<IFileSystem> fileSystem, SaveDataSpaceId spaceId, ulong saveDataId, bool useSecondMacKey);
|
||||||
|
Result OpenSaveDataFileSystemCore(ref SharedRef<IFileSystem> outFileSystem, out ulong outSaveDataId, SaveDataSpaceId spaceId, in SaveDataAttribute attribute, bool openReadOnly, bool cacheExtraData);
|
||||||
Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize, long journalSize);
|
Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize, long journalSize);
|
||||||
Result DeleteSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId);
|
Result DeleteSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId);
|
||||||
Result SwapSaveDataKeyAndState(SaveDataSpaceId spaceId, ulong saveDataId1, ulong saveDataId2);
|
Result SwapSaveDataKeyAndState(SaveDataSpaceId spaceId, ulong saveDataId1, ulong saveDataId2);
|
||||||
Result SetSaveDataState(SaveDataSpaceId spaceId, ulong saveDataId, SaveDataState state);
|
Result SetSaveDataState(SaveDataSpaceId spaceId, ulong saveDataId, SaveDataState state);
|
||||||
Result SetSaveDataRank(SaveDataSpaceId spaceId, ulong saveDataId, SaveDataRank rank);
|
Result SetSaveDataRank(SaveDataSpaceId spaceId, ulong saveDataId, SaveDataRank rank);
|
||||||
Result OpenSaveDataIndexerAccessor(ref UniqueRef<SaveDataIndexerAccessor> outAccessor, SaveDataSpaceId spaceId);
|
Result OpenSaveDataIndexerAccessor(ref UniqueRef<SaveDataIndexerAccessor> outAccessor, SaveDataSpaceId spaceId);
|
||||||
}
|
bool IsProhibited(ref UniqueLock<SdkMutex> outLock, ApplicationId applicationId);
|
||||||
|
}
|
|
@ -46,7 +46,7 @@ internal class MultiCommitManager : IMultiCommitManager
|
||||||
{
|
{
|
||||||
private const int MaxFileSystemCount = 10;
|
private const int MaxFileSystemCount = 10;
|
||||||
|
|
||||||
public const ulong ProgramId = 0x0100000000000000;
|
public const ulong ProgramId = 0;
|
||||||
public const ulong SaveDataId = 0x8000000000000001;
|
public const ulong SaveDataId = 0x8000000000000001;
|
||||||
private const long SaveDataSize = 0xC000;
|
private const long SaveDataSize = 0xC000;
|
||||||
private const long SaveJournalSize = 0xC000;
|
private const long SaveJournalSize = 0xC000;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,13 +15,13 @@ using Utility = LibHac.FsSrv.Impl.Utility;
|
||||||
|
|
||||||
namespace LibHac.FsSrv;
|
namespace LibHac.FsSrv;
|
||||||
|
|
||||||
public class SaveDataFileSystemServiceImpl
|
public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
{
|
{
|
||||||
private Configuration _config;
|
private Configuration _config;
|
||||||
private EncryptionSeed _encryptionSeed;
|
private EncryptionSeed _encryptionSeed;
|
||||||
|
|
||||||
private SaveDataFileSystemCacheManager _saveDataFsCacheManager;
|
private SaveDataFileSystemCacheManager _saveFileSystemCacheManager;
|
||||||
private SaveDataExtraDataAccessorCacheManager _extraDataCacheManager;
|
private SaveDataExtraDataAccessorCacheManager _saveExtraDataCacheManager;
|
||||||
// Save data porter manager
|
// Save data porter manager
|
||||||
private bool _isSdCardAccessible;
|
private bool _isSdCardAccessible;
|
||||||
private TimeStampGetter _timeStampGetter;
|
private TimeStampGetter _timeStampGetter;
|
||||||
|
@ -40,22 +40,10 @@ public class SaveDataFileSystemServiceImpl
|
||||||
|
|
||||||
public Result Get(out long timeStamp)
|
public Result Get(out long timeStamp)
|
||||||
{
|
{
|
||||||
return _saveService.GetSaveDataCommitTimeStamp(out timeStamp);
|
return _saveService.GetSaveDataCommitTimeStamp(out timeStamp).Ret();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SaveDataFileSystemServiceImpl(in Configuration configuration)
|
|
||||||
{
|
|
||||||
_config = configuration;
|
|
||||||
_saveDataFsCacheManager = new SaveDataFileSystemCacheManager();
|
|
||||||
_extraDataCacheManager = new SaveDataExtraDataAccessorCacheManager();
|
|
||||||
|
|
||||||
_timeStampGetter = new TimeStampGetter(this);
|
|
||||||
|
|
||||||
Result rc = _saveDataFsCacheManager.Initialize(_config.MaxSaveFsCacheCount);
|
|
||||||
Abort.DoAbortUnless(rc.IsSuccess());
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Configuration
|
public struct Configuration
|
||||||
{
|
{
|
||||||
public BaseFileSystemServiceImpl BaseFsService;
|
public BaseFileSystemServiceImpl BaseFsService;
|
||||||
|
@ -68,7 +56,7 @@ public class SaveDataFileSystemServiceImpl
|
||||||
public IBufferManager BufferManager;
|
public IBufferManager BufferManager;
|
||||||
public RandomDataGenerator GenerateRandomData;
|
public RandomDataGenerator GenerateRandomData;
|
||||||
public SaveDataTransferCryptoConfiguration SaveTransferCryptoConfig;
|
public SaveDataTransferCryptoConfiguration SaveTransferCryptoConfig;
|
||||||
public int MaxSaveFsCacheCount;
|
public int SaveDataFileSystemCacheCount;
|
||||||
public Func<bool> IsPseudoSaveData;
|
public Func<bool> IsPseudoSaveData;
|
||||||
public ISaveDataIndexerManager SaveIndexerManager;
|
public ISaveDataIndexerManager SaveIndexerManager;
|
||||||
|
|
||||||
|
@ -76,10 +64,36 @@ public class SaveDataFileSystemServiceImpl
|
||||||
public FileSystemServer FsServer;
|
public FileSystemServer FsServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
private static bool IsDeviceUniqueMac(SaveDataSpaceId spaceId)
|
||||||
{
|
{
|
||||||
var registry = new ProgramRegistryImpl(_config.FsServer);
|
return spaceId == SaveDataSpaceId.System ||
|
||||||
return registry.GetProgramInfo(out programInfo, processId);
|
spaceId == SaveDataSpaceId.User ||
|
||||||
|
spaceId == SaveDataSpaceId.Temporary ||
|
||||||
|
spaceId == SaveDataSpaceId.ProperSystem ||
|
||||||
|
spaceId == SaveDataSpaceId.SafeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Result WipeData(IFileSystem fileSystem, in Path filePath, RandomDataGenerator random)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SaveDataFileSystemServiceImpl(in Configuration configuration)
|
||||||
|
{
|
||||||
|
_config = configuration;
|
||||||
|
_saveFileSystemCacheManager = new SaveDataFileSystemCacheManager();
|
||||||
|
_saveExtraDataCacheManager = new SaveDataExtraDataAccessorCacheManager();
|
||||||
|
|
||||||
|
_timeStampGetter = new TimeStampGetter(this);
|
||||||
|
|
||||||
|
Result rc = _saveFileSystemCacheManager.Initialize(_config.SaveDataFileSystemCacheCount);
|
||||||
|
Abort.DoAbortUnless(rc.IsSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_saveFileSystemCacheManager.Dispose();
|
||||||
|
_saveExtraDataCacheManager.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result DoesSaveDataEntityExist(out bool exists, SaveDataSpaceId spaceId, ulong saveDataId)
|
public Result DoesSaveDataEntityExist(out bool exists, SaveDataSpaceId spaceId, ulong saveDataId)
|
||||||
|
@ -116,7 +130,12 @@ public class SaveDataFileSystemServiceImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.3.0
|
public Result OpenSaveDataFile(ref SharedRef<IFile> outFile, SaveDataSpaceId spaceId, ulong saveDataId,
|
||||||
|
OpenMode openMode)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public Result OpenSaveDataFileSystem(ref SharedRef<IFileSystem> outFileSystem, SaveDataSpaceId spaceId,
|
public Result OpenSaveDataFileSystem(ref SharedRef<IFileSystem> outFileSystem, SaveDataSpaceId spaceId,
|
||||||
ulong saveDataId, in Path saveDataRootPath, bool openReadOnly, SaveDataType type, bool cacheExtraData)
|
ulong saveDataId, in Path saveDataRootPath, bool openReadOnly, SaveDataType type, bool cacheExtraData)
|
||||||
{
|
{
|
||||||
|
@ -141,10 +160,10 @@ public class SaveDataFileSystemServiceImpl
|
||||||
|
|
||||||
using var saveDataFs = new SharedRef<ISaveDataFileSystem>();
|
using var saveDataFs = new SharedRef<ISaveDataFileSystem>();
|
||||||
|
|
||||||
using (_saveDataFsCacheManager.GetScopedLock())
|
using (_saveFileSystemCacheManager.GetScopedLock())
|
||||||
using (_extraDataCacheManager.GetScopedLock())
|
using (_saveExtraDataCacheManager.GetScopedLock())
|
||||||
{
|
{
|
||||||
if (isEmulatedOnHost || !_saveDataFsCacheManager.GetCache(ref saveDataFs.Ref(), spaceId, saveDataId))
|
if (isEmulatedOnHost || !_saveFileSystemCacheManager.GetCache(ref saveDataFs.Ref(), spaceId, saveDataId))
|
||||||
{
|
{
|
||||||
bool isDeviceUniqueMac = IsDeviceUniqueMac(spaceId);
|
bool isDeviceUniqueMac = IsDeviceUniqueMac(spaceId);
|
||||||
bool isJournalingSupported = SaveDataProperties.IsJournalingSupported(type);
|
bool isJournalingSupported = SaveDataProperties.IsJournalingSupported(type);
|
||||||
|
@ -163,13 +182,13 @@ public class SaveDataFileSystemServiceImpl
|
||||||
using SharedRef<ISaveDataExtraDataAccessor> extraDataAccessor =
|
using SharedRef<ISaveDataExtraDataAccessor> extraDataAccessor =
|
||||||
SharedRef<ISaveDataExtraDataAccessor>.CreateCopy(in saveDataFs);
|
SharedRef<ISaveDataExtraDataAccessor>.CreateCopy(in saveDataFs);
|
||||||
|
|
||||||
rc = _extraDataCacheManager.Register(in extraDataAccessor, spaceId, saveDataId);
|
rc = _saveExtraDataCacheManager.Register(in extraDataAccessor, spaceId, saveDataId);
|
||||||
if (rc.IsFailure()) return rc.Miss();
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using var registerFs = new SharedRef<SaveDataFileSystemCacheRegister>(
|
using var registerFs = new SharedRef<SaveDataFileSystemCacheRegister>(
|
||||||
new SaveDataFileSystemCacheRegister(ref saveDataFs.Ref(), _saveDataFsCacheManager, spaceId, saveDataId));
|
new SaveDataFileSystemCacheRegister(ref saveDataFs.Ref(), _saveFileSystemCacheManager, spaceId, saveDataId));
|
||||||
|
|
||||||
if (openReadOnly)
|
if (openReadOnly)
|
||||||
{
|
{
|
||||||
|
@ -203,11 +222,61 @@ public class SaveDataFileSystemServiceImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSaveDataInternalStorageFileSystem(ref SharedRef<IFileSystem> outFileSystem,
|
public Result OpenSaveDataInternalStorageFileSystem(ref SharedRef<IFileSystem> outFileSystem,
|
||||||
SaveDataSpaceId spaceId, ulong saveDataId, in Path saveDataRootPath, bool useSecondMacKey)
|
SaveDataSpaceId spaceId, ulong saveDataId, in Path saveDataRootPath, bool useSecondMacKey,
|
||||||
|
bool isReconstructible)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result ExtendSaveDataFileSystemCore(out long extendedTotalSize, ulong saveDataId, SaveDataSpaceId spaceId,
|
||||||
|
SaveDataType type, long dataSize, long journalSize, in Path saveDataRootPath, bool isExtensionStart)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result OpenSaveDataImageFile(ref UniqueRef<IFile> outFile, SaveDataSpaceId spaceId, ulong saveDataId,
|
||||||
|
in Path saveDataRootPath)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result StartExtendSaveDataFileSystem(out long extendedTotalSize, ulong saveDataId, SaveDataSpaceId spaceId,
|
||||||
|
SaveDataType type, long dataSize, long journalSize, in Path saveDataRootPath)
|
||||||
|
{
|
||||||
|
return ExtendSaveDataFileSystemCore(out extendedTotalSize, saveDataId, spaceId, type, dataSize, journalSize,
|
||||||
|
in saveDataRootPath, isExtensionStart: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result ResumeExtendSaveDataFileSystem(out long extendedTotalSize, ulong saveDataId, SaveDataSpaceId spaceId,
|
||||||
|
SaveDataType type, in Path saveDataRootPath)
|
||||||
|
{
|
||||||
|
return ExtendSaveDataFileSystemCore(out extendedTotalSize, saveDataId, spaceId, type, dataSize: 0,
|
||||||
|
journalSize: 0, in saveDataRootPath, isExtensionStart: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result FinishExtendSaveDataFileSystem(ulong saveDataId, SaveDataSpaceId spaceId)
|
||||||
|
{
|
||||||
|
Result rc = DeleteSaveDataMeta(saveDataId, spaceId, SaveDataMetaType.ExtensionContext);
|
||||||
|
if (rc.IsFailure() && !ResultFs.PathNotFound.Includes(rc))
|
||||||
|
return rc.Miss();
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RevertExtendSaveDataFileSystem(ulong saveDataId, SaveDataSpaceId spaceId, long originalSize,
|
||||||
|
in Path saveDataRootPath)
|
||||||
|
{
|
||||||
|
using var saveDataFile = new UniqueRef<IFile>();
|
||||||
|
Result rc = OpenSaveDataImageFile(ref saveDataFile.Ref(), spaceId, saveDataId, in saveDataRootPath);
|
||||||
|
|
||||||
|
if (rc.IsSuccess())
|
||||||
|
{
|
||||||
|
saveDataFile.Get.SetSize(originalSize).IgnoreResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
FinishExtendSaveDataFileSystem(saveDataId, spaceId).IgnoreResult();
|
||||||
|
}
|
||||||
|
|
||||||
public Result QuerySaveDataTotalSize(out long totalSize, int blockSize, long dataSize, long journalSize)
|
public Result QuerySaveDataTotalSize(out long totalSize, int blockSize, long dataSize, long journalSize)
|
||||||
{
|
{
|
||||||
// Todo: Implement
|
// Todo: Implement
|
||||||
|
@ -316,6 +385,82 @@ public class SaveDataFileSystemServiceImpl
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result CreateSaveDataFileSystem(ulong saveDataId, in SaveDataCreationInfo2 creationInfo,
|
||||||
|
in Path saveDataRootPath, bool skipFormat)
|
||||||
|
{
|
||||||
|
Unsafe.SkipInit(out Array18<byte> saveImageNameBuffer);
|
||||||
|
|
||||||
|
long dataSize = creationInfo.Size;
|
||||||
|
long journalSize = creationInfo.JournalSize;
|
||||||
|
ulong ownerId = creationInfo.OwnerId;
|
||||||
|
SaveDataSpaceId spaceId = creationInfo.SpaceId;
|
||||||
|
SaveDataFlags flags = creationInfo.Flags;
|
||||||
|
|
||||||
|
using var fileSystem = new SharedRef<IFileSystem>();
|
||||||
|
|
||||||
|
Result rc = OpenSaveDataDirectoryFileSystem(ref fileSystem.Ref(), creationInfo.SpaceId, in saveDataRootPath,
|
||||||
|
allowEmulatedSave: false);
|
||||||
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
|
|
||||||
|
using var saveImageName = new Path();
|
||||||
|
rc = PathFunctions.SetUpFixedPathSaveId(ref saveImageName.Ref(), saveImageNameBuffer.Items, saveDataId);
|
||||||
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
|
|
||||||
|
bool isPseudoSaveFs = _config.IsPseudoSaveData();
|
||||||
|
bool isCreationSuccessful = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (isPseudoSaveFs)
|
||||||
|
{
|
||||||
|
rc = FsSystem.Utility.EnsureDirectory(fileSystem.Get, in saveImageName);
|
||||||
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveDataExtraData extraData = default;
|
||||||
|
extraData.Attribute = creationInfo.Attribute;
|
||||||
|
extraData.OwnerId = ownerId;
|
||||||
|
|
||||||
|
rc = GetSaveDataCommitTimeStamp(out extraData.TimeStamp);
|
||||||
|
if (rc.IsFailure())
|
||||||
|
extraData.TimeStamp = 0;
|
||||||
|
|
||||||
|
extraData.CommitId = 0;
|
||||||
|
_config.GenerateRandomData(SpanHelpers.AsByteSpan(ref extraData.CommitId));
|
||||||
|
|
||||||
|
extraData.Flags = flags;
|
||||||
|
extraData.DataSize = dataSize;
|
||||||
|
extraData.JournalSize = journalSize;
|
||||||
|
extraData.FormatType = creationInfo.FormatType;
|
||||||
|
|
||||||
|
rc = WriteSaveDataFileSystemExtraData(spaceId, saveDataId, in extraData, in saveDataRootPath,
|
||||||
|
creationInfo.Attribute.Type, updateTimeStamp: true);
|
||||||
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
|
|
||||||
|
isCreationSuccessful = true;
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Delete any created save if something goes wrong.
|
||||||
|
if (!isCreationSuccessful)
|
||||||
|
{
|
||||||
|
if (isPseudoSaveFs)
|
||||||
|
{
|
||||||
|
fileSystem.Get.DeleteDirectoryRecursively(in saveImageName).IgnoreResult();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileSystem.Get.DeleteFile(in saveImageName).IgnoreResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Result CreateSaveDataFileSystem(ulong saveDataId, in SaveDataAttribute attribute,
|
public Result CreateSaveDataFileSystem(ulong saveDataId, in SaveDataAttribute attribute,
|
||||||
in SaveDataCreationInfo creationInfo, in Path saveDataRootPath, in Optional<HashSalt> hashSalt,
|
in SaveDataCreationInfo creationInfo, in Path saveDataRootPath, in Optional<HashSalt> hashSalt,
|
||||||
bool skipFormat)
|
bool skipFormat)
|
||||||
|
@ -379,11 +524,6 @@ public class SaveDataFileSystemServiceImpl
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result WipeData(IFileSystem fileSystem, in Path filePath, RandomDataGenerator random)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result DeleteSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, bool wipeSaveFile,
|
public Result DeleteSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, bool wipeSaveFile,
|
||||||
in Path saveDataRootPath)
|
in Path saveDataRootPath)
|
||||||
{
|
{
|
||||||
|
@ -391,7 +531,7 @@ public class SaveDataFileSystemServiceImpl
|
||||||
|
|
||||||
using var fileSystem = new SharedRef<IFileSystem>();
|
using var fileSystem = new SharedRef<IFileSystem>();
|
||||||
|
|
||||||
_saveDataFsCacheManager.Unregister(spaceId, saveDataId);
|
_saveFileSystemCacheManager.Unregister(spaceId, saveDataId);
|
||||||
|
|
||||||
// Open the directory containing the save data
|
// Open the directory containing the save data
|
||||||
Result rc = OpenSaveDataDirectoryFileSystem(ref fileSystem.Ref(), spaceId, in saveDataRootPath, false);
|
Result rc = OpenSaveDataDirectoryFileSystem(ref fileSystem.Ref(), spaceId, in saveDataRootPath, false);
|
||||||
|
@ -433,13 +573,13 @@ public class SaveDataFileSystemServiceImpl
|
||||||
// Nintendo returns blank extra data for directory save data.
|
// Nintendo returns blank extra data for directory save data.
|
||||||
// We've extended directory save data to store extra data so we don't need to do that.
|
// We've extended directory save data to store extra data so we don't need to do that.
|
||||||
|
|
||||||
using UniqueLockRef<SdkRecursiveMutexType> scopedLockFsCache = _saveDataFsCacheManager.GetScopedLock();
|
using UniqueLockRef<SdkRecursiveMutexType> scopedLockFsCache = _saveFileSystemCacheManager.GetScopedLock();
|
||||||
using UniqueLockRef<SdkRecursiveMutexType> scopedLockExtraDataCache = _extraDataCacheManager.GetScopedLock();
|
using UniqueLockRef<SdkRecursiveMutexType> scopedLockExtraDataCache = _saveExtraDataCacheManager.GetScopedLock();
|
||||||
|
|
||||||
using var extraDataAccessor = new SharedRef<ISaveDataExtraDataAccessor>();
|
using var extraDataAccessor = new SharedRef<ISaveDataExtraDataAccessor>();
|
||||||
|
|
||||||
// Try to grab an extra data accessor for the requested save from the cache.
|
// Try to grab an extra data accessor for the requested save from the cache.
|
||||||
Result rc = _extraDataCacheManager.GetCache(ref extraDataAccessor.Ref(), spaceId, saveDataId);
|
Result rc = _saveExtraDataCacheManager.GetCache(ref extraDataAccessor.Ref(), spaceId, saveDataId);
|
||||||
|
|
||||||
if (rc.IsSuccess())
|
if (rc.IsSuccess())
|
||||||
{
|
{
|
||||||
|
@ -456,7 +596,7 @@ public class SaveDataFileSystemServiceImpl
|
||||||
if (rc.IsFailure()) return rc.Miss();
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
|
|
||||||
// Try to grab an accessor from the cache again.
|
// Try to grab an accessor from the cache again.
|
||||||
rc = _extraDataCacheManager.GetCache(ref extraDataAccessor.Ref(), spaceId, saveDataId);
|
rc = _saveExtraDataCacheManager.GetCache(ref extraDataAccessor.Ref(), spaceId, saveDataId);
|
||||||
|
|
||||||
if (rc.IsFailure())
|
if (rc.IsFailure())
|
||||||
{
|
{
|
||||||
|
@ -478,13 +618,13 @@ public class SaveDataFileSystemServiceImpl
|
||||||
// Nintendo does nothing when writing directory save data extra data.
|
// Nintendo does nothing when writing directory save data extra data.
|
||||||
// We've extended directory save data to store extra data so we don't return early.
|
// We've extended directory save data to store extra data so we don't return early.
|
||||||
|
|
||||||
using UniqueLockRef<SdkRecursiveMutexType> scopedLockFsCache = _saveDataFsCacheManager.GetScopedLock();
|
using UniqueLockRef<SdkRecursiveMutexType> scopedLockFsCache = _saveFileSystemCacheManager.GetScopedLock();
|
||||||
using UniqueLockRef<SdkRecursiveMutexType> scopedLockExtraDataCache = _extraDataCacheManager.GetScopedLock();
|
using UniqueLockRef<SdkRecursiveMutexType> scopedLockExtraDataCache = _saveExtraDataCacheManager.GetScopedLock();
|
||||||
|
|
||||||
using var extraDataAccessor = new SharedRef<ISaveDataExtraDataAccessor>();
|
using var extraDataAccessor = new SharedRef<ISaveDataExtraDataAccessor>();
|
||||||
|
|
||||||
// Try to grab an extra data accessor for the requested save from the cache.
|
// Try to grab an extra data accessor for the requested save from the cache.
|
||||||
Result rc = _extraDataCacheManager.GetCache(ref extraDataAccessor.Ref(), spaceId, saveDataId);
|
Result rc = _saveExtraDataCacheManager.GetCache(ref extraDataAccessor.Ref(), spaceId, saveDataId);
|
||||||
|
|
||||||
if (rc.IsFailure())
|
if (rc.IsFailure())
|
||||||
{
|
{
|
||||||
|
@ -498,7 +638,7 @@ public class SaveDataFileSystemServiceImpl
|
||||||
if (rc.IsFailure()) return rc.Miss();
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
|
|
||||||
// Try to grab an accessor from the cache again.
|
// Try to grab an accessor from the cache again.
|
||||||
rc = _extraDataCacheManager.GetCache(ref extraDataAccessor.Ref(), spaceId, saveDataId);
|
rc = _saveExtraDataCacheManager.GetCache(ref extraDataAccessor.Ref(), spaceId, saveDataId);
|
||||||
|
|
||||||
if (rc.IsFailure())
|
if (rc.IsFailure())
|
||||||
{
|
{
|
||||||
|
@ -592,12 +732,6 @@ public class SaveDataFileSystemServiceImpl
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSaveDataDirectoryFileSystemImpl(ref SharedRef<IFileSystem> outFileSystem,
|
|
||||||
SaveDataSpaceId spaceId, in Path basePath)
|
|
||||||
{
|
|
||||||
return OpenSaveDataDirectoryFileSystemImpl(ref outFileSystem, spaceId, in basePath, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result OpenSaveDataDirectoryFileSystemImpl(ref SharedRef<IFileSystem> outFileSystem,
|
public Result OpenSaveDataDirectoryFileSystemImpl(ref SharedRef<IFileSystem> outFileSystem,
|
||||||
SaveDataSpaceId spaceId, in Path basePath, bool createIfMissing)
|
SaveDataSpaceId spaceId, in Path basePath, bool createIfMissing)
|
||||||
{
|
{
|
||||||
|
@ -680,15 +814,10 @@ public class SaveDataFileSystemServiceImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
public Result OpenSaveDataDirectoryFileSystemImpl(ref SharedRef<IFileSystem> outFileSystem,
|
||||||
|
SaveDataSpaceId spaceId, in Path basePath)
|
||||||
{
|
{
|
||||||
_encryptionSeed = seed;
|
return OpenSaveDataDirectoryFileSystemImpl(ref outFileSystem, spaceId, in basePath, true);
|
||||||
|
|
||||||
_config.SaveFsCreator.SetSdCardEncryptionSeed(seed.Value);
|
|
||||||
_config.SaveIndexerManager.InvalidateIndexer(SaveDataSpaceId.SdSystem);
|
|
||||||
_config.SaveIndexerManager.InvalidateIndexer(SaveDataSpaceId.SdUser);
|
|
||||||
|
|
||||||
return Result.Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result IsProvisionallyCommittedSaveData(out bool isProvisionallyCommitted, in SaveDataInfo saveInfo)
|
public Result IsProvisionallyCommittedSaveData(out bool isProvisionallyCommitted, in SaveDataInfo saveInfo)
|
||||||
|
@ -704,13 +833,15 @@ public class SaveDataFileSystemServiceImpl
|
||||||
return spaceId == SaveDataSpaceId.User && IsSaveEmulated(in saveDataRootPath);
|
return spaceId == SaveDataSpaceId.User && IsSaveEmulated(in saveDataRootPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDeviceUniqueMac(SaveDataSpaceId spaceId)
|
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
||||||
{
|
{
|
||||||
return spaceId == SaveDataSpaceId.System ||
|
_encryptionSeed = seed;
|
||||||
spaceId == SaveDataSpaceId.User ||
|
|
||||||
spaceId == SaveDataSpaceId.Temporary ||
|
_config.SaveFsCreator.SetSdCardEncryptionSeed(seed.Value);
|
||||||
spaceId == SaveDataSpaceId.ProperSystem ||
|
_config.SaveIndexerManager.InvalidateIndexer(SaveDataSpaceId.SdSystem);
|
||||||
spaceId == SaveDataSpaceId.SafeMode;
|
_config.SaveIndexerManager.InvalidateIndexer(SaveDataSpaceId.SdUser);
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSdCardAccessibility(bool isAccessible)
|
public void SetSdCardAccessibility(bool isAccessible)
|
||||||
|
@ -753,6 +884,11 @@ public class SaveDataFileSystemServiceImpl
|
||||||
return programId;
|
return programId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SaveDataTransferCryptoConfiguration GetSaveDataTransferCryptoConfiguration()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public Result GetSaveDataIndexCount(out int count)
|
public Result GetSaveDataIndexCount(out int count)
|
||||||
{
|
{
|
||||||
UnsafeHelpers.SkipParamInit(out count);
|
UnsafeHelpers.SkipParamInit(out count);
|
||||||
|
@ -766,10 +902,10 @@ public class SaveDataFileSystemServiceImpl
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSaveDataIndexerAccessor(ref UniqueRef<SaveDataIndexerAccessor> outAccessor, out bool neededInit,
|
public Result OpenSaveDataIndexerAccessor(ref UniqueRef<SaveDataIndexerAccessor> outAccessor,
|
||||||
SaveDataSpaceId spaceId)
|
out bool isInitialOpen, SaveDataSpaceId spaceId)
|
||||||
{
|
{
|
||||||
return _config.SaveIndexerManager.OpenSaveDataIndexerAccessor(ref outAccessor, out neededInit, spaceId);
|
return _config.SaveIndexerManager.OpenSaveDataIndexerAccessor(ref outAccessor, out isInitialOpen, spaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetTemporaryStorageIndexer()
|
public void ResetTemporaryStorageIndexer()
|
||||||
|
|
|
@ -122,14 +122,14 @@ internal class SaveDataIndexerManager : ISaveDataIndexerManager, IDisposable
|
||||||
/// The accessor must be disposed after use.
|
/// The accessor must be disposed after use.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="outAccessor">If the method returns successfully, contains the created accessor.</param>
|
/// <param name="outAccessor">If the method returns successfully, contains the created accessor.</param>
|
||||||
/// <param name="neededInit">If the method returns successfully, contains <see langword="true"/>
|
/// <param name="isInitialOpen">If the method returns successfully, contains <see langword="true"/>
|
||||||
/// if the indexer needed to be initialized.</param>
|
/// if the indexer needed to be initialized because this was the first time it was opened.</param>
|
||||||
/// <param name="spaceId">The <see cref="SaveDataSpaceId"/> of the indexer to open.</param>
|
/// <param name="spaceId">The <see cref="SaveDataSpaceId"/> of the indexer to open.</param>
|
||||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||||
public Result OpenSaveDataIndexerAccessor(ref UniqueRef<SaveDataIndexerAccessor> outAccessor,
|
public Result OpenSaveDataIndexerAccessor(ref UniqueRef<SaveDataIndexerAccessor> outAccessor,
|
||||||
out bool neededInit, SaveDataSpaceId spaceId)
|
out bool isInitialOpen, SaveDataSpaceId spaceId)
|
||||||
{
|
{
|
||||||
UnsafeHelpers.SkipParamInit(out neededInit);
|
UnsafeHelpers.SkipParamInit(out isInitialOpen);
|
||||||
|
|
||||||
if (_isBisUserRedirectionEnabled && spaceId == SaveDataSpaceId.User)
|
if (_isBisUserRedirectionEnabled && spaceId == SaveDataSpaceId.User)
|
||||||
{
|
{
|
||||||
|
@ -226,7 +226,7 @@ internal class SaveDataIndexerManager : ISaveDataIndexerManager, IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
outAccessor.Reset(new SaveDataIndexerAccessor(indexer, ref indexerLock.Ref()));
|
outAccessor.Reset(new SaveDataIndexerAccessor(indexer, ref indexerLock.Ref()));
|
||||||
neededInit = wasIndexerInitialized;
|
isInitialOpen = wasIndexerInitialized;
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace LibHac.FsSrv.Sf;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The interface most programs use to interact with the FS service.
|
/// The interface most programs use to interact with the FS service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
/// <remarks>Based on FS 14.1.0 (nnSdk 14.3.0)</remarks>
|
||||||
public interface IFileSystemProxy : IDisposable
|
public interface IFileSystemProxy : IDisposable
|
||||||
{
|
{
|
||||||
Result SetCurrentProcess(ulong processId);
|
Result SetCurrentProcess(ulong processId);
|
||||||
|
@ -42,6 +42,7 @@ public interface IFileSystemProxy : IDisposable
|
||||||
Result GetCacheStorageSize(out long dataSize, out long journalSize, ushort index);
|
Result GetCacheStorageSize(out long dataSize, out long journalSize, ushort index);
|
||||||
Result CreateSaveDataFileSystemWithHashSalt(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo, in HashSalt hashSalt);
|
Result CreateSaveDataFileSystemWithHashSalt(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo, in HashSalt hashSalt);
|
||||||
Result OpenHostFileSystemWithOption(ref SharedRef<IFileSystemSf> outFileSystem, in FspPath path, MountHostOption option);
|
Result OpenHostFileSystemWithOption(ref SharedRef<IFileSystemSf> outFileSystem, in FspPath path, MountHostOption option);
|
||||||
|
Result CreateSaveDataFileSystemWithCreationInfo2(in SaveDataCreationInfo2 creationInfo);
|
||||||
Result OpenSaveDataFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
Result OpenSaveDataFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||||
Result OpenSaveDataFileSystemBySystemSaveDataId(ref SharedRef<IFileSystemSf> outFileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
Result OpenSaveDataFileSystemBySystemSaveDataId(ref SharedRef<IFileSystemSf> outFileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||||
Result OpenReadOnlySaveDataFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
Result OpenReadOnlySaveDataFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||||
|
|
|
@ -136,6 +136,7 @@ public class TypeLayoutTests
|
||||||
Assert.Equal(0x40, GetOffset(in s, in s.OwnerId));
|
Assert.Equal(0x40, GetOffset(in s, in s.OwnerId));
|
||||||
Assert.Equal(0x48, GetOffset(in s, in s.TimeStamp));
|
Assert.Equal(0x48, GetOffset(in s, in s.TimeStamp));
|
||||||
Assert.Equal(0x50, GetOffset(in s, in s.Flags));
|
Assert.Equal(0x50, GetOffset(in s, in s.Flags));
|
||||||
|
Assert.Equal(0x54, GetOffset(in s, in s.FormatType));
|
||||||
Assert.Equal(0x58, GetOffset(in s, in s.DataSize));
|
Assert.Equal(0x58, GetOffset(in s, in s.DataSize));
|
||||||
Assert.Equal(0x60, GetOffset(in s, in s.JournalSize));
|
Assert.Equal(0x60, GetOffset(in s, in s.JournalSize));
|
||||||
Assert.Equal(0x68, GetOffset(in s, in s.CommitId));
|
Assert.Equal(0x68, GetOffset(in s, in s.CommitId));
|
||||||
|
|
Loading…
Reference in a new issue